Compact MathML cleanup
This commit is contained in:
@@ -279,13 +279,10 @@ function normalizeCopiedHtml(html: string): string {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
normalizeMathMl($);
|
|
||||||
|
|
||||||
$(":empty")
|
$(":empty")
|
||||||
.not("br,img,hr")
|
.not("br,img,hr")
|
||||||
.filter((_, element) => $(element).parents("math, .katex, .katex-display").length === 0)
|
.filter((_, element) => $(element).parents("math, .katex, .katex-display").length === 0)
|
||||||
.remove();
|
.remove();
|
||||||
normalizeMathMl($);
|
|
||||||
|
|
||||||
const finalDocument = cheerio.load($.html(), {}, false);
|
const finalDocument = cheerio.load($.html(), {}, false);
|
||||||
normalizeMathMl(finalDocument);
|
normalizeMathMl(finalDocument);
|
||||||
@@ -476,72 +473,6 @@ async function extractConversation(sourceUrl: string): Promise<ExtractedConversa
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function comparableMathText(value: string): string {
|
|
||||||
return value.replace(/\\div/g, "÷").replace(/\s+/g, "").trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
function trimDuplicateMathFallback(fallback: string, expression: string): string | null {
|
|
||||||
const target = comparableMathText(expression);
|
|
||||||
if (!target) return null;
|
|
||||||
let consumed = "";
|
|
||||||
let index = 0;
|
|
||||||
while (index < fallback.length && consumed.length < target.length) {
|
|
||||||
const next = fallback.startsWith("\\div", index) ? "÷" : fallback[index];
|
|
||||||
const width = fallback.startsWith("\\div", index) ? 4 : 1;
|
|
||||||
index += width;
|
|
||||||
if (/\s/.test(next)) continue;
|
|
||||||
consumed += next;
|
|
||||||
}
|
|
||||||
if (consumed === target) return fallback.slice(index);
|
|
||||||
|
|
||||||
const leading = fallback.match(/^\s*/)?.[0] || "";
|
|
||||||
const rest = fallback.slice(leading.length);
|
|
||||||
const fallbackRun = rest.match(/^[^\s<]+/)?.[0] || "";
|
|
||||||
const mathOperators = /[=∑∏√±×⋅*/^_≥≤<>−+÷]/;
|
|
||||||
if (fallbackRun.length >= 3 && mathOperators.test(fallbackRun) && mathOperators.test(target)) {
|
|
||||||
return `${leading}${rest.slice(fallbackRun.length)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstLine = rest.split(/\n/, 1)[0] || "";
|
|
||||||
const compactLine = comparableMathText(firstLine);
|
|
||||||
if (compactLine.length >= 8 && mathOperators.test(compactLine) && mathOperators.test(target)) {
|
|
||||||
const available = new Map<string, number>();
|
|
||||||
for (const char of target) available.set(char, (available.get(char) || 0) + 1);
|
|
||||||
let shared = 0;
|
|
||||||
for (const char of compactLine) {
|
|
||||||
const count = available.get(char) || 0;
|
|
||||||
if (count <= 0) continue;
|
|
||||||
available.set(char, count - 1);
|
|
||||||
shared += 1;
|
|
||||||
}
|
|
||||||
if (shared / Math.min(target.length, compactLine.length) >= 0.6) {
|
|
||||||
return `${leading}${rest.slice(firstLine.length)}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function trimMathFallbackNode(node: ChildNode | null, expression: string): void {
|
|
||||||
if (node?.nodeType === Node.TEXT_NODE) {
|
|
||||||
const trimmed = trimDuplicateMathFallback(node.textContent || "", expression);
|
|
||||||
if (trimmed !== null) node.textContent = trimmed;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(node instanceof HTMLElement) || node.tagName.toLowerCase() !== "span") return;
|
|
||||||
if (node.childNodes.length !== 1 || node.firstChild?.nodeType !== Node.TEXT_NODE) return;
|
|
||||||
const trimmed = trimDuplicateMathFallback(node.textContent || "", expression);
|
|
||||||
if (trimmed !== null) node.textContent = trimmed;
|
|
||||||
}
|
|
||||||
|
|
||||||
clone.querySelectorAll("math").forEach((math) => {
|
|
||||||
const visible = math.cloneNode(true) as Element;
|
|
||||||
visible.querySelectorAll("annotation, annotation-xml").forEach((node) => node.remove());
|
|
||||||
const visibleText = visible.textContent || "";
|
|
||||||
math.querySelectorAll("annotation, annotation-xml").forEach((node) => node.remove());
|
|
||||||
trimMathFallbackNode(math.nextSibling, visibleText);
|
|
||||||
});
|
|
||||||
|
|
||||||
return clone.innerHTML.trim();
|
return clone.innerHTML.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user