Table of Contents

Documentation With Docfx

Documentation plays a crucial role in helping everyone adopt and use custom packages. For packages published by the Bonsai Foundation, we use docfx, a static site generator for .NET projects, to automatically generate and publish documentation pages. As we have integrated and extended docfx with specific Bonsai documentation features, we encourage package developers to use docfx to ensure a consistent and integrated experience across the Bonsai community.

The following article will go into detail on how to create a docfx website for your package. For documentation style guidelines, check out the Documentation Style Guide.

Tip

We recommend using a code editor with an integrated terminal like Visual Studio Code to follow along with these instructions.

Repository organization

To help long term maintenance of documentation, we recommend package repositories to be organized according to the following standard folder structure before setting up docfx:

.
├── .bonsai/                 # Local Bonsai Environment (see note below) 
├── .github/workflows/       # GitHub Actions Folder (see note below) 
│   └── docs.yml
├── docs/                    # Folder to setup docfx
└── src/
    └── Bonsai.PackageName/  # Project files here
...
  • .bonsai/ - A local Bonsai environment is required to run the script that exports Bonsai workflow images. To create one, run the following commands:
dotnet new install Bonsai.Templates
dotnet new bonsaienv
  • .github/workflows/ - The docfx website is often automatically published to GitHub Pages using a GitHub Actions workflow specified in the docs.yml file. Unfortunately these workflows tend to be very project specific and we do not yet have a standardized pipeline. For a minimal example and inspiration you can check the workflow on a package repository that has been recently updated, e.g. bonsai-rx/zeromq.

Setup docfx

You can setup a local installation of docfx directly in your package repository with the following commands (executed in the root directory):

dotnet new tool-manifest
dotnet tool install --local docfx

Then navigate to the docs folder and initialize a new docfx website with the following command:

dotnet docfx init

We recommend the following options for new websites (make sure to match the name to your package):

Name (mysite): Bonsai - Package Name
Generate .NET API documentation? [y/n] (y): y
.NET projects location (src): src
Markdown docs location (docs): articles
Enable site search? [y/n] (y): y
Enable PDF? [y/n] (y): n

You should now have a minimal docfx website. Run the following command to generate a local preview of the website, and verify that API documentation for your package has been generated successfully:

dotnet docfx --serve

Docfx folder organization

The documentation guides assume the docs folder is organized according to the following layout:

.
├── api/                     # Automatically generated by docfx
├── apidoc/                  # Place individual operator articles here (see style guide)
├── articles/                # Place "Manual" section articles here (see style guide) 
├── bonsai/                  # Docfx-tools submodule (see note below)
├── images/                  # Place images like screenshots here
├── template/                # Custom CSS template (see note below)
│   └── public/
│       ├── main.css
│       └── main.js
├── tutorials/               # Place "Tutorials" section articles here (see style guide)
├── workflows/               # Place .bonsai workflow files here for image export
├── build.ps1                # Bonsai workflow image export script (see note below)
├── logo.svg                 # Website logo
└── favicon.ico              # Website bookmark logo
...
  • bonsai/ - this folder is where we initialize the submodule referencing docfx-tools. This submodule contains scripts for automating image export from Bonsai workflows (if you want to include them in your article) and also common infrastructure for workflow containers. To create this submodule, run this command in the docs folder:
git submodule add https://github.com/bonsai-rx/docfx-tools bonsai

If you cloned the repository and the bonsai folder does not contain any files:

git submodule update --init

To update the submodule to the latest commit:

git submodule update --remote
  • template/ - the files in this docfx template extend the base template in docfx-tools. Below are templates for main.css and main.js which add a GitHub link to the top right of the navigation bar and include all styles for workflow containers.
main.css
@import "workflow.css";
main.js
import WorkflowContainer from "./workflow.js"

export default {
    defaultTheme: 'auto',
    iconLinks: [{
        icon: 'github',
        href: 'https://github.com/org-name/PackageName',
        title: 'GitHub'
    }],
    start: () => {
        WorkflowContainer.init();
    }
}
  • build.ps1 - this custom script exports Bonsai workflow images using docfx-tools and then calls the docfx build process. Make sure to change the line to point to your package output location:
.\bonsai\modules\Export-Image.ps1 "..\src\Bonsai.PackageName\bin\Release\net462"
dotnet docfx @args
  • logo.svg and favicon.ico - for official Bonsai packages these can be downloaded from the docfx-assets repository.

Configuring docfx

The docfx.json file in the docs folder specifies the configuration options for the website and needs to be modified to make use of all available features. If in doubt, refer to a Bonsai package repository that has been recently updated, e.g. bonsai-rx/machinelearning, or the docfx documentation for more information. These steps are listed in order of appearance in docfx.json.

Hide obsolete operators

Add a filter attribute to hide obsolete operators from the package docs. In the process of upgrading packages we want to avoid documenting operators that are no longer supported (but are still included for compatibility purposes for old workflows). You can also hide private classes that are not supposed to be shown to the end user.

"metadata": [
    {
        "filter": "filter.yml"
    }
]

Make a file called filter.yml with the following lines and place it in the docs directory. You can also specify other uids here.

apiRules:
- exclude:
    hasAttribute:
      uid: System.ObsoleteAttribute

Exclude these files from content to avoid duplicate errors.

"build": {
    "content": [
        "exclude": [
            "_site/**",
            "filter.yml",
            "apidoc/**"
        ]
    ]
}

Enable operator articles

Add the overwrite attribute to ensure individual operator articles stored in the apidoc folder are included in both articles and API docs.

"build": {
    "overwrite": [
      {
        "files": [
          "apidoc/**.md"
        ],
        "exclude": [
          "obj/**",
          "_site/**"
        ]
      }
    ],
}

Add resource files

Modify the resource attribute to include files that need to be imported.

"resource": {
    "files": [
        "logo.svg",
        "favicon.ico",
        "images/**",
        "workflows/**"
    ]
}

Apply modern template

Modify the template attribute to use the modern template and apply the docfx-tools custom templates to enable workflow containers.

"template": [
    "default",
    "modern",
    "bonsai/template",
    "template"
]

Update global metadata

Modify the globalMetadata attribute to change package name and add the _appFooter attribute and description.

"globalMetadata": {
    "_appName": "Bonsai - PackageName",
    "_appTitle": "Bonsai.PackageName",
    "_appFooter": "&copy; 2024 Bonsai Foundation CIC and Contributors. Made with <a href=\"https://dotnet.github.io/docfx\">docfx</a>"
}

Enable custom extensions and xref

Add the markdownEngineProperties attribute to enable markdig(docfx markdown processor) extensions for additional markdown functionality.

"build": {
    "markdownEngineProperties": {
        "markdigExtensions": [
        "attributes",
        "customcontainers"
        ]
    }
}

Add the xref attribute to cross reference classes from the Bonsai library (if you use them to build your package). If you have used other libraries with docfx documentation, add their xrefmap.yml here as well.

"build": {
    "xref": [
        "https://bonsai-rx.org/docs/xrefmap.yml",
    ]
}

Publishing to GitHub Pages

Once you are satisfied with the website, publish to GitHub Pages. A GitHub Actions workflow should already be in place if you follow the standard folder structure. Make sure docs.yml is in the .github/workflows folder.

  1. Setup a new branch called gh-pages on your fork of the repository.
  2. Go to your repo settings > Pages > Build and deployment > under Source select Deploy from a branch and make sure gh-pages is selected.
  3. Commit your edits and push them online.
  4. Under the Actions tab of your GitHub repo, trigger the Build docs workflow manually with the Run workflow button on the branch you committed your edits to. This will build the docs site on the gh-pages branch.
  5. Once the Build docs workflow has been completed, the pages-build-deployment workflow will run and publish your forked repo automatically.
  6. The URL for the site can be found in the Pages section of your repository settings.
Note

To ensure that the Bonsai Editor can link to the reference documentation for package operators, make sure that the PackageProjectUrl in either the .csproj file or the Directory.Build.props file points to the URL for the documentation website.

Version control cleanup

To keep your online GitHub repository clean, you can use .gitignore files to ignore files or documentation which are automatically generated and do not need to be version controlled. Add each item as a separate line to the appropriate .gitignore file in each location.

.
├── .bonsai/
│   └── .gitignore           # Packages, *.exe, *.exe.settings, *.exe.old (local environment files regenerated by Setup.cmd)
└── docs/
    ├── api/
    │   └── .gitignore       # *.yml, .manifest (docfx automatically generated files)
    ├── workflows/
    │   └── .gitignore       # *.layout, *.svg (bonsai workflow layout files and locally generated images)
    └── .gitignore           # _site (folder generated by docfx for local preview)
...

Creating example workflows

To include an example workflow in an article of the documentation, first create the example workflow using the local bonsai environment and save it as articleFileName-workflowName.bonsai into the workflows folder. In the text of the article that references this example workflow, add a workflow custom container.

For example, assuming you want to include CustomPulseTrain-SendCustomWaveform.bonsai:

:::workflow
![Send Custom Waveform](../workflows/CustomPulseTrain-SendCustomWaveform.bonsai)
:::

Workflow images are automatically exported as SVG files by the docfx-tools submodule. The steps below require an existing build.ps1 file and a local bonsai environment.

To generate the images locally for the docfx preview, navigate to the docs folder and run this command (make sure build.ps1 has been modified to point to the correct package folder in src):

./build.ps1

If any of the nodes are greyed out in the generated SVG, then additional packages need to be installed in the local bonsai environment by using the package manager.

Troubleshooting

File not found errors

These are usually due to folders not being in the right place. Check the directory trees above or a repository that has been recently updated, e.g. bonsai-rx/machinelearning, for reference. Also pay attention to any scripts or CSS files that require modification to the package name or link/source location.

Docfx local preview not updating

If you are running the local preview dotnet docfx --serve and not seeing changes:

  1. Make sure that any changes you have made in your code editor are saved.
  2. Hard refresh pages in the browser using either Ctrl+Shift+R and Ctrl+F5 or clear the cache to avoid cache issues.
  3. As a last resort - check that the content updates online by publishing your website.

Differences between local and online builds

If there are discrepancies between local and online builds and they persist, this could indicate a docfx version conflict. The online build process uses a local installation of docfx but it is also possible to install docfx globally (which we do not recommend). To check if this is the cause of the discrepancy:

Make sure to run this command which uses the local installation of docfx

dotnet docfx --serve

Instead of this command which uses the global installation of docfx.

docfx --serve

The .config folder in the root directory contains docfx local version info if you need to check it.

If you wish to update the local installation of docfx run this command in the root directory:

dotnet tool update docfx