Bug description
With llms-txt: true, the generated .llms.md files replace some tables with the literal text [TABLE]. All the content of the table is lost. The HTML page keeps the table, so only the LLM-facing variant is damaged.
The tables that are lost are the ones whose cells contain more than one block, for example a grid table or a .list-table div with two paragraphs in one cell. Tables with single-paragraph cells are written correctly as GFM pipe tables.
This is visible on the Quarto website. On https://quarto.org/docs/extensions/lua-api.llms.md, line 291 reads:
The constructors below accept the same fields as documented for each node type, with some additional flexibility:
[TABLE]
### JSON Encoding
The sentence "The constructors below" now points at nothing, so the constructor signatures for quarto.Callout(), quarto.Tabset(), and the other custom nodes are unreachable from the .llms.md page. The same page rendered as HTML, https://quarto.org/docs/extensions/lua-api.html, shows the full table.
The problem is not limited to that page. Counting [TABLE] lines in a few published files:
| Page |
[TABLE] count |
docs/reference/formats/html.llms.md |
18 |
docs/authoring/tables.llms.md |
3 |
docs/output-formats/html-themes.llms.md |
2 |
Steps to reproduce
_quarto.yml:
project:
type: website
website:
title: "Repro"
llms-txt: true
index.qmd:
---
title: "Repro"
---
+-------------------+------------------------+
| Constructor | Fields |
+===================+========================+
| `quarto.Callout()`| Required: `type` |
| | |
| | Optional: `title` |
+-------------------+------------------------+
Then:
quarto render
cat _site/index.llms.md
Actual behavior
_site/index.html contains the complete table.
Expected behavior
_site/index.llms.md keeps the content of the table, in any form a reader can use. For example a grid table:
# Repro
+-----------------------+--------------------+
| Constructor | Fields |
+=======================+====================+
| `quarto.Callout()` | Required: `type` |
| | |
| | Optional: `title` |
+-----------------------+--------------------+
Root cause
convertHtmlToLlmsMarkdown() converts the rendered HTML to markdown with pandoc -t gfm-raw_html.
|
const cmd = [pandocBinaryPath()]; |
|
cmd.push(tempHtml); |
|
cmd.push("-f", "html"); |
|
cmd.push("-t", "gfm-raw_html"); |
|
cmd.push("--lua-filter", filterPath); |
|
cmd.push("-o", outputPath); |
|
cmd.push("--wrap=none"); |
That target format removes every path Pandoc has to write a complex table. The Markdown writer selects a table syntax with an ordered set of guards. gfm enables pipe_tables but not simple_tables, multiline_tables, or grid_tables, so only the pipe-table branches and the HTML fallback can match. The pipe-table branches need hasSimpleCells. The -raw_html modifier disables Ext_raw_html, which removes the HTML fallback. Nothing matches, so the writer takes the final otherwise branch and emits the literal string [TABLE].
hasSimpleCells comes from onlySimpleTableCells, which accepts a cell only when it holds exactly one Plain or one Para with no line break, or nothing at all. A cell with two paragraphs, a list, or a code block fails this test.
The Custom Nodes table in lua-api.qmd is a .list-table whose cells hold two paragraphs, such as Required: type followed by Optional: title, content, .... That is what makes it fail.
The same input confirms the mechanism outside Quarto, with the Pandoc that Quarto ships:
# cell with two paragraphs
pandoc t.html -f html -t gfm-raw_html --wrap=none
# [TABLE]
pandoc t.html -f html -t gfm --wrap=none
# the table, written as raw HTML
gfm cannot be extended out of the problem, because the writer refuses the extension:
pandoc t.html -f html -t gfm+grid_tables-raw_html
# The extension 'grid_tables' is not supported for gfm.
A target format that keeps a non-pipe table syntax does produce the content. markdown-raw_html writes the same input as a grid table.
Your environment
- IDE: Terminal
- OS: macOS 26.6.1
Quarto check output
Quarto 99.9.9
[✓] Checking environment information...
Quarto cache location: /Users/mcanouil/Library/Caches/quarto
[✓] Checking versions of quarto binary dependencies...
Pandoc version 3.10.0: OK
Dart Sass version 1.101.0: OK
Deno version 2.7.14: OK
Typst version 0.15.1: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
Version: 99.9.9
commit: d4cb49f1e70fb34e4cdf38edbb2f938c3ce7cc21
Path: /Users/mcanouil/Projects/quarto-dev/quarto-cli/package/dist/bin
[✓] Checking tools....................OK
TinyTeX: v2026.07
Chrome Headless Shell: (not installed)
VeraPDF: (not installed)
[✓] Checking LaTeX....................OK
Using: TinyTex
Path: /Users/mcanouil/Library/TinyTeX/bin/universal-darwin
Version: 2026
[✓] Checking Chrome Headless....................OK
Using: Chrome from QUARTO_CHROMIUM
Path: /Applications/Brave Browser.app/Contents/MacOS/Brave Browser
[✓] Checking basic markdown render....OK
(|) Checking R installation...........ℹ R version 4.6.1 (2026-06-24)
! Config '~/.Rprofile' was loaded!
[✓] Checking R installation...........OK
Version: 4.6.1
Path: /Library/Frameworks/R.framework/Versions/4.6/Resources
LibPaths:
- /Users/mcanouil/Projects/quarto-dev/quarto-playground/renv/library/macos/R-4.6/aarch64-apple-darwin23
- /Users/mcanouil/Library/Caches/org.R-project.R/R/renv/sandbox/macos/R-4.6/aarch64-apple-darwin23/46003b10
knitr: 1.51
rmarkdown: 2.31
[✓] Checking Knitr engine render......OK
[✓] Checking Python 3 installation....OK
Version: 3.9.6
Path: /Library/Developer/CommandLineTools/usr/bin/python3
Jupyter: (None)
Jupyter is not available in this Python installation.
Install with python3 -m pip install jupyter
There is an unactivated Python environment in .venv. Did you forget to activate it?
[✓] Checking Julia installation...
Bug description
With
llms-txt: true, the generated.llms.mdfiles replace some tables with the literal text[TABLE]. All the content of the table is lost. The HTML page keeps the table, so only the LLM-facing variant is damaged.The tables that are lost are the ones whose cells contain more than one block, for example a grid table or a
.list-tablediv with two paragraphs in one cell. Tables with single-paragraph cells are written correctly as GFM pipe tables.This is visible on the Quarto website. On https://quarto.org/docs/extensions/lua-api.llms.md, line 291 reads:
The sentence "The constructors below" now points at nothing, so the constructor signatures for
quarto.Callout(),quarto.Tabset(), and the other custom nodes are unreachable from the.llms.mdpage. The same page rendered as HTML, https://quarto.org/docs/extensions/lua-api.html, shows the full table.The problem is not limited to that page. Counting
[TABLE]lines in a few published files:[TABLE]countdocs/reference/formats/html.llms.mddocs/authoring/tables.llms.mddocs/output-formats/html-themes.llms.mdSteps to reproduce
_quarto.yml:index.qmd:Then:
Actual behavior
_site/index.htmlcontains the complete table.Expected behavior
_site/index.llms.mdkeeps the content of the table, in any form a reader can use. For example a grid table:Root cause
convertHtmlToLlmsMarkdown()converts the rendered HTML to markdown withpandoc -t gfm-raw_html.quarto-cli/src/project/types/website/website-llms.ts
Lines 276 to 282 in 55389ba
That target format removes every path Pandoc has to write a complex table. The Markdown writer selects a table syntax with an ordered set of guards.
gfmenablespipe_tablesbut notsimple_tables,multiline_tables, orgrid_tables, so only the pipe-table branches and the HTML fallback can match. The pipe-table branches needhasSimpleCells. The-raw_htmlmodifier disablesExt_raw_html, which removes the HTML fallback. Nothing matches, so the writer takes the finalotherwisebranch and emits the literal string[TABLE].hasSimpleCellscomes fromonlySimpleTableCells, which accepts a cell only when it holds exactly onePlainor oneParawith no line break, or nothing at all. A cell with two paragraphs, a list, or a code block fails this test.The
Custom Nodestable inlua-api.qmdis a.list-tablewhose cells hold two paragraphs, such asRequired: typefollowed byOptional: title, content, .... That is what makes it fail.The same input confirms the mechanism outside Quarto, with the Pandoc that Quarto ships:
gfmcannot be extended out of the problem, because the writer refuses the extension:pandoc t.html -f html -t gfm+grid_tables-raw_html # The extension 'grid_tables' is not supported for gfm.A target format that keeps a non-pipe table syntax does produce the content.
markdown-raw_htmlwrites the same input as a grid table.Your environment
Quarto check output
Quarto 99.9.9 [✓] Checking environment information... Quarto cache location: /Users/mcanouil/Library/Caches/quarto [✓] Checking versions of quarto binary dependencies... Pandoc version 3.10.0: OK Dart Sass version 1.101.0: OK Deno version 2.7.14: OK Typst version 0.15.1: OK [✓] Checking versions of quarto dependencies......OK [✓] Checking Quarto installation......OK Version: 99.9.9 commit: d4cb49f1e70fb34e4cdf38edbb2f938c3ce7cc21 Path: /Users/mcanouil/Projects/quarto-dev/quarto-cli/package/dist/bin [✓] Checking tools....................OK TinyTeX: v2026.07 Chrome Headless Shell: (not installed) VeraPDF: (not installed) [✓] Checking LaTeX....................OK Using: TinyTex Path: /Users/mcanouil/Library/TinyTeX/bin/universal-darwin Version: 2026 [✓] Checking Chrome Headless....................OK Using: Chrome from QUARTO_CHROMIUM Path: /Applications/Brave Browser.app/Contents/MacOS/Brave Browser [✓] Checking basic markdown render....OK (|) Checking R installation...........ℹ R version 4.6.1 (2026-06-24) ! Config '~/.Rprofile' was loaded! [✓] Checking R installation...........OK Version: 4.6.1 Path: /Library/Frameworks/R.framework/Versions/4.6/Resources LibPaths: - /Users/mcanouil/Projects/quarto-dev/quarto-playground/renv/library/macos/R-4.6/aarch64-apple-darwin23 - /Users/mcanouil/Library/Caches/org.R-project.R/R/renv/sandbox/macos/R-4.6/aarch64-apple-darwin23/46003b10 knitr: 1.51 rmarkdown: 2.31 [✓] Checking Knitr engine render......OK [✓] Checking Python 3 installation....OK Version: 3.9.6 Path: /Library/Developer/CommandLineTools/usr/bin/python3 Jupyter: (None) Jupyter is not available in this Python installation. Install with python3 -m pip install jupyter There is an unactivated Python environment in .venv. Did you forget to activate it? [✓] Checking Julia installation...