AsciiBinder AsciiDoc to Markdown to Astro
The OpenShift documentation is a good stress test for the DogsBay Asciidoc to Markdown converter. It is based on AsciiBinder and has:
- A topic map instead of a directory tree
- Multiple product distros sharing one source
- Several hundred symlinks so
include::resolves at any depth - Attributes threaded through nearly every page.
- 20,000+
.adocfiles, of which ~12,000 belong to theopenshift-enterprisedistro.
dogsbay/openshift-docs-markdown runs the Asciidoc to Markdown conversion on a schedule and commits the result. You can fork it and have your own copy building in about seven minutes of wall-clock time, most of which is waiting on npm.
- Converting AsciiDoc to Markdown
- Why existing AsciiDoc converters lose your structure
- Why Jinja is the right target
- Mapping AsciiDoc variables to Jinja
- Mapping AsciiDoc conditionals to Jinja
- Mapping AsciiDoc ifeval to Jinja
- Mapping AsciiDoc includes and level offsets to Jinja
- AsciiBinder AsciiDoc to Markdown to Astro — you are here
- AsciiBinder AsciiDoc to Markdown to MkDocs
- AsciiBinder AsciiDoc to Markdown to Docusaurus
What is in the repo
There is one branch per upstream version. The main holds only the two workflows while the content lives on a branch named after the upstream ref it mirrors.
main the two workflows, nothing else
enterprise-4.22
markdown/ 11,885 .md — the converted source
site/ the generated Astro project
site/dist/ 1,799 built HTML pages
dogsbay.config.yml
MIGRATION.md what survived conversion, and what did notThe markdown/ folder is ordinary Markdown, and its history is a changelog of what upstream changed and what the converter did with it.
Fork the repo and use GitHub Actions to run the conversion online
- Fork dogsbay/openshift-docs-markdown.
- Open the Actions tab and enable workflows. GitHub disables them on forks by default.
- Manually run the action named 1. Convert AsciiDoc → Markdown. The inputs default to
enterprise-4.22andopenshift-enterprise. Anyenterprise-*upstream branch works. - When it finishes, manually run the action named 2. Build HTML site against the same branch.
It takes roughly 115 seconds for the conversion and 325 seconds for the build and deploy, with most of the time spent downloading the packages from npm.
All of it runs on GitHub's runners, so you need nothing installed locally to get this far — a browser and a fork are enough.
Where your site appears
Workflow 2 publishes to GitHub Pages and turns Pages on for you, so there is no Settings trip. Your copy lands at:
https://<your-username>.github.io/openshift-docs-markdown/Pages to check
| Page | Why it is interesting |
|---|---|
| https://dogsbay.github.io/openshift-docs-markdown/installing/installing_bare_metal/upi/installing-bare-metal/ | 75 include:: directives resolved into one 1.1 MB page |
| https://dogsbay.github.io/openshift-docs-markdown/rest_api/monitoring_apis/prometheus-monitoring-coreos-com-v1/ | the largest page in the corpus — 604 KB of Markdown |
| https://dogsbay.github.io/openshift-docs-markdown/welcome/oke_about/ | a comparison table built from AsciiDoc span cells (2+h|) |
| https://dogsbay.github.io/openshift-docs-markdown/tutorials/dev-app-web-console/ | UI icons rendered inside sentences |
Those links point at this repo's build, so you can look before forking anything.
workflow_dispatch reads the workflow file from the branch you select, so keeping both on main means one file to maintain rather than one per version.
Running it on a schedule
Workflow 1 already carries a default weekly schedule:
on:
workflow_dispatch:
inputs:
upstream_ref:
default: "enterprise-4.22"
distro:
default: "openshift-enterprise"
schedule:
- cron: "0 5 * * 1" # Mondays 05:00 UTCA fork inherits it, so a weekly refresh needs nothing beyond enabling Actions. The scheduler disables cron on repositories with no activity for 60 days, and it runs schedules only on the default branch, which is why main holds the workflows.
Running the OpenShift conversion to Markdown locally
Everything above runs on GitHub's machines. Running the conversion locally needs two things:
- git, for the clone.
- Node.js 22 and the
npxthat ships with it.
There is nothing extra to install — npx fetches the CLI on first use, and site dev installs the generated project's own dependencies when it first runs.
git clone --depth 1 --branch enterprise-4.22 \
https://github.com/openshift/openshift-docs.git
npx dogsbay migrate-asciidoc ./openshift-docs -o ./out \
--distro openshift-enterprise \
--site-name "OpenShift Container Platform" \
-a product_title="OpenShift Container Platform" \
-a product_version=4.22 \
-a openshift_enterprise=trueThat writes out/markdown/, a dogsbay.config.yml and a MIGRATION.md. To see it as a site:
cd out && npx dogsbay site devsite dev rebuilds the content and installs the scaffold's dependencies on first run, so there is no separate install step. On a laptop the build is about 50 seconds and peaks near 1.5 GB of memory.
The attribute settings
The -a flags matter to the conversion. OpenShift's AsciiDoc is dense with ifdef::openshift-enterprise[] and {product-title} — more than 50,000 attribute references and 6,000 conditionals survive into the Markdown.
The conversion writes them into dogsbay.config.yml and leaves the Markdown templated: {{ product_title }} stays a variable, {% if openshift_enterprise %} stays a conditional. They only resolve when you build the site for a specific version and distro.
--distro is specified at conversion time, because the topic map gives the same file different labels per distro — the same page is "Fedora CoreOS" for OKD and "Red Hat Enterprise Linux CoreOS" for Enterprise — so a distro-neutral nav would carry duplicates rather than a superset.
What to look at once it runs
site dev serves on http://localhost:4321 by default. There is no base path on a local build, so the slugs below map straight onto it — http://localhost:4321/welcome/oke_about/ and so on. If you would rather not run anything, the same pages are live at dogsbay.github.io/openshift-docs-markdown.
Start with MIGRATION.md in the output directory: it reports what survived conversion and what did not. Then these five, each chosen because it breaks a different part of a converter.
/installing/installing_bare_metal/upi/installing-bare-metal/ — 75 include:: directives resolved into one page, 1.1 MB served. Modular AsciiDoc at its most extreme: almost none of this page's text lives in its own file.
/support/gathering-cluster-data/ — 32 includes and 18 conditionals in 5 KB of source. This is the attribute machinery doing its job; view the Markdown behind it and you will see {% if %} blocks that only resolve at build time.
/rest_api/monitoring_apis/prometheus-monitoring-coreos-com-v1/ — the largest page in the corpus, 604 KB of Markdown and 3.4 MB served. Generated Kubernetes API reference: deeply nested definition lists, thousands of rows, and a good check that nothing quietly truncates.
/welcome/oke_about/ — a product comparison table built from AsciiDoc span cells (2+h|). Column spans are where table conversion usually falls apart: the label cell spans two columns and the row has to stay one row.
/tutorials/dev-app-web-console/ — UI icons inside sentences, from image:fa-plus-circle.png[title="Quick create menu"]. An inline image that renders as a block splits the sentence around it, which is obvious to a reader and invisible to a test that only counts pages.