DocFxTocGenerator 1.37.0
dotnet tool install --global DocFxTocGenerator --version 1.37.0
dotnet new tool-manifest
dotnet tool install --local DocFxTocGenerator --version 1.37.0
#tool dotnet:?package=DocFxTocGenerator&version=1.37.0
nuke :add-package DocFxTocGenerator --version 1.37.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 (
*.mdand*swagger.json) in the given documentation folder. Flags-s | --sequence,-r | --overrideand-g | --ignoreare processed here to read setting files in the hierarchy. - Ensure indexing - validate structure with given settings. Depending on the
--indexingflag automatedindex.mdfiles are added where necessary. - Generate the table of contents - generate the
toc.ymlfile(s). For folders it can be indicated if they should have a reference into child files using the--folderRefflag. Using the--orderingflag 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.mdwhen noindex.mdorreadme.mdis found in a folder.NoDefaultMulti- generate anindex.mdwhen noindex.mdorreadme.mdis found in a folder and there are 2 or more files.NotExists- generate anindex.mdwhen noindex.mdfile is found in a folder.NotExistsMulti- generate anindex.mdwhen noindex.mdfile is found in a folder and there are 2 or more files.EmptyFolders- generate anindex.mdwhen 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.mdfile 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.
README and index 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.mdin the folder if it exists.IndexReadme- reference theindex.mdif it exists, otherwise reference theREADME.mdif 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.
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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.37.0 | 439 | 10/22/2025 |
| 1.36.0 | 1,715 | 8/11/2025 |
| 1.35.0 | 494 | 7/22/2025 |
| 1.34.0 | 863 | 7/1/2025 |
| 1.33.0 | 1,162 | 6/3/2025 |
| 1.32.0 | 5,915 | 12/19/2024 |
| 1.31.0 | 112 | 12/19/2024 |
| 1.30.0 | 132 | 12/18/2024 |
| 1.29.0 | 135 | 12/16/2024 |
| 1.28.0 | 937 | 11/26/2024 |
| 1.27.0 | 285 | 11/21/2024 |
| 1.24.0 | 297 | 11/14/2024 |
| 1.23.0 | 456 | 10/30/2024 |
| 1.22.0 | 223 | 10/29/2024 |
| 1.21.0 | 17,225 | 9/2/2024 |
| 1.20.0 | 484 | 8/21/2024 |
| 1.19.0 | 4,432 | 5/16/2024 |
| 1.18.0 | 4,915 | 1/18/2024 |
| 1.17.0 | 2,141 | 12/8/2023 |
| 1.16.0 | 1,277 | 11/15/2023 |
| 1.15.0 | 484 | 11/6/2023 |
| 1.14.0 | 247 | 11/2/2023 |
| 1.13.0 | 630 | 10/24/2023 |
| 1.12.0 | 1,621 | 10/11/2023 |
| 1.11.0 | 120 | 10/11/2023 |
| 1.10.0 | 12,677 | 4/5/2023 |
| 1.9.0 | 382 | 4/4/2023 |