allowedTags: a self-closing custom tag at the end of a line turns every later blank line into `<!---->` (preprocessCustomTags)
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 72/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- markdown, react, typescript
- Lĩnh vực
- frontend
Hướng nghiên cứu
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.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- TypeScript
- Star
- 5.7k
- Fork
- 324
- Merge trung bình
- 2 ngày 14 giờ
- Pull request đã merge (30 ngày)
- 24
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của vercel/streamdown
-
remend: unclosed `$$` in a table cell is closed on a new line when an earlier line has mathCó thể đã có người làm @orinnz đã nhận 36 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
vercel/streamdown#652 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Pass the original error to Mermaid `errorComponent`Có thể đã có người làm @aradhyacp đã nhận hôm nay. Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 58/100
vercel/streamdown#720 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 52/100
vercel/streamdown#719 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
@streamdown/mermaid: plugin defaults override Mermaid's own theme and fontCó thể đã có người làm @DeepanB15 đã nhận hôm nay. Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 56/100
vercel/streamdown#714 · 2 bình luận · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 45/100
vercel/streamdown#699 · 4 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của vercel/streamdown
Issue tương tự
-
Recording drops clicks on links, filters and checkboxes that share a form with a search fieldCó thể đã có người làm @columbia11 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Tencent/BrowserSkill#657 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 65/100
Maintainer thường phản hồi trong vòng 2 ngày
-
Choosing a folder while continuing an Antigravity session submits a history fork the runtime rejectsĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 87/100
-
ai-handle
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
nextlevelbuilder/dewee-web-v2#138 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
NEARBuilders/citynode.app#512 ·
Maintainer thường phản hồi trong vòng 1 ngày