Skip to content

[FEATURE] Write the table of contents of a manual as toc.json - #1399

Open
linawolf wants to merge 1 commit into
mainfrom
task/guides-llms-toc-json
Open

linawolf wants to merge 1 commit into
mainfrom
task/guides-llms-toc-json

Conversation

@linawolf

@linawolf linawolf commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

A rendered manual says a great deal about each of its pages and nothing
about itself as a whole. A tool that wants to read one -- a search index,
an agent, a script collecting release notes -- has to crawl it to learn
what pages there are and how they hang together. "objects.inv.json" comes
closest, but it is an index rather than a table of contents: flat, without
order or nesting, repeating the project title and version in every entry
and knowing only ".html" addresses. For the 985 pages of TYPO3 Explained
14.3 that is 4.2 MB, against the 568 KB this file needs.

Add an "llm_toc" output format in a new package,
guides-machine-readable, which collects the output that describes a
manual to the tools and language models that read it rather than to a
person. What a reader gets from the rendered pages and the navigation
around them, a program has to be told; the table of contents is the
first of that, and more is expected to follow. Enabling the extension is
all there is to it.

Which files a page is named as follows from the output formats the project
configured. The library already treats a format as the extension it writes,
so a project rendering HTML and Markdown names both, and a format that
writes a single file for the whole project names no page at all. That
answer is a public service of its own, so anything else describing pages
can reuse it rather than keep a second list of formats.

Two events let a theme add what only it knows -- ModifyTocProjectInfo
for the project section, ModifyTocPageEntry for every page. They pass
the section and each page as objects, TocProject and PageDescriptor, so
a downstream theme can correct values or add its own keys, like its
permalinks and version rule, without forking the file.

Ported from TYPO3-Documentation/render-guides, where it has shipped since
0.42 and feeds docs.typo3.org.

Signed-off-by: linawolf
Assisted-By: Claude Opus 5 (1M context) noreply@anthropic.com
Assisted-By: Claude Opus 5.5 (1M context) noreply@anthropic.com

What it looks like

This is the whole of toc.json for the integration fixture added here --
three pages in two levels, plus one no toctree reaches:

{
    "project": {
        "title": "Table of contents",
        "version": "2.0"
    },
    "pages": [
        {
            "path": "index",
            "html": "index.html",
            "title": "Table of contents",
            "anchor": "toc-start",
            "pages": [
                {
                    "path": "Chapter/Index",
                    "html": "Chapter/Index.html",
                    "title": "Chapter",
                    "anchor": "toc-chapter",
                    "pages": [
                        {
                            "path": "Chapter/Page",
                            "html": "Chapter/Page.html",
                            "title": "A page with no label",
                            "anchor": "a-page-with-no-label"
                        }
                    ]
                }
            ]
        },
        {
            "orphan": true,
            "path": "Orphan",
            "html": "Orphan.html",
            "title": "Orphan",
            "anchor": "toc-orphan"
        }
    ]
}

A live example

TYPO3 has published this file since render-guides 0.42, so there is a real
one to look at rather than a fixture:

https://docs.typo3.org/m/typo3/reference-coreapi/14.3/en-us/toc.json

985 pages, 3 of them orphans. It carries two keys this PR leaves to the
theme -- project.permalink and the md file beside each html one --
both added through ModifyTocProjectInfo and the output formats, with no
change to the generic file.

@linawolf
linawolf force-pushed the task/guides-llms-toc-json branch 2 times, most recently from 3c220eb to 06132d1 Compare September 20, 2026 11:28
@linawolf
linawolf force-pushed the task/guides-llms-toc-json branch from 06132d1 to df58eba Compare October 4, 2026 10:41

@jaapio jaapio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming of guides-llms seems to be a bit off. I don't like the name. But I do have a hard time to suggest a better name.

The purpose of this extension is to improve the LLM accessibility of the docs generated by guides right? Maybe we should include that into the name. Because this package is not doing anything with an llm.

Comment thread packages/guides-llms/src/Llms/Renderer/TocRenderer.php Outdated
Comment thread packages/guides-llms/src/Llms/Event/ModifyTocPage.php Outdated
Comment thread packages/guides-llms/src/Llms/Renderer/TocRenderer.php Outdated
Comment thread packages/guides-llms/src/Llms/Renderer/TocRenderer.php Outdated
Comment thread docs/components/table-of-contents.rst Outdated
@linawolf
linawolf force-pushed the task/guides-llms-toc-json branch 2 times, most recently from 4788c69 to b572528 Compare October 5, 2026 14:40
A rendered manual says a great deal about each of its pages and nothing
about itself as a whole. A tool that wants to read one -- a search index,
an agent, a script collecting release notes -- has to crawl it to learn
what pages there are and how they hang together. "objects.inv.json" comes
closest, but it is an index rather than a table of contents: flat, without
order or nesting, repeating the project title and version in every entry
and knowing only ".html" addresses. For the 985 pages of TYPO3 Explained
14.3 that is 4.2 MB, against the 568 KB this file needs.

Add an "llm_toc" output format in a new package,
guides-machine-readable, which collects the output that describes a
manual to the tools and language models that read it rather than to a
person. What a reader gets from the rendered pages and the navigation
around them, a program has to be told; the table of contents is the
first of that, and more is expected to follow. Enabling the extension is
all there is to it.

Which files a page is named as follows from the output formats the project
configured. The library already treats a format as the extension it writes,
so a project rendering HTML and Markdown names both, and a format that
writes a single file for the whole project names no page at all. That
answer is a public service of its own, so anything else describing pages
can reuse it rather than keep a second list of formats.

Two events let a theme add what only it knows -- ModifyTocProjectInfo
for the project section, ModifyTocPageEntry for every page. They pass
the section and each page as objects, TocProject and PageDescriptor, so
a downstream theme can correct values or add its own keys, like its
permalinks and version rule, without forking the file.

Ported from TYPO3-Documentation/render-guides, where it has shipped since
0.42 and feeds docs.typo3.org.

Signed-off-by: linawolf
Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Assisted-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@linawolf
linawolf force-pushed the task/guides-llms-toc-json branch from b572528 to bf62475 Compare October 5, 2026 14:49
@linawolf
linawolf marked this pull request as ready for review October 10, 2026 09:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants