Preserve KaTeX display math rendering

This commit is contained in:
Codex
2026-07-08 09:36:44 +00:00
parent 1f4d1dde1b
commit 65759088bd
2 changed files with 39 additions and 2 deletions
+24 -2
View File
@@ -268,6 +268,7 @@ function normalizeCopiedHtml(html: string): string {
$("span").each((_, span) => { $("span").each((_, span) => {
const element = $(span); const element = $(span);
if (element.closest("a[data-citation]").length > 0) return; if (element.closest("a[data-citation]").length > 0) return;
if (element.closest(".katex, .katex-display").length > 0) return;
if (Object.keys(span.attribs || {}).length === 0) element.replaceWith(element.contents()); if (Object.keys(span.attribs || {}).length === 0) element.replaceWith(element.contents());
}); });
@@ -282,7 +283,7 @@ function normalizeCopiedHtml(html: string): string {
$(":empty") $(":empty")
.not("br,img,hr") .not("br,img,hr")
.filter((_, element) => $(element).parents("math").length === 0) .filter((_, element) => $(element).parents("math, .katex, .katex-display").length === 0)
.remove(); .remove();
normalizeMathMl($); normalizeMathMl($);
@@ -448,9 +449,30 @@ async function extractConversation(sourceUrl: string): Promise<ExtractedConversa
clone.querySelectorAll("*").forEach((element) => { clone.querySelectorAll("*").forEach((element) => {
Array.from(element.attributes).forEach((attr) => { Array.from(element.attributes).forEach((attr) => {
const name = attr.name.toLowerCase(); const name = attr.name.toLowerCase();
const keep = ["href", "src", "alt", "title", "colspan", "rowspan"].includes(name); const elementClass = element.getAttribute("class") || "";
const inMathOrKatex =
element.closest("math, .katex, .katex-display") !== null ||
/\bkatex(?:-|$)/.test(elementClass);
const keep =
["href", "src", "alt", "title", "colspan", "rowspan"].includes(name) ||
(inMathOrKatex &&
[
"aria-hidden",
"class",
"display",
"encoding",
"fence",
"mathvariant",
"maxsize",
"minsize",
"separator",
"stretchy",
"style",
"xmlns"
].includes(name));
if (name.startsWith("on") || !keep) element.removeAttribute(attr.name); if (name.startsWith("on") || !keep) element.removeAttribute(attr.name);
if ((name === "href" || name === "src") && /^javascript:/i.test(attr.value)) element.removeAttribute(attr.name); if ((name === "href" || name === "src") && /^javascript:/i.test(attr.value)) element.removeAttribute(attr.name);
if (name === "style" && /(?:expression|@import|url\s*\()/i.test(attr.value)) element.removeAttribute(attr.name);
}); });
}); });
+15
View File
@@ -113,6 +113,21 @@ h1 { margin: 0; font-size: clamp(28px, 5vw, 44px); line-height: 1.12; letter-spa
.content math { color: inherit; font-family: math, "STIX Two Math", "Cambria Math", "Noto Sans Math", serif; font-size: 1.02em; } .content math { color: inherit; font-family: math, "STIX Two Math", "Cambria Math", "Noto Sans Math", serif; font-size: 1.02em; }
.content > math { display: block; max-width: 100%; margin: 0.95em 0; overflow-x: auto; overflow-y: hidden; } .content > math { display: block; max-width: 100%; margin: 0.95em 0; overflow-x: auto; overflow-y: hidden; }
.content p math, .content li math { vertical-align: -0.08em; } .content p math, .content li math { vertical-align: -0.08em; }
.content .katex { font: normal 1.18em/1.2 "Times New Roman", "STIX Two Math", "Cambria Math", "Noto Sans Math", serif; text-indent: 0; white-space: nowrap; }
.content .katex-display { display: block; max-width: 100%; margin: 1em 0; padding: 14px 16px; overflow-x: auto; overflow-y: hidden; border-radius: 8px; background: var(--soft); text-align: center; }
.content .katex-display > .katex { display: inline-block; text-align: initial; }
.content .katex-mathml { position: absolute; width: 1px; height: 1px; padding: 0; border: 0; overflow: hidden; clip: rect(1px, 1px, 1px, 1px); white-space: nowrap; }
.content .katex-html { display: inline-block; }
.content .katex .base { position: relative; display: inline-block; white-space: nowrap; }
.content .katex .strut { display: inline-block; }
.content .katex .mord, .content .katex .mop, .content .katex .mbin, .content .katex .mrel, .content .katex .mopen, .content .katex .mclose, .content .katex .mpunct, .content .katex .minner { display: inline-block; }
.content .katex .mspace { display: inline-block; }
.content .katex .vlist-t { display: inline-table; table-layout: fixed; border-collapse: collapse; }
.content .katex .vlist-r { display: table-row; }
.content .katex .vlist { display: table-cell; position: relative; vertical-align: bottom; }
.content .katex .vlist > span { display: block; height: 0; position: relative; }
.content .katex .pstrut { display: block; overflow: hidden; width: 0; }
.content .katex .frac-line { display: inline-block; width: 100%; border-bottom: 0.04em solid currentColor; }
.content a[data-citation] { display: inline-flex; align-items: center; gap: 5px; max-width: min(100%, 260px); min-height: 24px; margin: 0 2px; padding: 2px 8px 2px 5px; border: 1px solid var(--border); border-radius: 999px; background: var(--soft); color: var(--text); font-size: 0.88em; line-height: 1.25; white-space: nowrap; text-decoration: none; vertical-align: -5px; } .content a[data-citation] { display: inline-flex; align-items: center; gap: 5px; max-width: min(100%, 260px); min-height: 24px; margin: 0 2px; padding: 2px 8px 2px 5px; border: 1px solid var(--border); border-radius: 999px; background: var(--soft); color: var(--text); font-size: 0.88em; line-height: 1.25; white-space: nowrap; text-decoration: none; vertical-align: -5px; }
.content a[data-citation]:hover { background: color-mix(in srgb, var(--soft) 82%, var(--text) 18%); } .content a[data-citation]:hover { background: color-mix(in srgb, var(--soft) 82%, var(--text) 18%); }
.content a[data-citation] img { width: 16px; height: 16px; max-width: 16px; max-height: 16px; border-radius: 50%; object-fit: cover; flex: 0 0 auto; } .content a[data-citation] img { width: 16px; height: 16px; max-width: 16px; max-height: 16px; border-radius: 50%; object-fit: cover; flex: 0 0 auto; }