



























@@ -25,6 +25,17 @@ const INTERNAL_RUNTIME_SCAFFOLDING_TAG_RE = new RegExp(
2525`<\\s*\\/?\\s*(?:${INTERNAL_RUNTIME_SCAFFOLDING_TAG_PATTERN})\\b[^>]*>`,
2626"gi",
2727);
28+const HTML_TAG_RE = /<\/?[a-z][a-z0-9_-]*\b[^>]*>/gi;
29+30+function stripRemainingHtmlTags(text: string): string {
31+let previous: string;
32+let current = text;
33+do {
34+previous = current;
35+current = current.replace(HTML_TAG_RE, "");
36+} while (current !== previous);
37+return current;
38+}
28392940export function stripInternalRuntimeScaffolding(text: string): string {
3041return text
@@ -42,29 +53,25 @@ export function stripInternalRuntimeScaffolding(text: string): string {
4253 * prose (e.g. `a < b`).
4354 */
4455export function sanitizeForPlainText(text: string): string {
45-return (
46-stripInternalRuntimeScaffolding(text)
47-// Preserve angle-bracket autolinks as plain URLs before tag stripping.
48-.replace(/<((?:https?:\/\/|mailto:)[^<>\s]+)>/gi, "$1")
49-// Line breaks
50-.replace(/<br\s*\/?>/gi, "\n")
51-// Block elements → newlines
52-.replace(/<\/?(p|div)>/gi, "\n")
53-// Bold → WhatsApp/Signal bold
54-.replace(/<(b|strong)>(.*?)<\/\1>/gi, "*$2*")
55-// Italic → WhatsApp/Signal italic
56-.replace(/<(i|em)>(.*?)<\/\1>/gi, "_$2_")
57-// Strikethrough → WhatsApp/Signal strikethrough
58-.replace(/<(s|strike|del)>(.*?)<\/\1>/gi, "~$2~")
59-// Inline code
60-.replace(/<code>(.*?)<\/code>/gi, "`$1`")
61-// Headings → bold text with newline
62-.replace(/<h[1-6][^>]*>(.*?)<\/h[1-6]>/gi, "\n*$1*\n")
63-// List items → bullet points
64-.replace(/<li[^>]*>(.*?)<\/li>/gi, "• $1\n")
65-// Strip remaining HTML tags (require tag-like structure: <word...>)
66-.replace(/<\/?[a-z][a-z0-9_-]*\b[^>]*>/gi, "")
67-// Collapse 3+ consecutive newlines into 2
68-.replace(/\n{3,}/g, "\n\n")
69-);
56+const converted = stripInternalRuntimeScaffolding(text)
57+// Preserve angle-bracket autolinks as plain URLs before tag stripping.
58+.replace(/<((?:https?:\/\/|mailto:)[^<>\s]+)>/gi, "$1")
59+// Line breaks
60+.replace(/<br\s*\/?>/gi, "\n")
61+// Block elements → newlines
62+.replace(/<\/?(p|div)>/gi, "\n")
63+// Bold → WhatsApp/Signal bold
64+.replace(/<(b|strong)>(.*?)<\/\1>/gi, "*$2*")
65+// Italic → WhatsApp/Signal italic
66+.replace(/<(i|em)>(.*?)<\/\1>/gi, "_$2_")
67+// Strikethrough → WhatsApp/Signal strikethrough
68+.replace(/<(s|strike|del)>(.*?)<\/\1>/gi, "~$2~")
69+// Inline code
70+.replace(/<code>(.*?)<\/code>/gi, "`$1`")
71+// Headings → bold text with newline
72+.replace(/<h[1-6][^>]*>(.*?)<\/h[1-6]>/gi, "\n*$1*\n")
73+// List items → bullet points
74+.replace(/<li[^>]*>(.*?)<\/li>/gi, "• $1\n");
75+76+return stripRemainingHtmlTags(converted).replace(/\n{3,}/g, "\n\n");
7077}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。