DocFxTocGenerator 1.28.0
dotnet tool install --global DocFxTocGenerator --version 1.28.0
dotnet new tool-manifest # if you are setting up this repo dotnet tool install --local DocFxTocGenerator --version 1.28.0
#tool dotnet:?package=DocFxTocGenerator&version=1.28.0
nuke :add-package DocFxTocGenerator --version 1.28.0
Table of Contents (TOC) generator for DocFX
This tool allow to generate a yaml compatible toc.yml
file for DocFX.
Usage
DocFxTocGenerator [options]
Options:
-d, --docfolder <docfolder> (REQUIRED) The root folder of the documentation.
-o, --outfolder <outfolder> The output folder for the generated table of contents
file. Default is the documentation folder.
-v, --verbose Show verbose messages of the process.
-s, --sequence Use .order files per folder to define the sequence of
files and directories. Format of the file is filename
without extension per line.
-r, --override Use .override files per folder to define title overrides
for files and folders. Format of the file is filename
without extension or directory name followed by a
semi-column followed by the custom title per line.
-g, --ignore Use .ignore files per folder to ignore directories.
Format of the file is directory name per line.
--indexing When to generated an index.md for a folder.
<EmptyFolders|Never|NoDefault|NoDefaultMulti|NotExistMulti Never - Do not genereate.
|NotExists> NoDefault - When no index.md or readme.md found.
NoDefaultMulti - When no index.md or readme.md found and
multiple files.
EmptyFolders - For empty folders.
NotExists - When no index found.
NotExistMulti - When no index and multiple files.
[default: Never]
--folderRef <First|Index|IndexReadme|None> Strategy for folder-entry references.
None - Never reference anything.
Index - Index.md only if exists.
IndexReadme - Index.md or readme.md if exists.
First - First file in folder if any exists.
[default: First]
--ordering <All|FilesFirst|FoldersFirst> How to order items in a folder.
All - Folders and files combined.
FoldersFirst - Folders first, then files.
FilesFirst - Files first, then folders. [default: All]
-m, --multitoc <multitoc> Indicates how deep in the tree toc files should be
generated for those folders. A depth of 0 is the root
only (default behavior).
--camelCase Use camel casing for titles.
--version Show version information
-?, -h, --help Show help and usage information
Return values: 0 - succesfull. 1 - some warnings, but process could be completed. 2 - a fatal error occurred.
Warnings, errors and verbose
If the tool encounters situations that might need some action, a warning is written to the output. The table of contents is still created. If the tool encounters an error, an error message is written to the output. The table of contents will not be created.
If you want to trace what the tool is doing, use the -v or --verbose
flag to output all details of processing the files and folders and creating the table of contents.
Overall process
The overall process of this tool is:
- Content inventory - retrieve all folders and files (
*.md
and*swagger.json
) in the given documentation folder. Flags-s | --sequence
,-r | --override
and-g | --ignore
are processed here to read setting files in the hierarchy. - Ensure indexing - validate structure with given settings. Depending on the
--indexing
flag automatedindex.md
files are added where necessary. - Generate the table of contents - generate the
toc.yml
file(s). For folders it can be indicated if they should have a reference into child files using the--folderRef
flag. Using the--ordering
flag the ordering of directories and files can be defined. In this step the-m | --multitoc <multitoc>
flag is evaluated and processed on generation.
Title of directories and files
For directories the name of the directory is used by default, where the first character is uppercased and special characters ([
, ]
, :
, `,\
, {
, }
, (
, )
, *
, /
) are removed and -
, _
and multiple spaces are replaced by a single space.
For markdown files the first level-1 heading is taken as title. For swagger files the title and version are taken as title. On error the file name without extension is taken and processed the same way as the name of a directory.
The .override
setting file can be used to override this behavior. See Defining title overrides with .override
.
Folder settings
Folder settings can be provided on ordering directories and files, ignore directories and override titles of files. Flags -s | --sequence
, -r | --override
and -g | --ignore
are processed here to read setting files in the hierarchy.
Defining the order with .order
If the -s | --sequence
parameter is provided, the tool will inspect folders if a .order
file exists and use that to determine the order of files and directories. The .order
file is just a list of file- and/or directory-names, case-sensitive without file extensions. Also see the Azure DevOps WIKI documentation on this file.
A sample .order
file looks like this:
getting-started
working-agreements
developer
Ordering of directories and files in a folder is influenced by the -s | --sequence
flag in combination with the .order
file in that directory, combined with the (optional) --ordering
flag. Also see Ordering.
Defining directories to ignore with .ignore
If the -g | --ignore
parameter is provided, the tool will inspect folders if a .ignore
file exists and use that to ignore directories. The .ignore
file is just a list of file- and/or directory-names, case-sensitive without file extensions.
A sample .ignore
file looks like this:
node_modules
bin
It only applies to the folder it's in, not for other subfolders under that folder.
Defining title overrides with .override
If the -r | --override
parameter is provided, the tool will inspect folders if a .override
file exists and use that for overrides of file or directory titles as they will show in the generated toc.yml
. The .override
file is a list of file- and/or directory-names, case-sensitive without file extensions, followed by a semi-column, followed by the title to use.
For example, if the folder name is introduction
, the default behavior will be to create the name Introduction
. If you want to call it To start with
, you can use overrides, like in the following example:
introduction;To start with
working-agreements;All working agreements of all teams
The title for an MD-file is taken from the H1-header in the file. The title for a directory is the directory-name, but cleanup from special characters and the first character in capitals.
Automatic generating index.md
files
If the -indexing <method>
parameter is provided the method
defines the conditions for generating an index.md
file. The options are:
Never
- never generate anindex.md
. This is the default.NoDefault
- generate anindex.md
when noindex.md
orreadme.md
is found in a folder.NoDefaultMulti
- generate anindex.md
when noindex.md
orreadme.md
is found in a folder and there are 2 or more files.NotExists
- generate anindex.md
when noindex.md
file is found in a folder.NotExistsMulti
- generate anindex.md
when noindex.md
file is found in a folder and there are 2 or more files.EmptyFolders
- generate anindex.md
when a folder doesn't contain any files.
Template for generating an index.md
When an index.md
file is generated, this is done by using a Liquid template. The tool contains a default template:
# {{ current.DisplayName }}
{% comment -%}Looping through all the files and show the display name.{%- endcomment -%}
{% for file in current.Files -%}
{%- if file.IsMarkdown -%}
* [{{ file.DisplayName }}]({{ file.Name }})
{% endif -%}
{%- endfor %}
This results in a markdown file like this:
# Brasil
* [Nova Friburgo](nova-friburgo.md)
* [Rio de Janeiro](rio-de-janeiro.md)
* [Sao Paulo](sao-paulo.md)
You can also provide a customized template to be used. The ensure indexing process will look for a file with the name .index.liquid
in the folder where an index.md
needs to be generated. If it doesn't exist in that folder it's traversing all parent folders up to the root and until a .index.liquid
file is found.
In the template access is provided to this information:
current
- this is the current folder that needs anindex.md
file of typeFolderData
.root
- this is the root folder of the complete hierarchy of the documentation of typeFolderData
.
FolderData
class
Property | Description |
---|---|
Name |
Folder name from disk |
DisplayName |
Title of the folder |
Path |
Full path of the folder |
Sequence |
Sequence number from the .order file or int.MaxValue when not defined. |
RelativePath |
Relative path of the folder from the root of the documentation. |
Parent |
Parent folder. When null it's the root folder. |
Folders |
A list of FolderData objects for the sub-folders in this folder. |
Files |
A list of FileData objects for the files in this folder. |
HasIndex |
A boolean indicating whether this folder contains an index.md |
Index |
The FileData object of the index.md in this folder if it exists. If it doesn't exists this will be null . |
HasReadme |
A boolean indicating whether this folder contains an README.md |
Readme |
The FileData object of the README.md in this folder if it exists. If it doesn't exists this will be null . |
FileData
class
Property | Description |
---|---|
Name |
Filename including the extension |
DisplayName |
Title of the file. |
Path |
Full path of the file |
Sequence |
Sequence number from the .order file or int.MaxValue when not defined. |
RelativePath |
Relative path of the file from the root of the documentation. |
Parent |
Parent folder. |
IsMarkdown |
A boolean indicating whether this file is a markdown file. |
IsSwagger |
A boolean indicating whether this file is a Swagger JSON file. |
IsIndex |
A boolean indicating whether this file is an index.md file. |
IsReadme |
A boolean indicating whether this file is a README.md file. |
For more information on how to use Liquid logic, see the article Using Liquid for text-based templates with .NET | by Martin Tirion | Medium and the Liquid reference.
Liquid, by design, is very forgiving. If you reference an object or property that doesn't exist, it will render to an empty string. But if you introduce language errors (missing {{
for instance) an error is thrown, the error is in the output of the tool but will not crash the tool, but will be resulting in error code 1 (warning). In the case of an error like this, no index.md
is generated.
Ordering
There are these options for ordering directories and folders:
All
- order all directories and files by sequence, then by title.FoldersFirst
- order all directories first, then the files. Ordering is for each of them done by sequence, then by title.FilesFirst
- order all files first, then the folders. Ordering is for each of them done by sequence, then by title.
For all of these options the .order
file can be used when it exists and the -s | --sequence
flag is used. The line in the .order
file determines the sequence of a file or directory. So, the first entry results in sequence 1. In all other cases a folder or file has an equal sequence of int.MaxValue
.
By default the ordering of files is applied where the index.md
is first and the README.md
is second, optionally followed by the settings from the .order
file. This behavior can only be overruled by adding index
and/or readme
to a .order
file and use of the -s | --sequence
flag.
[!NOTE]
README
andindex
are always validated case-sensitive to make sure they are ordered correctly. All other file names and directory names are matched case-insensitive.
Folder referencing
The table of content is constructed from the folders and files. For folders there are various strategies to determine if it will have a reference:
None
- no reference for all folders.Index
- reference theindex.md
in the folder if it exists.IndexReadme
- reference theindex.md
if it exists, otherwise reference theREADME.md
if it exists.First
- reference the first file in the folder after ordering has been applied.
When using DocFx to generate the website, folders with no reference will just be entries in the hive that can be opened and closed. The UI will determine what will be showed as content.
Multiple table of content files
The default for this tool is to generate only one toc.yml
file in the root of the output directory. But with a large hierarchy, this file can get pretty large. In that case it might be easier to have a few toc.yml
files per level to have multiple, smaller toc.yml
files.
The -m | --multitoc
option will control how far down the hierarchy toc.yml
files are generated. Let's explain this feature by an example hierarchy:
📂docs
📄README.md
📂continents
📄index.md
📂americas
📄README.md
📄extra-facts.md
📂brasil
📄README.md
📄nova-friburgo.md
📄rio-de-janeiro.md
📂united-states
📄los-angeles.md
📄new-york.md
📄washington.md
📂europe
📄README.md
📂germany
📄berlin.md
📄munich.md
📂netherlands
📄amsterdam.md
📄rotterdam.md
📂vehicles
📄index.md
📂cars
📄README.md
📄audi.md
📄bmw.md
Default behavior or depth=0
By default, when the depth
is 0
(or the option is omitted), only one toc.yml
file is generated in the root of the output folder containing the complete hierarchy of folders and files. For the example hierarchy it would look like this:
# This is an automatically generated file
- name: Multi toc example
href: README.md
- name: Continents
href: continents/index.md
items:
- name: Americas
href: continents/americas/README.md
items:
- name: Americas Extra Facts
href: continents/americas/extra-facts.md
- name: Brasil
href: continents/americas/brasil/README.md
items:
- name: Nova Friburgo
href: continents/americas/brasil/nova-friburgo.md
- name: Rio de Janeiro
href: continents/americas/brasil/rio-de-janeiro.md
- name: Los Angeles
href: continents/americas/united-states/los-angeles.md
items:
- name: New York
href: continents/americas/united-states/new-york.md
- name: Washington
href: continents/americas/united-states/washington.md
- name: Europe
href: continents/europe/README.md
items:
- name: Amsterdam
href: continents/europe/netherlands/amsterdam.md
items:
- name: Rotterdam
href: continents/europe/netherlands/rotterdam.md
- name: Berlin
href: continents/europe/germany/berlin.md
items:
- name: Munich
href: continents/europe/germany/munich.md
- name: Vehicles
href: vehicles/index.md
items:
- name: Cars
href: vehicles/cars/README.md
items:
- name: Audi
href: vehicles/cars/audi.md
- name: BMW
href: vehicles/cars/bmw.md
Behavior with depth=1 or more
When a depth
of 1
is given, a toc.yml
is generated in the root of the output folder and in each sub-folder of the documentation root. The toc.yml
in the root will only contain documents of the folder itself and references to the toc.yml
files in the sub-folders. In our example for the root it would look like this:
# This is an automatically generated file
- name: Multi toc example
href: README.md
- name: Continents
href: continents/toc.yml
- name: Vehicles
href: vehicles/toc.yml
The toc.yml
files in the sub-folders continents
and vehicles
will contain the complete hierarchy from that point on. For instance, for vehicles
it will look like this:
# This is an automatically generated file
- name: Cars
href: cars/README.md
items:
- name: Audi
href: cars/audi.md
- name: BMW
href: cars/bmw.md
Camel case titles
By default titles are changed to pascal casing, meaning that the first character is capitalized. With the option --camelCase
all titles will be changed to camel casing, meaning that the first character is lower cased. Only exception are overrides from .override
files.
[!NOTE]
As this rule is applied to everything, it is also applied to titles coming from Swagger-files. If this is an issue, this can be corrected for that file using an
.override
file in that folder.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
This package has no dependencies.
Version | Downloads | Last updated |
---|---|---|
1.28.0 | 87 | 11/26/2024 |
1.27.0 | 117 | 11/21/2024 |
1.24.0 | 149 | 11/14/2024 |
1.23.0 | 356 | 10/30/2024 |
1.22.0 | 158 | 10/29/2024 |
1.21.0 | 2,508 | 9/2/2024 |
1.20.0 | 438 | 8/21/2024 |
1.19.0 | 3,907 | 5/16/2024 |
1.18.0 | 4,764 | 1/18/2024 |
1.17.0 | 2,092 | 12/8/2023 |
1.16.0 | 1,246 | 11/15/2023 |
1.15.0 | 437 | 11/6/2023 |
1.14.0 | 207 | 11/2/2023 |
1.13.0 | 589 | 10/24/2023 |
1.12.0 | 1,585 | 10/11/2023 |
1.11.0 | 87 | 10/11/2023 |
1.10.0 | 12,450 | 4/5/2023 |
1.9.0 | 249 | 4/4/2023 |