`<pre>` / `<script>` / `<style>` contents are parsed as markdown instead of passed through triggering spurious parse errors

Open
#674 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
62/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
rust
Domain
tooling

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&#96;&#96;&#96;{python}\nx\n</pre>\n'
<pre>
&#96;&#96;&#96;{python}
x
</pre>

$ printf -- '<pre>\n&#96;&#96;&#96;{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 │ &#96;&#96;&#96;{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&#96;&#96;&#96;{python}\nx\n</pre>\n' | pandoc -f markdown -t native
[ RawBlock
    (Format "html") "<pre>\n&#96;&#96;&#96;{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):

Dominant language
Rust
Stars
255
Forks
17
Avg merge
6h 20m
Merged PRs (30d)
109

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from quarto-dev/q2

All issues in quarto-dev/q2

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.