docToolchain Manual

1. What Is docToolchain?

1.1. Introduction

docToolchain is a documentation generation tool that uses the Docs as Code approach as a basis for its architecture, plus some additional automation provided by the arc42 template.

1.2. Docs as Code

‘Docs as code’ refers to a philosophy that you should write documentation using the same tools as you use to write code. If you need to write technical docs for your software project, why not use the same tools and processes as you use for your source code? There are so many benefits:

  • You don’t have to learn a complicated docs management system.

  • Developers feel more at home in the docs because they look and feel like code.

  • You can manage docs using standard version control like GitHub.

1.3. arc42

arc42 has been a part of docToolchain since the earliest version. But what is arc42?

Dr. Gernot Starke and Peter Hruschka created the arc42 template as a standard for software architecture documentation. They used their experience of software architectures both in the template structure and the explanations that appear in each chapter to guide you when you’re writing your documentation.

arc42 is available in well-known formats including MS Word, textile, and Confluence. All of these formats are automatically generated from a single golden master which is formatted in AsciiDoc.

1.4. How docToolchain Brings Everything Together

To follow a docs as code approach, you need a build script that automates steps like exporting diagrams and rendering Markdown (or AsciiDoc in the case of docToolchain) to the target format.

Creating this type of build script is not easy (and even harder to maintain). There are also lots of questions to answer: “How do I create .docx?” and “Why doesn’t lib x work with lib y?”

docToolchain is the result of one developer’s journey through the docs as code universe. The goal of docToolchain is to automate the creation of technical docs through an easy-to-use build script that only needs to be configured not modified, and that is nurtured and cared for by a diverse open source community.

1.5. What You Get with docToolchain

1.5.1. A Ready-Made Document Management System

By using a version control system like Git, you get a perfect document management system for free. Git allows you to version your docs, branch them, and also leaves an audit trail. You can even check who wrote which part of the docs. Isn’t that great?

And because your docs are simple plain text, it’s easy to do a diff and see exactly what has changed. Bonus: storing your docs in the same repo as your code means they’re always in sync!

1.5.2. Built-In Collaboration and Review

As a distributed version control system, Git comes with doc collaboration and review processes built in. People can fork the docs and send pull requests for the changes they make. You review the changes. Done!

Most Git frontends like Bitbucket, GitLab and GitHub also allow you to reject pull requests with comments.

1.5.3. Image References and Code Snippets

Instead of pasting images into a binary document format, docToolchain lets you reference images. This ensures that your imagery is always up-to-date every time you rebuild your documents.

You can also reference code snippets directly from your source code. You’ll save so much time because your docs and code will always be in sync and completely up to date!

1.5.4. Compound and Stakeholder-Tailored Docs

As if image refs and code snippets weren’t enough, docToolchain also lets you split docs into several sub-documents plus a master for greater cohesion. And you’re not restricted to one master. You can create master docs for different stakeholders that only contain the chapters they need.

1.5.5. And So Much More…​

If you can dream it, you can script it! Want to include a list of open issues from Jira? You can! Want to include a changelog from Git? Go for it! Want to use inline text-based diagrams? Knock yourself out!


1.6. Install docToolchain

1.6.1. Prerequisites

  • Java 17, 21 or 25 — check with java -version (./dtcw4 local install java installs Java 25 for you)

  • git — needed to clone docToolchain during installation

  • Bashdtcw4 is a Bash script (on Windows, use WSL2)

1.6.2. Quick Start

1. Get the Wrapper Script

Download dtcw4 into your project directory:

cd <your project>
curl -Lo dtcw4 https://doctoolchain.org/dtcw4
chmod +x dtcw4
On Windows, use WSL2. dtcw4 is a Bash script.
2. Install docToolchain
# Install Java if needed
./dtcw4 local install java

# Install docToolchain v4
./dtcw4 local install doctoolchain

This clones the main-4.x branch and builds the runtime JARs once (~2 min). After that, no build tool is involved at runtime.

3. Download a Template (optional)

First, create a config file if you don’t have one yet:

touch docToolchainConfig.groovy
./dtcw4 local downloadTemplate

This interactively installs the arc42 architecture template and updates your config file.

4. Generate Output
./dtcw4 local generateHTML
./dtcw4 local generatePDF
./dtcw4 local generateSite

Output is written to the build/ directory:

build/
├── html5/          # generateHTML output
├── pdf/            # generatePDF output
└── microsite/
    └── output/     # generateSite output
5. List All Tasks
./dtcw4 tasks

1.6.3. How It Works

Only dtcw4 lives in your project directory. It handles:

  1. Installation: Clones docToolchain from GitHub and builds the runtime JARs once.

  2. Task execution: Delegates to the installed dtcw in ~/.doctoolchain/docToolchain-4.0.0/, which runs tasks directly via the JVM — no Gradle, no daemon.

Runtime JARs are stored in ~/.doctoolchain/docToolchain-4.0.0/lib/. Task execution uses direct JVM invocation (~2-3s startup).

1.6.4. Running in Docker

docToolchain provides a container image from Docker Hub:

./dtcw4 docker generateHTML

The wrapper script detects the container engine and pulls the image automatically.

Custom Docker Image
./dtcw4 docker image <image_name> generateHTML
Environment Variables for Docker

Create a file dtcw_docker.env in your project directory:

PROJECT=MY_PROJECT
TEAM=MY_TEAM

1.6.5. Updating

./dtcw4 local install doctoolchain --update

This pulls the latest main-4.x and rebuilds the runtime JARs.

1.6.6. Environment Variables

Variable Default Description

DTC_VERSION

4.0.0

docToolchain version to use

DTC_V4_BRANCH

main-4.x

Git branch to install from

DTC_HEADLESS

auto-detected

Set to true for non-interactive mode (CI/CD)

DTC_CONFIG_FILE

docToolchainConfig.groovy

Path to configuration file

DTC_SITETHEME

(none)

URL to an external microsite theme zip


1.7. Features

docToolchain v4 is a docs-as-code tool that generates professional documentation from AsciiDoc sources.

1.7.1. Fast Startup

Tasks run via direct JVM invocation — no Gradle daemon, no build system overhead. Typical startup time is 2-3 seconds.

1.7.2. No Ruby Required

v4 uses AsciidoctorJ (the Java port of AsciiDoctor) exclusively. No Ruby gems, no external asciidoctor CLI needed.

1.7.3. Multiple Output Formats

Generate HTML, PDF, or a full microsite from the same AsciiDoc sources. See the Tasks section for all available output formats.

1.7.4. Multiple Markup Formats

The microsite renders more than AsciiDoc: Markdown and plain HTML work out of the box, and reStructuredText (.rst) is supported via a one-line converter entry. See Multi-Markup for the full list and how to enable .rst.

1.7.5. Diagram Support

Built-in support for text-based diagrams via asciidoctor-diagram: PlantUML, ditaa, Mermaid, and more.

1.7.6. Math & Formulas (STEM)

docToolchain renders mathematical and scientific formulas (AsciiDoc STEM content). STEM is enabled out of the box — no configuration needed.

Use it inline or as a block, in either the latexmath or the asciimath notation:

A square root inline: stem:[sqrt(4) = 2].

[latexmath]
++++
\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
++++

[asciimath]
++++
sum_(i=1)^n i = (n(n+1))/2
++++

The default notation for an unqualified \$…\$ / [stem] is latexmath. Override it per document with :stem: asciimath, or pin a single expression with the explicit [asciimath] / [latexmath] block forms shown above.

Formulas render in all main output formats:

  • HTML — rendered in the browser via MathJax.

  • PDF — rendered natively by asciidoctor-pdf.

In the microsite, MathJax is loaded the same way as in standalone HTML. For fully offline / self-contained sites you can bundle MathJax locally instead of loading it from a CDN — see the tracking issue.

1.7.7. Confluence Publishing

Publish your documentation directly to Confluence, keeping docs-as-code and Confluence in sync. Only changed pages are updated — no spam for page watchers.

1.7.8. Cross-Platform

All tasks work on Linux, macOS, and Windows. The exportPPT task uses Apache POI — no Windows-only dependencies.

1.7.9. Template Support

Bootstrap your project with architecture templates like arc42 or req42.

1.7.10. CI/CD Ready

Set DTC_HEADLESS=true for non-interactive mode. Works with GitHub Actions, GitLab CI, Jenkins, and any CI system with Java 17, 21 or 25.


1.8. Extending docToolchain: Custom Tasks and Monkey-Patching

docToolchain ships every task as a self-contained Groovy script. You can use the same mechanism in your own project — to add a task or to change one that docToolchain already provides. Neither needs a fork, a build step, or an edit to a registry.

This is a v4 feature (the Gradle-free runtime driven by dtcw/dtcw4). The older v3 customTasks config entry belongs to the Gradle build and does not apply here.

1.8.1. How task resolution works

When you run ./dtcw <task>, the wrapper looks for the task script in two places, the project first, the installation second:

  1. scripts/<task>.groovy in your project (the project scripts directory)

  2. <task>.groovy in the installed docToolchain (~/.doctoolchain/docToolchain-<version>/scripts/)

A file counts as a task only if it carries the marker // @task within its first five lines — exactly the rule used by the built-in tasks. This is how a project script can be discovered without you registering it anywhere.

The project scripts directory defaults to scripts/ under your project root. Override it with the environment variable DTC_PROJECT_SCRIPTS_DIR.

In the docker environment the project is mounted at a fixed location inside the container, so DTC_PROJECT_SCRIPTS_DIR must be a path relative to the project root. An absolute value cannot be reached inside the container, so project tasks would not be found there (resolution falls back to the installed task).

1.8.2. Adding a custom task

Create a skeleton with createTask and edit it:

./dtcw createTask exportNotion

This writes scripts/exportNotion.groovy with the // @task marker already in place. Add your logic, then run it:

./dtcw exportNotion

It also shows up in the task list, under its own heading:

./dtcw tasks

You can of course create the file by hand instead — the only requirement is the // @task marker near the top.

Reusing docToolchain’s helpers

A custom task can reuse the bundled helpers (for example DtcConfig to read docToolchainConfig.groovy). They live in the installation, not your project, and dtcw tells your script where via the dtc.scriptsHome system property:

def docDir = System.getProperty('docDir', '.')
def configFile = System.getProperty('mainConfigFile', 'docToolchainConfig.groovy')

def scriptsHome = System.getProperty('dtc.scriptsHome')
def gcl = new GroovyClassLoader(this.class.classLoader)
def DtcConfig = gcl.parseClass(new File(scriptsHome, 'lib/DtcConfig.groovy'))
def config = DtcConfig.load(docDir, configFile).getRaw()

println "inputPath is ${config.inputPath}"

The skeleton created by createTask already contains this pattern.

1.8.3. Monkey-patching an installed task

To change what a shipped task does, copy it into your project and edit the copy:

./dtcw copyTask generateHTML

This copies the installed generateHTML.groovy to scripts/generateHTML.groovy in your project. Because the project copy has the same name as an installed task, it overrides it: from now on ./dtcw generateHTML runs your copy.

docToolchain makes the override visible so you never patch by accident:

  • ./dtcw generateHTML prints a note to stderr that the installed task is being overridden by your project file.

  • ./dtcw tasks lists generateHTML as overridden by scripts/generateHTML.groovy.

The copy keeps working even though it now lives in your project: its bundled helpers and resources still resolve from the installation via dtc.scriptsHome.

To return to the shipped behaviour, simply delete your copy.

A monkey-patched task is pinned to the version you copied. After upgrading docToolchain, re-copy the task if you want to pick up upstream changes.

1.8.4. Security note

Project tasks are Groovy code that runs with your privileges — the same trust level that docToolchainConfig.groovy already has, since it too is executable Groovy. Opening someone else’s project and running dtcw runs their scripts. Treat a project’s scripts/ directory with the same care as its config.


2. docToolchain Tasks

3. generateHTML

3.1. About This Task

Generates HTML5 from your AsciiDoc sources using AsciidoctorJ. Output is written to build/html5/.

./dtcw4 local generateHTML

3.2. Configuration

Specify which files to render in your docToolchainConfig.groovy:

inputFiles = [
    [file: 'manual.adoc', formats: ['html','pdf']],
]

3.3. Single-File HTML

To produce a single self-contained HTML file, set :data-uri: in your AsciiDoc source. Be aware that the file can become very large.

3.4. Text-Based Diagrams

docToolchain includes the asciidoctor-diagram extension for PlantUML, ditaa, and other diagram types.

.example diagram
[plantuml, "{plantUMLDir}demoPlantUML", png]
----
class BlockProcessor
class DiagramBlock

BlockProcessor <|-- DiagramBlock
----
Use {plantUMLDir} in the image name to ensure diagrams work for both HTML and PDF output.
Use a unique image name for each diagram to avoid overwriting.

3.5. Controlling Diagram Size

Use the width attribute (pixels) or scale attribute (ratio):

[plantuml, target="{plantUMLDir}myDiagram", format=png, width=250]
[plantuml, target="{plantUMLDir}myDiagram", format=png, scale=0.75]
If Graphviz is not installed, add !pragma layout smetana as the first line of your PlantUML diagram to use the built-in Java layout engine.

3.7. Source

View the source of this task: scripts/generateHTML.groovy on GitHub


4. generatePDF

4.1. About This Task

Generates PDF from your AsciiDoc sources using AsciidoctorJ PDF. Output is written to build/pdf/. The result looks like a typeset book, not a print-to-PDF web page.

./dtcw4 local generatePDF

4.2. Configuration

Specify which files to render in your docToolchainConfig.groovy:

inputFiles = [
    [file: 'manual.adoc', formats: ['html','pdf']],
]

Add the files you want rendered with the pdf format.

4.3. Custom PDF Theme

To customize colors, fonts, headers, and footers, create a custom-theme.yml file.

  1. Run ./dtcw4 local copyThemes pdfTheme to copy the bundled pdfTheme (including the example template_config/pdfTheme/custom-theme.yml) into your project.

  2. Reference it from your AsciiDoc file:

:pdf-themesdir: {docdir}/../pdfTheme
:pdf-theme: custom

4.5. Source

View the source of this task: scripts/generatePDF.groovy on GitHub


5. generateSite

5.1. About This Task

When your documentation grows beyond a single document, a microsite bundles everything into a navigable website with landing page, blog, and search. The generateSite task renders a static site from your AsciiDoc sources using docToolchain’s built-in site generator. (Up to v3 this was jBake; v4 replaced it with a self-contained generator while keeping the same jbake--prefixed page metadata.)

./dtcw4 local generateSite

Output is written to build/microsite/output/.

5.2. Pages

The microsite is page-oriented: each AsciiDoc file becomes a page. Add page metadata to include a page in the site (the jbake- prefix is kept for backwards compatibility):

page metadata
:jbake-menu: arc42
:jbake-title: Solution Strategy
:jbake-order: 4
:jbake-type: page_toc
:jbake-status: published

:toc:

== Solution Strategy
jbake-menu

The top-level menu code. Defaults to the top-level folder name (without order prefix).

jbake-title

Title shown in the navigation. Defaults to the first headline.

jbake-order

Sort order in the sidebar. Defaults to the numeric prefix of the filename or folder.

jbake-type

Controls the template. Use page_toc for a page with sidebar table of contents, or page for full-width.

jbake-status

Either draft or published. Files prefixed with _ default to draft.

Start pages with a == level headline.

5.3. Configuration

Configuration follows a convention-over-configuration approach. Defaults work out of the box — configure only what you want to change.

5.3.1. Menu

Navigation Structure
  • A top-level menu with entries across the top of the page.

  • A section sidebar for each top-level menu entry.

The structure is derived from your folder layout:

src/docs/
├── 10_foo
│   ├── 10_first.adoc
│   └── 20_second.adoc
└── 20_bar
    ├── 10_lorem.adoc
    └── 20_ipsum
        ├── 10_topic-A.adoc
        └── 20_topic-B.adoc

Top-level folders determine menu codes (foo, bar). Sub-folders create navigation tree nodes. Numeric prefixes control sort order.

Configuring the Top-Level Menu

Map menu codes to display titles in your docToolchainConfig.groovy:

menu = [code1: 'Some Title 1', code2: 'Other Title 2', code3: '-']

Use '-' to hide a menu entry. When no mapping is defined, the code itself is used as the title. The order in the map determines the display order.

In the right column, links are controlled by values in docToolchainConfig.groovy:

  • "Improve this doc": shown when gitRepoUrl is set.

  • "Create an issue": shown when issueUrl is set.

5.4. Templates and Style

The bundled templates use Bootstrap 5 as their CSS framework. Templates and styles are bundled with docToolchain.

5.4.1. Branding (Fonts, Colors, Logo)

You can re-brand the microsite without copying the whole theme. Set any of these keys in the microsite block of docToolchainConfig.groovy. Every value is optional — leave it empty to keep the theme default.

microsite.with {
    // your logo, relative to the site's asset root (assets/images)
    logo = 'images/my-logo.png'

    // colors — any CSS color value
    colorPrimary     = '#1f8a5b'   // accent / brand color
    colorPrimaryDark = '#155138'   // darker shade used in gradients
    colorLink        = '#176c49'   // body link color
    colorInk         = '#17181c'   // main text color
    colorBackground  = '#f4f3ee'   // page background
    colorCard        = '#fbfaf6'   // card / panel background

    // fonts — a CSS font-family value
    fontHeading = "'Roboto', sans-serif"
    fontBody    = "'Open Sans', sans-serif"
    fontMono    = "'JetBrains Mono', monospace"
    // optional: load custom web fonts (e.g. a Google Fonts stylesheet)
    fontCssUrl  = 'https://fonts.googleapis.com/css2?family=Roboto&family=Open+Sans&display=swap'
}

The colors override the theme’s CSS custom properties and apply to both the pages and the landing page. For deeper changes, copy the full theme with copyThemes jBakeTheme and edit the CSS directly.

5.5. Landing Page

The microsite needs a landing page as its start page. Run copyLandingPage to scaffold an editable copy into your project, then configure it in docToolchainConfig.groovy:

microsite.with {
    landingPage = 'landingpage.gsp'   // file in your theme's doc/ folder
}

The landing page is plain HTML5 styled with Bootstrap — the header and footer are added automatically. If microsite.landingPage is not set, the site is generated without an index.html landing page.

index.gsp in src/site/templates is the internal master template, not your landing page. Put your landing-page content in src/site/doc/<landingPage> instead.

5.6. Blog

The microsite includes a blog. Create posts in src/docs/blog/<year>/<post-name>.adoc:

blog post template
:jbake-title: My Post Title
:jbake-date: 2025-01-15
:jbake-type: post
:jbake-tags: blog, asciidoc
:jbake-status: published

= {jbake-title}
{jbake-date}

Your content here.

The microsite includes a search input field that can be linked to an external search engine.

5.8. CI/CD

Set DTC_HEADLESS=true in automated builds to skip interactive prompts (e.g., theme installation).

5.9. Source

View the source of this task: scripts/generateSite.groovy on GitHub


6. publishToConfluence

6.1. About This Task

This task takes a generated HTML file, splits it by headline, and pushes it to your instance of Confluence. This lets you use the docs-as-code approach even if your organisation insists on using Confluence as its main document repository.

Since 01.01.2024, Atlassian has been turning off API V1 for Confluence Cloud wherever a V2 equivalent exists. docToolchain versions from 3.1 on support API V2. If you are using an older version of docToolchain, you’ll need to upgrade to a newer version. To enable API V2, set useV1Api to false in the Confluence section of the docToolchain configuration file.

Currently, docToolchain only has full support for the old Confluence editor. The new editor is not fully supported yet. You can use the new editor, but you may experience some unexpected layout issues/ changes. To make use of the new editor you need to set enforceNewEditor to true in the Confluence section of the docToolchain configuration file.

6.2. Special Features

6.2.1. Easy Code Block Conversion

[source]-blocks are converted to code-macro blocks in Confluence.

Confluence supports a very limited list of languages supported for code block syntax highlighting. When specifying an unknown language, it would even display an error. Therefore, some transformation is applied.

  • If no language is given in the source block, it is explicitly set to plain text (because the default would be Java that might not always apply).

  • Some known and common AsciiDoc source languages are mapped to Confluence code block languages.

    source target note

    json

    yml

    produces an acceptable highlighting

    shell

    bash

    only a specific shell is supported

    yaml

    yml

    different name of language

  • If the language of the source block is not supported by Confluence, it is set to plain text as fallback to avoid the error.

Get a list of valid languages (and learn how to add others) here.

6.2.2. Minimal Impact on Non-Techie Confluence Users

Only pages and images that changed between task runs are published, and only those changes are notified to page watchers, cutting down on 'spam'.

6.2.3. Keywords Automatically Attached as Labels

:keywords: are attached as labels to every Confluence page generated using the publishToConfluence task. See Atlassian’s own guidelines on labels. Several keywords are allowed, and they must be separated by commas. For example: :keywords: label_1, label-2, label3, …​. Labels (keywords) must not contain a space character. Use either '_' or '-'.

6.3. Configuration

You configure the publishToConfluence task in the file docToolchainConfig.groovy. It is located in the root of your project folder. We try to make the configuration self-explanatory, but below is some more information about each config option.

input

is an array of files to upload to Confluence with the ability to configure a different parent page for each file.

6.4. Attributes

  • file: absolute or relative path to the asciidoc generated html file to be exported

  • url: absolute URL to an asciidoc generated html file to be exported

  • ancestorName (optional): the name of the parent page in Confluence as string; this attribute has priority over ancestorId, but if page with given name doesn’t exist, ancestorId will be used as a fallback

  • ancestorId (optional): the id of the parent page in Confluence as string; leave this empty if a new parent shall be created in the space

The following four keys can also be used in the global section below

  • spaceKey: page specific variable for the key of the confluence space to write to case sensitive! If the case is not correct, it can be that new page will be created but can’t be updated in the next run.

  • subpagesForSections (optional): The number of nested sub-pages to create. Default is '1'. '0' means creating all on one page. The following migration for removed configuration can be used.

    • allInOnePage = true is the same as subpagesForSections = 0

    • allInOnePage = false && createSubpages = false is the same as subpagesForSections = 1

    • allInOnePage = false && createSubpages = true is the same as subpagesForSections = 2

  • pagePrefix (optional): page specific variable, the pagePrefix will be a prefix for the page title and it’s sub-pages use this if you only have access to one confluence space but need to store several pages with the same title - a different pagePrefix will make them unique

  • pageSuffix (optional): same usage as prefix but appended to the title and it’s subpages

only 'file' or 'url' is allowed. If both are given, 'url' is ignored

ancestorId

The page ID of the parent page where you want your docs to be published. Go to this page, click Edit and the required ID will show up in the URL. Specify the ID as a string within the config file.

api

Endpoint of the confluenceAPI (REST) to be used and looks like https://[yourServer]/[context], while [context] is optional. If you use Confluence Cloud, you can omit the context. If you use Confluence Server, you may need to set a context, depending on your Confluence configuration.

rateLimit (since 3.2.0), The rate limit for Confluence requests. Default is 10 requests per second.

useV1Api

This feature is available for docToolchain >= 3.1 only

If you set this to false, ensure the api config is set to https://[yourCloudDomain]. (Mind no context given here)

If you are using Confluence Cloud, you can set this to false to use the new API V2. If you are using Confluence Server, you can set this to true to use the old API V1. If you are using Confluence Cloud and set this to true, you will get an error message, as Atlassian has been turning off API V1 since 01.01.2024.

enforceNewEditor

Atlassian is currently rolling out a new editor for Confluence. If you want to use the new editor, you can set this to true. If you are using the old editor, you can set this to false. If you are using the new editor, you may experience some unexpected layout issues/ changes, since the new editor has yet no feature parity and therefore may be incompatible.

disableToC

This boolean configuration determines whether the table of contents (ToC) is disabled on the page once uploaded to Confluence. false by default, so the ToC is active.

pagePrefix/pageSuffix

Confluence can’t handle two pages with the same name - even with different casing (lowercase, UPPERCASE, a mix). This script matches pages regardless of case and refuses to replace a page whose name differs from an existing page only by casing. Ideally, you should create a new Confluence space for each piece of larger documentation. If you are restricted and can’t create new spaces, you can use pagePrefix/pageSuffix to define a prefix/suffix for the doc so that it doesn’t conflict with other page names.

pageVersionComment

Set an optional comment for the new page version in Confluence.

credentials

For security reasons it is highly recommended to store your credentials in a separate file outside the Git repository, such as in your Home folder.

To authenticate with username and API token, use: credentials = "user:${new File("/users/me/apitoken").text}" or credentials = "user:${new File("/users/me/apitoken").text}"`.bytes.encodeBase64().toString()` to …​…​.. You can create an API-token in your profile.

Atlassian is deprecating unscoped (classic) API tokens. If you receive a 403 - Forbidden error with an existing token, create a new scoped API token and select the following scopes:

Scope Purpose

read:me

Verify API credentials (read current user info)

read:confluence-content.all

Read pages, attachments, and labels

write:confluence-content

Create, update, and delete pages, attachments, and labels

read:confluence-space.summary

Read space information (required when using API V2)

To authenticate with username and password, use: credentials = …​…​

You can also set your username, password of apitoken as an environment variable. You then do the following: 1. Open the file that contains the environment variables: a. On a Mac, go to your Home folder and open the file .zprofile. 2. …​.

apikey

In situations where you have to use full user authorisation because of internal Confluence permission handling, you’ll need to add the API-token in addition to the credentials. The API-token cannot be added to the credentials because it’s used for user and password exchange. Therefore, the API-token can be added as parameter apikey, which makes the addition of the token a separate header field with key: keyId and value of apikey. An example (including storing of the real value outside this configuration) is: apikey = "${new File("/home/me/apitoken").text}".

bearerToken

You can pass a Confluence Personal Access Token as the bearerToken. It is an alternative to credentials. Do not confuse it with apiKey.

extraPageContent

If you need to prefix your pages with a warning stating that 'this is generated content', this is where you do it.

enableAttachments

If value is set to true, any links to local file references will be uploaded as attachments. The current implementation only supports a single folder, the name of which will be used as a prefix to validate whether your file should be uploaded. If you enable this feature, and use a folder which starts with 'attachment', an adaption of this prefix is required.

pageLimit

Limits the number of pages retrieved from the server to check if a page with this name already exists.

jiraServerId Only required if you are using Jira on-premise. If you are using Jira cloud you do not need to set this value. Stores the Jira server ID that your Confluence instance is connected to. If a value is set, all anchors pointing to a Jira ticket will be replaced by the Confluence Jira macro. How-To find your Jira server ID please check the Atlassian documentation.

All files to attach will need to be linked inside the document: link:attachment/myfolder/myfile.json[My API definition]

attachmentPrefix

Stores the expected foldername of your output directory. Default is attachment.

proxy

If you need to provide proxy to access Confluence, you can set a map with the keys host (e.g. 'my.proxy.com'), port (e.g. '1234') and schema (e.g. 'http') of your proxy.

useOpenapiMacro

If this option is present and equal to confluence-open-api or swagger-open-api then any source block marked with class openapi will be wrapped in the Elitesoft Swagger Editor macro (see Elitesoft Swagger Editor). The key depends on the version of the macro.

For backward compatibility, if this option is present and equal to true, then again the Elitesoft Swagger Editor macro will be used.

If this option is present and equal to "open-api" then any source block marked with class openapi will be wrapped in Open API Documentation for Confluence macro: (see Open API Documentation for Confluence). A download source (yaml) button is shown by default.
Using the plugin can be handled on different ways.

  • copy/paste the content of the YAML file to the plugin without linking to the origin source by using the url to the YAML file

    [source.openapi,yaml]
    ----
    \include::https://my-domain.com/path-to-yaml[]
    ----
  • copy/paste the content of the YAML file to the plugin without linking to the origin source by using a YAML file in your project structure:

    [source.openapi,yaml]
    ----
    \include::my-yaml-file.yaml[]
    ----
  • create a link between the plugin and the YAML file without copying the content into the plugin. The advantage following this way is that even in case the API specification is changed without re-generating the documentation, the new version of the configuration is used in Confluence.

    [source.openapi,yaml,role="url:https://my-domain.com/path-to-yaml"]
    ----
    \include::https://my-domain.com/path-to-yaml[]
    ----

6.5. CSS Styling

Some AsciiDoctor features depend on specific CSS style definitions. Unless these styles are defined, some formatting that is present in the HTML version will not be represented when published to Confluence. To configure Confluence to include additional style definitions:

  1. Log in to Confluence as a space admin.

  2. Go to the desired space.

  3. Select Space tools > Look and Feel > Stylesheet.

  4. Click Edit then enter the desired style definitions.

  5. Click Save.

The default style definitions can be found in the AsciiDoc project as asciidoctor-default.css. You will most likely NOT want to include the entire thing, as some of the definitions are likely to disrupt Confluence’s layout.

The following style definitions are Confluence-compatible, and will enable the use of the built-in roles (big/small, underline/overline/line-through, COLOR/COLOR-background for the sixteen HTML color names):

.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background-color:#00fafa}
.black{color:#000}
.black-background{background-color:#000}
.blue{color:#0000bf}
.blue-background{background-color:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background-color:#fa00fa}
.gray{color:#606060}
.gray-background{background-color:#7d7d7d}
.green{color:#006000}
.green-background{background-color:#007d00}
.lime{color:#00bf00}
.lime-background{background-color:#00fa00}
.maroon{color:#600000}
.maroon-background{background-color:#7d0000}
.navy{color:#000060}
.navy-background{background-color:#00007d}
.olive{color:#606000}
.olive-background{background-color:#7d7d00}
.purple{color:#600060}
.purple-background{background-color:#7d007d}
.red{color:#bf0000}
.red-background{background-color:#fa0000}
.silver{color:#909090}
.silver-background{background-color:#bcbcbc}
.teal{color:#006060}
.teal-background{background-color:#007d7d}
.white{color:#bfbfbf}
.white-background{background-color:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background-color:#fafa00}

6.6. Source

View the source of this task: scripts/publishToConfluence.groovy on GitHub


7. exportPPT

7.1. About This Task

Exports PowerPoint slides (.pptx) as PNG images and extracts speaker notes as AsciiDoc.

./dtcw4 local exportPPT

In v4, this task uses Apache POI for rendering and works on all platforms (Linux, macOS, Windows). The v3 version was Windows-only (VBScript).

Only .pptx files are supported. Legacy .ppt format is not supported.

7.1.1. Generated Output

For each <name>.pptx found under your input path, the task writes:

  • slide images to src/docs/images/ppt/<name>/slide_NNN.png (one PNG per slide),

  • speaker notes to src/docs/ppt/<name>/slide_NNN_notes.adoc (only for slides that have notes),

  • a ready-to-include AsciiDoc file at src/docs/ppt/<name>/<name>.adoc.

The generated <name>.adoc contains one section per slide, each with the slide title as a === heading, the slide image, and an include of the slide’s notes:

=== <slide title>

image::ppt/<name>/slide_001.png[<slide title>]

include::slide_001_notes.adoc[]

Include the generated <name>.adoc from your own document to embed the slides and notes.

7.2. Further Reading

7.3. Source

View the source of this task: scripts/exportPPT.groovy on GitHub


8. exportExcel

8.1. About This Task

Exports Excel spreadsheets (.xlsx) to CSV and AsciiDoc tables using Apache POI. Each worksheet is exported as both .csv and .adoc. Formulas are evaluated and exported statically.

./dtcw4 local exportExcel

Output is written to <inputPath>/excel/[filename]/[worksheet].(adoc|csv) (by default src/docs/excel/…​). The src folder is used (not build) to preserve change history in version control.

8.2. Including Exported Data

As AsciiDoc table (preserves alignment, col-span, row-span, colors):

include::excel/Sample.xlsx/Numerical.adoc[]

As CSV:

[options="header",format="csv"]
|===
include::excel/Sample.xlsx/Numerical.csv[]
|===

8.3. Further Reading

8.4. Source

View the source of this task: scripts/exportExcel.groovy on GitHub


9. downloadTemplate

9.1. About This Task

This task is primarily used to bootstrap a new project. You can choose to download an official template like arc42 or req42 (both available in multiple languages) or you can register and use your own custom template.

9.2. Setup and Configuration

downloadTemplate requires an existing docToolchainConfig.groovy in your project root (or the path set via DTC_CONFIG_FILE). If the file doesn’t exist yet, create an empty one: touch docToolchainConfig.groovy.

9.3. Headless Mode

For unattended use (e.g., with CI/CD pipelines or LLM agents), the downloadTemplate task supports headless mode where no user input is required.

9.3.1. Using the DTC_HEADLESS Environment Variable

When DTC_HEADLESS=true is set, the task will use sensible defaults:

  • Template: arc42

  • Language: EN

  • Help variant: plain (without help text)

export DTC_HEADLESS=true
./dtcw4 local downloadTemplate

9.4. Further Reading and Resources

9.5. Source

View the source of this task: scripts/downloadTemplate.groovy on GitHub


10. createTask

10.1. About This Task

createTask scaffolds a new project-local custom task. It writes a ready-to-edit Groovy script — with the // @task marker already in place — into your project’s scripts directory, so dtcw discovers and runs it without any further wiring.

./dtcw createTask exportNotion

This creates scripts/exportNotion.groovy. Run it with ./dtcw exportNotion and see it listed via ./dtcw tasks.

10.2. Setup and Configuration

  • The task name must start with a letter and contain only letters, digits, hyphens or underscores. If omitted, the name defaults to customTask.

  • The target directory defaults to scripts/; override it with the DTC_PROJECT_SCRIPTS_DIR environment variable.

  • createTask never overwrites an existing file — pick a new name or edit the existing script directly.

The generated skeleton shows how to read docToolchainConfig.groovy and reuse docToolchain’s bundled helpers via the dtc.scriptsHome system property.

10.3. Further Reading and Resources

10.4. Source

View the source of this task: scripts/createTask.groovy on GitHub


11. copyTask

11.1. About This Task

copyTask copies an installed task script into your project so you can modify it — monkey-patching. The project copy has the same name as the installed task and therefore overrides it: dtcw runs your copy instead of the shipped one.

./dtcw copyTask generateHTML

This copies the installed generateHTML.groovy to scripts/generateHTML.groovy in your project. Edit it, then run ./dtcw generateHTML as usual.

11.2. Setup and Configuration

  • Pass the name of an existing installed task. Run ./dtcw tasks to see the available names.

  • The copy is placed in scripts/ by default; override with DTC_PROJECT_SCRIPTS_DIR.

  • copyTask refuses to overwrite an existing project copy.

11.3. How the Override Behaves

  • ./dtcw generateHTML prints a note to stderr that the installed task is being overridden by your project file.

  • ./dtcw tasks flags the task as overridden by scripts/generateHTML.groovy.

  • The copy still loads its bundled helpers and resources from the installation via dtc.scriptsHome, so it keeps working unchanged.

  • Delete the copy to fall back to the shipped task.

A copied task is pinned to the version you copied. After upgrading docToolchain, re-copy it if you want upstream changes.

11.4. Further Reading and Resources

11.5. Source

View the source of this task: scripts/copyTask.groovy on GitHub


11.6. Solutions to Common Problems

If you are stuck, also check Stack Overflow or raise an issue on GitHub.

11.6.1. References

Q: How can I reference source code from my documentation?
Answer

Within your documents folder (default src/docs), use relative includes:

include::filename.adoc[]

For files outside the documents folder, use:

include::/home/runner/work/docToolchain/docToolchainfilename.adoc[]

To make this work in editor previews, add:

ifndef::projectRootDir[:projectRootDir: ../../../]

11.6.2. Images

Q: Why are images not shown in the preview of my editor?
Answer

Your editor does not know the imagesdir attribute. Add this line to each file:

ifndef::imagesdir[:imagesdir: ../images]

Q: Which image format should I use?
Answer

PNG is the preferred format — all output formats support it well.

Other formats:

SVG

Great for high-resolution diagrams but may not render correctly in DOCX output.

JPG

Good for photos, not for diagrams (compression artifacts).

GIF

Not supported by the PDF renderer.

Q: Why are my images rotated in the output?
Answer

Mobile devices store orientation in image metadata rather than rotating the image. Fix with ImageMagick: convert -auto-orient photo.jpg photo.jpg Or re-save the image in any editor.

11.6.3. Runtime

Q: I get Could not initialize class java.awt.GraphicsEnvironment in WSL
Answer

This is a known WSL issue related to PlantUML and font rendering.

Solutions (try in order):

  1. Shut down WSL: wsl --shutdown from PowerShell, then retry

  2. Reinstall your Java runtime

  3. Use PowerShell instead of WSL

  4. Use a Kroki server for diagram rendering instead of PlantUML

Make sure WSL is up-to-date: wsl --update

Q: How do I configure a proxy?
Answer

Pass proxy settings as system properties:

./dtcw4 local generateSite -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=3128
Q: Can I tune the JVM startup for faster v4 builds?
Answer

docToolchain v4 runs every task in a fresh, short-lived JVM (no Gradle daemon). To make that startup cheap, the dtcw wrapper launches the v4 JVM with these flags by default: -XX:TieredStopAtLevel=1 -XX:+UseSerialGC.

A run that lasts only seconds never recoups the cost of the C2 JIT compiler optimising hot methods it abandons moments later. Capping the JIT at level 1 (C1) removes that wasted compilation, and SerialGC skips parallel-GC thread setup. On a typical site this roughly halves the wall-clock time.

The flags are a default, not a hard-coded value. Override them with the DTC_JAVA_STARTUP_OPTS environment variable:

# Disable the defaults entirely:
DTC_JAVA_STARTUP_OPTS= ./dtcw4 local generateSite

# Replace them with your own choice:
DTC_JAVA_STARTUP_OPTS="-XX:+UseParallelGC" ./dtcw4 local generateSite
For a very large documentation set whose render runs for minutes, the C2 JIT does eventually pay off. There, disabling the defaults (DTC_JAVA_STARTUP_OPTS=) can be faster — measure both and keep the winner.

11.7. Useful Resources

11.7.1. Underlying Technologies

Markup
AsciiDoc

Our preferred markup language for technical docs.

Markdown

jBake also supports Markdown via flexmark-java.

Templates
arc42
Docs as Code
Docs as Code
Static Site Generator
jBake
  • jBake — drove generateSite in v3; v4 uses a built-in generator (MicrositeBaker)

  • Docsy — the standard theme in v3; v4 ships Bootstrap 5 GSP templates

  • Bootstrap 5 — CSS framework

11.7.2. Books

Title Author Language

Docs Like Code

Anne Gentle

English

arc42 by Example

Gernot Starke, Stefan Zörner, Michael Simons, Ralf D. Müller

English

Communicating Software Architectures with arc42

Gernot Starke, Peter Hruschka

English

11.8. Configuration

docToolchain uses a single Groovy configuration file for all settings.

11.8.1. Configuration File

By default, docToolchain looks for docToolchainConfig.groovy in your project root.

Overriding the Config File

Use the DTC_CONFIG_FILE environment variable:

export DTC_CONFIG_FILE=path/to/config.groovy
The config file must exist before running any task. If it is missing, DtcConfig.load() will fail. Run ./dtcw4 local downloadTemplate to create a default one, or create an empty docToolchainConfig.groovy manually.

11.8.2. Core Settings

outputPath = 'build'
inputPath = 'src/docs'

inputFiles = [
    [file: 'manual.adoc', formats: ['html','pdf']],
]

imageDirs = ['images/.']
outputPath

Base directory for all generated output.

inputPath

Directory containing your AsciiDoc sources.

inputFiles

List of files to process, with desired output formats (html, pdf).

imageDirs

Directories to scan for images (relative to inputPath).

11.8.3. Microsite Settings

microsite.with {
    contextPath = '/'
    title = 'My Documentation'
    host = 'https://example.com'
    landingPage = 'landingpage.gsp'
    menu = [
        about: 'About',
        manual: 'User Docs',
        tasks: 'Tasks',
    ]
}
menu

Maps menu codes (from folder names or :jbake-menu: attributes) to display titles. Use '-' to hide a menu entry.

11.8.4. Confluence Settings

confluence = [
    api: 'https://your-wiki.atlassian.net/wiki',
    spaceKey: 'MY_SPACE',
    credentials: "user:${new File('/path/to/apitoken').text}",
    input: [
        [file: 'build/html5/manual.html', ancestorId: '123456'],
    ],
]

See the publishToConfluence task for all options.

11.8.5. Dynamic Configuration

Since the config file is executable Groovy, you can use dynamic values:

// From system property: ./dtcw4 local generateHTML -DmyProp=value
example = System.properties.myProp

// From environment variable
example = System.getenv("MY_VAR")