Table of Contents

zkdoc (on-premises)

One of Zeugwerk's CI/CD tools for TwinCAT. zkdoc is the on-premises command-line tool that generates API documentation from TwinCAT PLC source code and produces HTML sites via DocFX. It is the self-hosted counterpart to zkdoc-action.

Use zkdoc when you need to generate documentation in a private or air-gapped environment, integrate with a pipeline that does not use GitHub/GitLab/Bitbucket Actions, or customize the output extensively with your own DocFX templates.

For cloud-based doc generation with no local setup, use zkdoc-action instead.

Comment syntax - How to write documentation comments in your PLC source: Syntax reference.


Availability

Option When to use
zkdoc-action Public repositories on GitHub, GitLab, or Bitbucket. Free tier (30 builds/month).
zkdoc CLI (this page) Private repos, on-premises pipelines, or any CI that runs Windows executables. Requires a license.

Contact us for licensing, trials, and on-premises options.


Requirements

Requirement Notes
Windows Required; zkdoc runs as a Windows .NET executable.
.NET runtime Bundled with the zkdoc distribution.
License file license.lic must be placed in the same folder as zkdoc.exe. Trial available on request.
DocFX (optional) Required only for HTML output. Download from dotnet.github.io/docfx.

Installation & licensing

  1. Extract the zkdoc ZIP archive to a folder on your machine (e.g. C:\tools\zkdoc\).
  2. Place license.lic (provided by Zeugwerk) in the same folder.
  3. Optionally install DocFX and add docfx.exe to your PATH.

Verify the installation:

zkdoc.exe --version

Quick start

Point zkdoc at your .plcproj file and it extracts documentation, writes Markdown, and sets up a DocFX project:

zkdoc.exe --docfx --markdown -o "C:\output\docs" "C:\repos\MyProject\MyPLC\MyPLC.plcproj"

Then build the HTML site with DocFX:

docfx.exe build "C:\output\docs\docfx.json"

Serve locally for preview:

docfx.exe serve "C:\output\docs\docfx.json"

Writing documentation comments

zkdoc extracts documentation written directly in your PLC source using /// and //< comment delimiters. The same syntax works with zkdoc-action in the cloud.

For the full reference - delimiter rules, visibility filters, \copydoc, cross-references, diagrams, and code formatting - see the Comment syntax reference.


Usage

zkdoc.exe [filepaths...] [options]

filepaths can be:

  • One or more paths to .plcproj files.
  • A directory that contains a .Zeugwerk/config.json (the project is resolved automatically). Pass . for the current directory.

CLI reference

Option Short Default Description
filepaths (current dir) Paths to .plcproj files or directories containing .Zeugwerk/config.json. Multiple paths can be listed; zkdoc combines them into one documentation set.
--output -o documentation Root output directory. Created if it does not exist. All generated files are written under this path.
--docfx - Subfolder name inside --output for DocFX Markdown and the docfx.json project file (e.g. reference). Required to produce HTML with DocFX.
--markdown - Subfolder name inside --output for plain Markdown reference files (no DocFX dependency). Can be used independently of --docfx.
--filter -f ((_)*Test[s]*\\.*?\|.*?\\(_)*Test[s]*\\.*?\|.*?\\(_)*Example[s]*\\.*?) Regular expression to exclude source paths. Matched against the full file path. Files whose path contains _Test, _Tests, or _Examples as a subfolder are excluded by default.
--include-internal false Include objects marked with the INTERNAL access modifier or the {attribute 'hide'} pragma. Excluded by default.
--exclude-private false Exclude objects and methods with the PRIVATE access modifier. Included by default.
--exclude-protected false Exclude objects and methods with the PROTECTED access modifier. Included by default.
--depth 1 Maximum category depth shown in the navigation sidebar of the generated site. Increase for projects with deep namespaces.
--twincat-source-target src Subfolder inside --output where TwinCAT PLC source files are extracted.
--telemetry false Send anonymous usage data to Zeugwerk (install ID, tool name, version).

Output structure

After running zkdoc --docfx --markdown -o documentation MyPLC.plcproj, the output directory contains:

documentation/
├── docfx.json              ← DocFX project file (generated once; not overwritten if it exists)
├── toc.yml                 ← Top-level table of contents
├── index.md                ← Landing page (generated if not present)
├── reference/              ← DocFX Markdown (--docfx)
│   ├── toc.yml
│   └── <Namespace>/
│       ├── <FunctionBlock>.md
│       ├── <Interface>.md
│       └── ...
├── md-reference/           ← Plain Markdown (--markdown), no DocFX deps
│   └── ...
├── userguide/              ← Placeholder user guide (generated if not present)
│   ├── introduction.md
│   └── toc.yml
└── html/                   ← Final HTML output (produced by DocFX build)
    └── ...
Note

If docfx.json already exists in the output folder, zkdoc does not overwrite it. This lets you maintain a custom template or adjusted configuration across runs.


Examples

Single PLC, full HTML site

zkdoc.exe --docfx --markdown -o docs MyProject\MyPLC\MyPLC.plcproj
docfx.exe build docs\docfx.json
docfx.exe serve docs\docfx.json

Multiple PLCs in one documentation set

List all .plcproj paths; zkdoc merges them into a single API reference:

zkdoc.exe --docfx --markdown -o docs ^
  src\LibraryA\LibraryA.plcproj ^
  src\LibraryB\LibraryB.plcproj

Zeugwerk / Twinpack project (auto-discovery)

Pass the repository root (.) and zkdoc will use .Zeugwerk/config.json to discover all PLC projects:

zkdoc.exe --docfx --markdown -o docs .

Exclude additional folders

Use --filter to extend the default exclusions with your own pattern:

:: Exclude _Internal and _Internals folders as well
zkdoc.exe --docfx -o docs --filter "((_)*Internal[s]*\\.*?)" MyPLC.plcproj

Include internal members

zkdoc.exe --docfx -o docs --include-internal MyPLC.plcproj

Exclude private and protected members

zkdoc.exe --docfx -o docs --exclude-private --exclude-protected MyPLC.plcproj

Deeper namespace hierarchy

zkdoc.exe --docfx -o docs --depth 3 MyPLC.plcproj

Customizing documentation output

For adding custom Markdown pages, adjusting the folder layout, and customizing the DocFX HTML template, see the Customizing documentation output reference. The same options apply to zkdoc-action.


Integration with CI/CD pipelines

zkdoc requires a Windows agent with TwinCAT XAE and DocFX installed. The pipeline generates Markdown from the PLC source, then DocFX converts it to HTML. The HTML output can be archived as a build artifact or deployed to a web server / GitHub Pages.

Jenkins (Declarative Pipeline)

pipeline {
    agent { label 'windows-twincat' }

    stages {
        stage('Generate documentation') {
            steps {
                // Generate DocFX Markdown from PLC source into the documentation/ folder.
                bat "zkdoc.exe --docfx reference --output documentation ."
                // Build the HTML site from the generated DocFX project.
                bat "docfx.exe build documentation\\docfx.json"
            }
        }
        stage('Publish') {
            steps {
                publishHTML(target: [
                    reportDir: 'documentation/html',
                    reportFiles: 'index.html',
                    reportName: 'API Documentation'
                ])
            }
        }
    }

    post {
        always {
            archiveArtifacts artifacts: 'documentation/html/**/*', allowEmptyArchive: true
        }
    }
}

Azure DevOps

jobs:
  - job: Docs
    pool:
      name: 'windows-twincat-agents'
    steps:
      - script: |
          zkdoc.exe --docfx reference --output documentation .
          docfx.exe build documentation\docfx.json
        displayName: Generate documentation

      - task: PublishPipelineArtifact@1
        inputs:
          targetPath: documentation/html
          artifact: api-docs

Troubleshooting

Symptom Likely cause Fix
License verification failed license.lic missing or expired Place license.lic next to zkdoc.exe. Contact us for a trial or renewal.
Invalid arguments or no output No valid .plcproj or config.json found Verify the filepath argument and that the file exists.
Empty reference section All POUs matched by the filter Check --filter. Run with --include-internal to see if items are being hidden by access modifiers.
DocFX build errors Malformed Markdown or missing references Check zkdoc console output for parse warnings. Missing \copydoc targets print an explicit error message.
HTML layout broken Custom docfx.json references a missing template Verify template names in docfx.json. The default templates are default, modern, template, and statictoc.
docfx.json not updated Intentional - zkdoc never overwrites an existing docfx.json Edit docfx.json manually, or delete it to let zkdoc regenerate it.

Summary

  1. Install zkdoc and place license.lic next to the executable.
  2. Optionally install DocFX for HTML output.
  3. Run zkdoc.exe --docfx --markdown -o <out> <path-to.plcproj>.
  4. Run docfx.exe build <out>/docfx.json and open the html/ folder.
  5. Add custom Markdown pages to userguide/ and link them in toc.yml.

For comment syntax, cross-references, diagrams, and code formatting: Syntax reference.
For cloud-based generation without a local setup: zkdoc-action.