AsciiBinder AsciiDoc to Markdown to MkDocs
Part 8 converted the OpenShift documentation to Markdown and built it as an Astro site. The markdown is DogsBay MD, ordinary CommonMark plus a small directive vocabulary for the things AsciiDoc has and Markdown does not. The markdown is not tied to Astro and the DogsBay CLI can serialize it to other site generators' dialects.
This post converts the same ~1,800 pages to MkDocs with the Material theme, publishes them to GitHub Pages. The result is at dogsbay.github.io/openshift-docs-mkdocs and the workflow that builds it is dogsbay/openshift-docs-mkdocs.
- 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
- AsciiBinder AsciiDoc to Markdown to MkDocs — you are here
- AsciiBinder AsciiDoc to Markdown to Docusaurus
One flag
The export is a flag on the same build that produces the Astro site:
npx dogsbay site build ./out --to mkdocs --out ./mkdocs \
--site-url https://<you>.github.io/openshift-docs-mkdocs--to mkdocs names the target: the build assembles the pages exactly as it would for Astro and writes them out as an MkDocs project instead, with a mkdocs.yml for nav, theme features and Markdown extensions filled in, and a docs/ tree with one .md file per page plus the images.
mkdocs/
mkdocs.yml site_name, site_url, nav, theme.features, markdown_extensions
docs/
welcome.md
welcome/…
installing/…
images/ 675 filesThen the workflow runs pip install mkdocs-material && mkdocs build to create the site.
The site build is where attributes resolve, conditionals select the openshift-enterprise variant, and the includes pull in their modules in. Running the export means the MkDocs site is built from the same 1,799 pages as the Astro one, and the two can be compared page for page.
What the exporter has to translate
The common Markdown content straightforward. The following table shows how the directives are mapped to a specific MkDocs target:
| DogsBay MD | MkDocs Material |
|---|---|
:::note, :::warning, … (12 kinds) | !!! note admonitions, with AsciiDoc's IMPORTANT and CAUTION mapped to the Material names |
:::tabs | === "Tab" content tabs (pymdownx.tabbed) |
:::steps | ordered lists, since Material has no steps block |
| definition lists | def_list, one Term / : definition pair per entry |
| tables with nested block cells | <table markdown>, so Python-Markdown parses what is inside |
| fenced code with a title | pymdownx.superfences with the title attribute |
| footnotes, math | footnotes, pymdownx.arithmatex |
The extensions block is not a fixed list. The exporter walks the trees and switches on only what the corpus uses, so a small site gets a small mkdocs.yml.
Fidelity, measured against AsciiBinder
The comparison target is the page AsciiBinder itself renders from the same AsciiDoc, on a deliberately hard page: bare-metal UPI installation with network customizations, 75 includes, 166 code blocks.
| AsciiBinder HTML | MkDocs export | |
|---|---|---|
| Code blocks | 166 | 166 |
| Admonitions | 117 | 117 |
| Definition lists | 43 | 45 |
| Token occurrences retained | 98.7% |
The two extra definition lists and the missing 1.3% are all traceable to the source side: a == Next steps heading that AsciiBinder demotes into a related-links block, ids with a _ prefix from the module id scheme, and table numbering that AsciiBinder adds at render time.
Lessons learned
By default, every page in the MkDocs version carried the whole nav. Material renders the full nav: tree into each page unless navigation.prune is on. With 2,100 nav entries that was about 1 MB per page. The welcome page was 981 KB, of which the actual content was only a few KB. and 1.9 GB for the site, which is over GitHub Pages' 1 GB limit. The exporter now emits navigation.prune, Material's own recommendation for large sites:
| without prune | with prune | |
|---|---|---|
| welcome page | 981 KB | 259 KB |
| whole site | 1.9 GB | 650 MB |
There was no home page. MkDocs serves docs/index.md at the site root and emits nothing there otherwise. OpenShift's nav starts at welcome.md, so the root of the published site was a 404 while every deep link worked. The exporter now writes a docs/index.md that redirects to the first page in the nav.
Try AsciiDoc to Material for MkDocs yourself
The repo has the same shape as the Markdown one with the main branch holding one workflow and nothing else, and the exported project lands on a branch named after the source branch.
- Fork dogsbay/openshift-docs-mkdocs.
- In Settings → Pages, set the source to GitHub Actions. The workflow cannot do this for you; the default token is not allowed to.
- Open the Actions tab, enable workflows, and run Build MkDocs site. The input defaults to
enterprise-4.22.
The workflow does not clone OpenShift or run the AsciiDoc conversion. It sparse-checks-out markdown/ from dogsbay/openshift-docs-markdown's content branch, runs the export, builds with mkdocs-material, commits the project to the content branch, and deploys the built HTML from the artefact. The whole run is about five minutes. It refuses to deploy a site over 950 MB, which is a GitHub Pages limit, and it runs weekly, two hours after the Markdown repo's own sync.
Your copy appears at https://<your-username>.github.io/openshift-docs-mkdocs/.
Pages to check
| Page | Why |
|---|---|
| / | the redirect that was not there |
| /installing/installing_bare_metal/upi/installing-bare-metal-network-customizations/ | the page measured above: 166 code blocks, 117 admonitions |
| /welcome/glossary/ | definition lists through def_list |
| /welcome/oke_about/ | the span-cell comparison table, now as <table markdown> |
| /architecture/architecture/ | images under Material's layout |
The same pages exist on the Astro site and, in the next part, on the Docusaurus one. That is the point: one markdown source, three generators, the same content on each.