Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / DevOps / Git

Use DocFx to Generate a Documentation Web Site and Publish it to GitHub Pages

4.00/5 (1 vote)
17 Feb 2020CPOL8 min read 27.3K  
How to use the open source DocFx to generate a documentation web site (and a PDF file) and publish the site to GitHub Pages
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.

BAT
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:

JSON
{
    "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

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:

YAML
apiRules:
- exclude:
    # inherited members from Form
    uidRegex: ^System\.Windows\.Forms\.Form\..*$
    type: Member
- exclude:
    # inherited members from Control
    uidRegex: ^System\.Windows\.Forms\.Control\..*$
    type: Member	
- exclude:
    # mentioning types from System.* namespace
    uidRegex: ^System\..*$
    type: Type	
- exclude:
    # mentioning types from Microsoft.* namespace
    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:

  1. Concepts/toc.yml:
    YAML
    - name: Easy
      href: Easy/toc.yml
      topicHref: Easy/Abstract.md
    - name: Advanced
      href: Advanced/toc.yml
      topicHref: Advanced/Abstract.md
  2. Concepts/Advanced/toc.yml:
    YAML
    - name: Advanced Overview Title
      href: Advanced.md
  3. Concepts/Easy/toc.yml:
    YAML
    - 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:

BAT
cd ../docs

and then type:

BAT
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:
    YAML
    - name: Concepts
      href: ../Concepts/toc.yml
    - name: Reference
      href: ../reference/toc.yml 
  • Add a pdf section in the docfx.json with the following content:
    JSON
    "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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)