In this post, we’ll use DocFx to produce documentation for a Visual Studio C# solution in a Windows machine.
Table of Contents
Introduction
DocFx is a command line tool that generates documentation.
DocFx builds a documentation web site combining two sources:
- reference documentation it collects from comments found in source code files
- conceptual documentation provided to DocFx as Markdown files, by the user
According to DocFx web site:
"DocFX can produce documentation from source code (including .NET, REST, JavaScript, Java, Python and TypeScript) as well as raw Markdown files."
and also:
"DocFX can run on Linux, macOS, and Windows. The generated static website can be deployed to any host such as GitHub Pages or Azure Websites with no additional configuration."
DocFx is an open source tool developed by Microsoft and, as the company says, is a tool used in building Microsoft's documentation web site.
In this post, we'll use DocFx to produce documentation for a Visual Studio C# solution in a Windows machine.
DocFx Installation
The easiest way to download and install DocFx is to use the Chocolatey package manager for Windows. Open a terminal as administrator and execute the following:
choco install docfx -y
The above adds the DocFx to the PATH
environment variable too.
A Test Solution in Visual Studio
Open Visual Studio and create a solution with two projects: a Library project and a Windows Forms project.
Here is the folder structure:
Solution
+ App
+ Lib
Solution.sln
For each project, go to Properties | Build and check the XML documentation file check box.
Add some classes to both projects and document those classes. This is done by adding triple-slash comments to classes, methods and properties.
Build the solution.
Setting up DocFx with docfx init
The DocFx documentation provides two walkthroughs.
Those walkthroughs say that we init
the DocFx by opening a terminal, cd
to solution folder and then type docfx init -q
to initialize the project.
cd C:\Solution
docfx init -q
The -q
parameter is for quiet
. Otherwise, it goes through a series of questions the user has to answer.
The above creates a docfx_project
folder inside the root solution folder and adds a number of sub-folders and files to it. The most important file inside that docfx_project
is the docfx.json file which is the configuration file for the DocFx.
"docfx.json is the configuration file docfx uses to generate documentation"
All folder references inside that generated docfx.json are wrong. And some of the created folders are not needed at all.
Therefore, delete the docfx_project
folder. We are going to use our own way.
Setting up DocFx Manually
We need a sub-folder inside the root solution folder for the DocFx files and generated documentation. Create the new folder and name it DocFx
.
Solution
+ App
+ DocFx
+ Lib
Solution.sln
Inside DocFx
folder, create an empty docfx.json, open it with Visual Studio and add the following content:
{
"metadata": [
{
"src": [
{
"files": [ "**/**.csproj" ],
"src": ".."
}
],
"dest": "reference",
"disableGitFeatures": false,
"disableDefaultFilter": false,
"filter": "filterConfig.yml"
}
],
"build": {
"content": [
{
"files": [
"reference/**.yml",
"reference/index.md"
]
},
{
"files": [
"Concepts/toc.yml",
"Concepts/**.md",
"Concepts/**/toc.yml",
"toc.yml",
"*.md"
]
}
],
"resource": [
{
"files": [ "images/**" ]
}
],
"dest": "../docs",
"globalMetadataFiles": [],
"fileMetadataFiles": [],
"template": [ "default" ],
"postProcessors": [],
"markdownEngineName": "markdig",
"noLangKeyword": false,
"keepFileLink": false,
"cleanupCacheHistory": false,
"disableGitFeatures": false
}
}
The Anatomy of the docfx.json Configuration File
The docfx.json contains two sections: metadata
and build
. There can be a third section, pdf
, but we leave that ...adventure for a later time.
The metadata
section says to DocFx:
- where to find source code files, to gather comments from
- where to place the gathered material
- and how to filter inderited members of types found in source files
Our metadata
section says to DocFx:
- to look for source code files in all
csproj
files ("files": [ "**/**.csproj" ]
) starting from the rool solution folder ("src": ".."
) - place the gathered material to a folder named
reference
("dest": "reference",
) - and filter inherited members according to a provided
yml
file ("filter": "filterConfig.yml"
)
The reference folder will be created by DocFx if not there.
The Build Section
The build
section says to DocFx:
- where to find the content to build, for both types, the content DocFx gathered from source files (reference) and the content provided by the user as Markdown files (conceptual)
- where to find the images used in Markdown files
- where to place the "compiled" output, meaning the web site it generates
- and what template to use
Our build
section says to DocFx:
- the reference content is found in the reference folder while the conceptual is found in the Concepts folder
- the images are in the images folder
- place the generated site to the ../docs folder (
"dest": "../docs"
) - and use the
default
template
The docs Folder
We instruct DocFx to place the generated web site in a docs folder, under the root solution folder. This will result in the following folder structure:
Solution
+ App
+ DocFx
+ docs
+ Lib
Solution.sln
You can instruct DocFx to place the generated site in any folder you like.
We name that folder docs and place it under the root solution folder because GitHub Pages want it like that.
If you use github to host your open source project and you want to provide a nice documentation site for your project, you can achieve that easily by simply placing the documentation site inside the docs folder under the root and setting that docs folder as the publishing source for the GitHub Pages site.
The filterConfig.yml File
As the DocFx documentation says:
"A filter configuration file is in YAML format. You may filter out unwanted APIs or attributes by providing a filter configuration file and specifying its path."
Place a filterConfig.yml with the following content:
apiRules:
- exclude:
uidRegex: ^System\.Windows\.Forms\.Form\..*$
type: Member
- exclude:
uidRegex: ^System\.Windows\.Forms\.Control\..*$
type: Member
- exclude:
uidRegex: ^System\..*$
type: Type
- exclude:
uidRegex: ^Microsoft\..*$
type: Type
CAUTION: The lines containing the uidRegex
and type
entries should start with two spaces. YAML language uses white space indentation.
Conceptual Documentation and the TOC (Table Of Content) Files
DocFx accepts Markdown files containing conceptual documentation, written by the user. Organizes those Markdown files using TOC (Table Of Content) YAML files.
Under the DocFx folder, add an index.md file with whatever content you like.
Here is my DocFx folder:
DocFx
docfx.json
index.md
.gitignore
filterConfig.yml
toc.yml
Inside the DocFx folder, create a Concepts sub-folder and add the following folders and files:
Concepts
+ Advanced
Abstract.md
Advanced.md
toc.yml
+ Easy
Abstract.md
Easy.md
toc.yml
Abstract.md
toc.yml
You may place whatever content you like in these Markdown files. Usually, those files contain conceptual overviews regarding the use of the referenced API.
Regarding TOC
files, you may consult the relevant DocFx documentation which says that:
"DocFX supports processing Markdown files or Conceptual Files, as well as structured data model in YAML or JSON format or Metadata Files. Besides that, DocFX introduces a way to organize these files using Table-Of-Content Files or TOC Files, so that users can navigate through Metadata Files and Conceptual Files."
Listed below are the three toc.yml files used:
- Concepts/toc.yml:
- name: Easy
href: Easy/toc.yml
topicHref: Easy/Abstract.md
- name: Advanced
href: Advanced/toc.yml
topicHref: Advanced/Abstract.md
- Concepts/Advanced/toc.yml:
- name: Advanced Overview Title
href: Advanced.md
- Concepts/Easy/toc.yml:
- name: Easy Overview Title
href: Easy.md
-
The name
entry is the clickable title, i.e., link, to be displayed by the TOC of the generated site.
-
The href
entry says where to navigate when that title is clicked.
-
The optional topicHref
says what content file to display. Used when the href
links to another toc.yml, that is another Table Of Contents, but the user wants to provide some kind of abstraction to the visitor, as to what she/he is going to find in that link.
The .gitignore File
The docfx init -q
command adds a .gitignore file inside the DocFx folder. Create a .gitignore file with the following content and place it into the DocFx folder.
/**/DROP/
/**/TEMP/
/**/packages/
/**/bin/
/**/obj/
reference
Generate the Documentation Site
In order to generate the web site, open a terminal, cd
to DocFx
folder and just type:
docfx
The web site is generated.
It's time to preview the site. According to the documentation:
"If port 8080 is not in use, docfx will host _site under http://localhost:8080. If 8080 is in use, you can use docfx serve _site -p <port> to change the port to be used by docfx."
To preview the site, cd
to docs
:
cd ../docs
and then type:
docfx serve
or if the port 8080
is taken by another application, just use another port:
docfx serve -p 8081
Now the documentation site is running.
Open a browser and navigate to http://localhost:8080
.
Alternatively, if you place the folder of the generated site under the DocFx folder, you may build and run the site with just a single line.
docfx --serve
You may delete the generated folders, reference and docs. They are recreated in each build.
Publish the Generated Documentation Site to GitHub Pages
Push
your local git repository to your github remote repository. - In github repository, go to Settings (it's far right with the gear icon).
- Scroll down to GitHub Pages section.
- Select master branch /docs folder as Source.
- Do NOT select theme.
That's all. Your documentation site will be available soon, if not immediately, at:
`https://USER_NAME.github.io/PROJECT_NAME/`
The PDF Adventure
DocFx can generate a single PDF file, for the whole generated documentation. Not without problems.
DocFx generates the PDF output using the wkhtmltopdf tool.
To download and install wkhtmltopdf, open a terminal as administrator and type:
choco install wkhtmltopdf -y
In order to generate the coveted PDF file, the user has to read and ...understand the relevant documentation provided by DocFx.
One piece of that information can be found in the user manual while the other can be found in the third walkthrough.
Here is my way, after a lot of digging and experimenting:
- Add a PDF folder inside DocFx folder
- Add the following toc.yml inside PDF folder:
- name: Concepts
href: ../Concepts/toc.yml
- name: Reference
href: ../reference/toc.yml
- Add a
pdf
section in the docfx.json with the following content:
"pdf": {
"content": [
{
"files": [ "PDF/toc.yml" ]
},
{
"files": [
"reference/**.yml",
"reference/index.md"
],
"exclude": [
"**/toc.yml",
"**/toc.md"
]
},
{
"files": [
"Concepts/**.md",
"Concepts/**/toc.yml",
"toc.yml",
"*.md"
],
"exclude": [
"**/bin/**",
"**/obj/**",
"PDF/**",
"**/toc.yml",
"**/toc.md"
]
}
],
"resource": [
{
"files": [ "images/**" ],
"exclude": [
"**/bin/**",
"**/obj/**",
"PDF/**"
]
}
],
"dest": "_pdf",
"outline": "NoOutline"
}
- Open a terminal,
cd
to DocFx folder and type:
docfx pdf
This will generate a PDF file, without outline, meaning PDF TOC. Obviously, there is a problem and the outline is not correctly generated. So I deactivated using the "outline": "NoOutline"
.
Tested on
- Windows 10
- docfx 2.48.1.0
- wkhtmltopdf 0.12.5 (with patched qt)
History
- 17th February, 2020: Initial version