`<pre>` / `<script>` / `<style>` contents are parsed as markdown instead of passed through triggering spurious parse errors
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 62/100
Research direction
Start in crates/pampa/src/pandoc/treesitter_utils/paragraph.rs at paragraph_starts_raw_text_element, then trace write_rawblock for the related writer behavior. Reproduce the examples with cargo run --bin pampa; done means raw-text elements pass through opaque content without spurious parse errors, and fenced raw HTML remains round-trippable without introducing warnings.
Written by the indexing model from the issue text.
Description
Paragraph that opens with <pre>, <script>, <style>, or <textarea> are lifted to a verbatim html RawBlock (paragraph_starts_raw_text_element in crates/pampa/src/pandoc/treesitter_utils/paragraph.rs). The lift runs on the paragraph tree-sitter has already tokenized as markdown so interior bytes the grammar rejects are a fatal parse error before the lift sees them. Pandoc passes both through untouched. A <pre> whose interior happens to tokenize (emphasis markers, a code span) is passed through correctly, so the failure depends on the content rather than the element.
Entity-encoded backticks followed by an attribute-shaped {python}, as in the fixture:
$ printf -- '<pre>\n```{python}\nx\n</pre>\n'
<pre>
```{python}
x
</pre>
$ printf -- '<pre>\n```{python}\nx\n</pre>\n' | cargo run --bin pampa -- 2>&1
Error: [Q-2-41] Curly braces are reserved for attribute syntax
╭─[ <stdin>:2:17 ]
│
2 │ ```{python}
│ ───┬──
│ ╰──── Curly braces are reserved for attribute syntax in Quarto markdown. To write literal braces, escape them as `\{...\}`. If you meant to attach an attribute, use `.class` / `#id` / `key="value"` syntax, e.g. `[text]{.class}`.
───╯
$ printf -- '<pre>\n```{python}\nx\n</pre>\n' | pandoc -f markdown -t native
[ RawBlock
(Format "html") "<pre>\n```{python}\nx\n</pre>"
]
A CSS-style brace line:
$ printf -- '<pre>\na { b: c; }\n</pre>\n'
<pre>
a { b: c; }
</pre>
$ printf -- '<pre>\na { b: c; }\n</pre>\n' | cargo run --bin pampa -- 2>&1
Error: Parse error
╭─[ <stdin>:2:5 ]
│
2 │ a { b: c; }
│ ┬
│ ╰── unexpected character or token here
───╯
Related ```{=html} block issue
write_rawblock emits an html RawBlock bare whenever round_trips_bare_html accepts it, and a raw-text element is accepted on its opening tag alone, so an authored ```{=html} fence around a stylesheet or script parses cleanly, is written without its fence, and fails to re-read on the first brace. A <script> with if (a) { b(); } fails the same way. Even where the bare form does parse, the round trip is not clean: the fenced input reads with no diagnostics, while the writer's output re-reads with a Q-2-9 warning per tag whose hint is to put the block back in the fence the writer just removed. The fence records the author's intent that the block is opaque, which is the same declaration Q-2-9 asks for, so the writer should keep it for raw-text elements, or at least never emit a form the reader warns about, independently of the reader fix.
A fenced <style> block, written bare and re-read:
$ printf -- '```{=html}\n<style>\na { b: c; }\n</style>\n```\n'
```{=html}
<style>
a { b: c; }
</style>
```
$ printf -- '```{=html}\n<style>\na { b: c; }\n</style>\n```\n' | cargo run --bin pampa -- 2>&1
[ RawBlock (Format "html") "<style>\na { b: c; }\n</style>" ]
$ printf -- '```{=html}\n<style>\na { b: c; }\n</style>\n```\n' | cargo run --bin pampa -- -t qmd 2>&1
<style>
a { b: c; }
</style>
$ printf -- '```{=html}\n<style>\na { b: c; }\n</style>\n```\n' | cargo run --bin pampa -- -t qmd 2>/dev/null | cargo run --bin pampa -- 2>&1
Error: Parse error
╭─[ <stdin>:2:5 ]
│
2 │ a { b: c; }
│ ┬
│ ╰── unexpected character or token here
───╯
Without braces the bare form parses, but re-reads with two Q-2-9 warnings the fenced input did not have:
$ printf -- '```{=html}\n<style>\na: b;\n</style>\n```\n'
```{=html}
<style>
a: b;
</style>
```
$ printf -- '```{=html}\n<style>\na: b;\n</style>\n```\n' | cargo run --bin pampa -- 2>&1
[ RawBlock (Format "html") "<style>\na: b;\n</style>" ]
$ printf -- '```{=html}\n<style>\na: b;\n</style>\n```\n' | cargo run --bin pampa -- -t qmd 2>&1
<style>
a: b;
</style>
$ printf -- '```{=html}\n<style>\na: b;\n</style>\n```\n' | cargo run --bin pampa -- -t qmd 2>/dev/null | cargo run --bin pampa -- 2>&1
Warning: [Q-2-9] HTML element converted to raw HTML
╭─[ <stdin>:1:1 ]
│
1 │ <style>
│ ───┬───
│ ╰───── HTML element converted to raw HTML
───╯
ℹ This tag opens a line and names a block-level element, so it is passed through as a raw HTML block
ℹ To be explicit, put it in a ```{=html} block — or write a Quarto div instead: ::: {.your-class}
Warning: [Q-2-9] HTML element converted to raw HTML
╭─[ <stdin>:3:1 ]
│
3 │ </style>
│ ────┬───
│ ╰───── HTML element converted to raw HTML
───╯
ℹ This tag opens a line and names a block-level element, so it is passed through as a raw HTML block
ℹ To be explicit, put it in a ```{=html} block — or write a Quarto div instead: ::: {.your-class}
[ RawBlock (Format "html") "<style>\na: b;\n</style>" ]
In-the-wild, reader side (a bare <pre> that fails to parse):
Writer side (fenced <style> blocks that parse, are written bare, and fail to re-read):
- https://github.com/quarto-dev/quarto-web/blob/acb4d86cc60763908d4f6f68f713c3760fd4a98b/docs/authoring/includes.qmd#L107
- https://github.com/quarto-dev/quarto-web/blob/acb4d86cc60763908d4f6f68f713c3760fd4a98b/docs/dashboards/deployment.qmd#L18
- https://github.com/quarto-dev/quarto-web/blob/acb4d86cc60763908d4f6f68f713c3760fd4a98b/docs/manuscripts/index.qmd#L64
- Dominant language
- Rust
- Stars
- 255
- Forks
- 17
- Avg merge
- 6h 20m
- Merged PRs (30d)
- 109
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from quarto-dev/q2
-
Difficulty 3/5 1-2 days Newbie friendliness 38/100
quarto-dev/q2#642 ·
-
bug
quarto-dev/q2#576 · 1 assignee ·
-
quarto-hub
Difficulty 4/5 3-5 days Newbie friendliness 25/100
quarto-dev/q2#564 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 50/100
quarto-dev/q2#436 ·
-
bug
Difficulty 4/5 3-5 days Newbie friendliness 45/100
quarto-dev/q2#433 · 1 comment ·
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100