DOCOPS-153 Markdown versions of published pages for LLMs (Antora extension) - #96
Open
recrwplay wants to merge 7 commits into
Open
DOCOPS-153 Markdown versions of published pages for LLMs (Antora extension)#96recrwplay wants to merge 7 commits into
recrwplay wants to merge 7 commits into
Conversation
New site-generator extension that, at pagesComposed, converts each published page's article content to a sibling .md (mirrors the HTML output path) for LLM consumption. All AsciiDoc is already resolved (includes, attributes, xrefs, macros) since it converts the generated HTML. - turndown + turndown-plugin-gfm; node-html-parser for scoping to article.doc - code fences (with language), admonitions -> blockquotes, heading-anchor strip, absolute links, minimal title/url frontmatter - tables: header -> GFM; clean headerless 2-col -> key/value blocks; complex/irregular (colspan, embedded sub-grids) -> kept as HTML (LLM-readable) - wired into preview.yml; 10 unit tests; verified on docs-tools + docs-cypher Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- escape backslashes as well as | / " when building GFM cells and YAML frontmatter - strip trailing slashes in joinUrl without a regex (no ReDoS on untrusted input) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
roles-labels nests <div class="labels"> inside the labeled element; convert each in place to inline-code badges so they attach to their block and don't concatenate (the reported "AuraDB Business CriticalEnterprise Edition..." run-together). Parentheses on headings (`## Heading (`label`)`); bare badges on other labeled blocks (paragraphs, examples, admonitions, table cells). +2 tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
icon:name[] renders as an empty <i class="fa fa-name"> element with no text, which turndown drops as a blank node -- silently emptying the check marks in capability/feature matrices. Resolve the glyph to text in the node-html-parser preprocessing step (fa-check -> checkmark, fa-times -> cross, else title or icon name) so it survives both the top-level and nested table-cell conversion passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collaborator
|
This PR includes documentation updates |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Markdown versions of published pages for LLMs
Adds a new Antora site-generator extension,
@neo4j-antora/markdown-pages, that emits aMarkdown version of every published page so LLMs (and fetch tools) can consume the docs as
Markdown. An LLM can retrieve a page's Markdown from its path — the
.mdsits right beside thegenerated HTML (
.../page/index.html→.../page/index.md).Why convert the generated HTML (not the AsciiDoc source)
Converting the rendered HTML means everything is already resolved — includes, attributes,
xrefs (as real links), and custom macros (
label:, roles-labels, table-footnotes). Converting fromAsciiDoc source would require re-implementing Asciidoctor, and — crucially — many attributes are
defined in the playbook /
antora.yml, not in the page (e.g.{neo4j-docs-base-uri}, limits,versions). Those never appear in the content, so a raw-
.adocconsumer can't resolve them at all;only the built HTML has them substituted. (It also would not help with the hard table cases — see
Tables — because that limitation is Markdown's, not the source format's.)
How it works
pagesComposedevent — after Asciidoctor conversion and theroles-labels/table-footnotesextensions — and selects each page'sarticle.doccontent node (so pagechrome/nav/footer is excluded).
turndown+the GFM plugin, scoping with
node-html-parser(already a repo dependency)..mdto the site catalog viasiteCatalog.addFile, mirroring the HTML output path.Conversion handling:
> **NOTE**blockquotes.roles-labels) → inline`label`badges — parenthesised after the titleon headings (
## Heading (label)), bare on other blocks.icon:check[]etc. →<i class="fa fa-check">, which has no text content) →resolved to Unicode
✓/✗(else the icon's title or name). Without this, turndown drops theempty element and capability/feature matrices silently lose their cells.
<a class="anchor">self-links are dropped.title, absoluteurl) per file.Tables (hybrid)
Markdown/GFM can't express
colspanor nested grids, so a one-size rule mangles Neo4j's tables:key/value blocks.
tables with a Name/Type/Description arguments grid) → kept as HTML. HTML tables are valid
Markdown and read reliably by LLMs (structure/colspan explicit), so this is faithful rather than
a degraded fallback.
Usage
In a docset playbook:
Testing / verification
node --test).npm run build:previewin docs-tools, and against realdocs-cypher (function references, config tables) and docs-aura pages — including the
permission/capability matrices, confirming icons resolve to
✓/✗and no cells are lost.Known limitations (follow-ups, not blockers)
lines — cosmetic; doesn't affect LLM reading.
detect a function's Arguments sub-grid and render it as a nested GFM table.
applies to the whole section in AsciiDoc, but flat Markdown can't encode that containment, so the
badge sits next to the block it was on.
llms.txtindex orllms-full.txtyet (natural next step).🤖 Generated with Claude Code