allowedTags: a self-closing custom tag at the end of a line turns every later blank line into `<!---->` (preprocessCustomTags)
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 72/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- markdown, react, typescript
- Ambito
- frontend
Direzione di ricerca
Start in lib/preprocess-custom-tags.ts with normalizeUnclosedOpenTags, then compare its handling of self-closing tags with countNonSelfClosingOpenTags in parse-blocks.tsx. Reproduce both examples from the issue and check that self-closing tags no longer split later lists or corrupt blank lines, while an inline tag with a soft line break stays within one paragraph.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Version
streamdown 2.7.1. The same code is on main (ec1489a). 2.5.0 is not affected.
Repro
<Streamdown allowedTags={{ "cite-ref": ["id"] }} mode="static">
{'Intro <cite-ref id="a" />\n\n- one\n\n- two\n\nLast'}
</Streamdown>
2.7.1 output (classes stripped):
<p>Intro <cite-ref id="a"></cite-ref></p>
<ul><li>one</li></ul>
<ul><li>two</li></ul>
<p>Last</p>
Expected (2.5.0, or 2.7.1 without allowedTags): one <ul> with both items.
Effects
After the first self-closing allowed tag that ends a line:
- Loose lists split into one
<ul>/<ol>per item. - Lists flip between tight and loose.
- On 2.7.1, a later fenced code block with a blank line shows a literal
<!---->line. #684 fixes this one on main.
In our app, 19 of 75 real LLM answers end a line with <citation ids="…" />. 11 of them render differently.
Cause
In lib/preprocess-custom-tags.ts, normalizeUnclosedOpenTags matches open tags with <(${tagName})(?=[\s>/])([^>]*)>. That pattern also matches <tag … />. A self-closing tag has no </tag>, so it is treated as an unclosed (streaming) container. If the next character is \n, the function inserts \n\n and replaces every later blank line in the document with <!---->, then stops.
parse-blocks.tsx already skips self-closing tags in countNonSelfClosingOpenTags.
Related, an inline tag whose body has a soft line break
<Streamdown allowedTags={{ verse: [] }} mode="static">
{"He said: <verse>line one\nline two</verse> and left."}
</Streamdown>
2.7.1 output:
<p>He said: <verse></verse></p>
<p>line one
line two</p>
<p>and left.</p>
The tag is emptied and its body becomes a separate paragraph. In 2.5.0 the body stayed inside the tag within one paragraph. The cause is that normalizeClosedTag now pads any body that contains \n (since #484), even when the tag is inline.
Suggested fix
- In
normalizeUnclosedOpenTags, skip matches whose open tag ends with/>, in the same waycountNonSelfClosingOpenTagsdoes. - Only apply the blank-line sandwich when the open tag starts a line, or when the body contains a blank line. Leave inline tags whose body only has soft line breaks alone.
- Consider an opt-out so
allowedTagscan only extend the sanitize schema, as it did up to 2.5. For examplecustomTagMarkdown={false}, or a per-tag setting.
Our workaround: pass the tags through rehypePlugins (built from defaultRehypePlugins with an extended sanitize schema) instead of allowedTags.
We can open a PR with tests for the two cases above.
- Lingua principale
- TypeScript
- Stelle
- 5.7k
- Fork
- 319
- Merge medio
- 2g 14h
- PR unite (30g)
- 24
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di vercel/streamdown
-
remend: unclosed `$$` in a table cell is closed on a new line when an earlier line has mathForse già presa @orinnz l’ha presa 34 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
vercel/streamdown#652 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 58/100
vercel/streamdown#720 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 52/100
vercel/streamdown#719 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 56/100
vercel/streamdown#714 · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
vercel/streamdown#699 · 4 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di vercel/streamdown
Issue simili
-
Navbar avatar and name stay stale after saving profile changesForse già presa @alexechoi l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
marmelab/atomic-crm#416 ·
I maintainer di solito rispondono entro 1 giorno
-
feature-request
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
bluesky-social/social-app#12343 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
lucide-icons/lucide#5165 ·
I maintainer di solito rispondono entro 1 giorno
-
[Feature] Preferences - Keep the theme selection popover open after selection for quick previewAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
marktext/marktext#6033 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
area:desktop bug has repro platform:macos
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
anthropics/claude-code#107903 ·