mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-07-12 12:37:32 +00:00
fix(markdown): stop currency dollars rendering as KaTeX inline math (#5132)
This commit is contained in:
@@ -661,8 +661,11 @@ export function mdToHtml(src, opts) {
|
||||
return placeholder;
|
||||
} catch (e) { return match; }
|
||||
});
|
||||
// Inline math: $...$ (not preceded/followed by $ or digit, not spanning multiple lines)
|
||||
s = s.replace(/(?<!\$)\$(?!\$)([^\$\n]+?)\$(?!\$)/g, (match, math) => {
|
||||
// Inline math: $...$ — single line only, and Pandoc-style delimiter rules so
|
||||
// currency doesn't render as math ("$5 to $10"): the opening $ must be
|
||||
// immediately followed by a non-space, the closing $ must be immediately
|
||||
// preceded by a non-space and not followed by a digit.
|
||||
s = s.replace(/(?<![\$\d])\$(?!\$)(?=\S)([^\$\n]+?)(?<=\S)\$(?!\$|\d)/g, (match, math) => {
|
||||
try {
|
||||
const raw = math.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
const placeholder = `___MATH_BLOCK_${mathBlocks.length}___`;
|
||||
|
||||
@@ -18,12 +18,24 @@ def node_available():
|
||||
pytest.skip("node binary not on PATH")
|
||||
|
||||
|
||||
def _run_markdown_case(markdown: str, render_expr: str = "mod.mdToHtml(input)"):
|
||||
def _run_markdown_case(markdown: str, render_expr: str = "mod.mdToHtml(input)", with_katex: bool = False):
|
||||
script = textwrap.dedent(
|
||||
r"""
|
||||
import fs from 'node:fs';
|
||||
|
||||
globalThis.window = { location: { origin: 'http://localhost' }, katex: null };
|
||||
if (__WITH_KATEX__) {
|
||||
// Minimal stand-in for the CDN katex global: wraps the source so tests
|
||||
// can assert what was (or wasn't) handed to KaTeX.
|
||||
const katexStub = {
|
||||
renderToString(src, opts) {
|
||||
const display = !!(opts && opts.displayMode);
|
||||
return `<span class="katex" data-display="${display}">${src}</span>`;
|
||||
},
|
||||
};
|
||||
globalThis.window.katex = katexStub;
|
||||
globalThis.katex = katexStub;
|
||||
}
|
||||
globalThis.document = {
|
||||
readyState: 'loading',
|
||||
addEventListener() {},
|
||||
@@ -77,7 +89,9 @@ def _run_markdown_case(markdown: str, render_expr: str = "mod.mdToHtml(input)"):
|
||||
const input = JSON.parse(process.argv[1]);
|
||||
console.log(JSON.stringify({ html: __RENDER_EXPR__ }));
|
||||
"""
|
||||
).replace("__RENDER_EXPR__", render_expr)
|
||||
).replace("__RENDER_EXPR__", render_expr).replace(
|
||||
"__WITH_KATEX__", "true" if with_katex else "false"
|
||||
)
|
||||
result = subprocess.run(
|
||||
["node", "--input-type=module", "-e", script, json.dumps(markdown)],
|
||||
cwd=_REPO,
|
||||
@@ -200,6 +214,33 @@ def test_inline_code_content_is_html_escaped(node_available):
|
||||
assert "<b>" not in html
|
||||
|
||||
|
||||
def test_currency_dollar_amounts_are_not_rendered_as_math(node_available):
|
||||
# "$5 to $10" used to pair the two dollar signs as inline-math delimiters
|
||||
# and render "5 to" through KaTeX. Pandoc-style rules now reject it: the
|
||||
# closing $ is preceded by a space and followed by a digit.
|
||||
html = _run_markdown_case(
|
||||
"The price rose from $5 to $10 overnight.", with_katex=True
|
||||
)
|
||||
|
||||
assert 'class="katex"' not in html
|
||||
assert "$5" in html
|
||||
assert "$10" in html
|
||||
|
||||
|
||||
def test_inline_math_still_renders_through_katex(node_available):
|
||||
html = _run_markdown_case("Pythagoras: $x^2 + y^2 = z^2$ holds.", with_katex=True)
|
||||
|
||||
assert '<span class="katex" data-display="false">x^2 + y^2 = z^2</span>' in html
|
||||
assert "$" not in html
|
||||
|
||||
|
||||
def test_display_math_still_renders_through_katex(node_available):
|
||||
html = _run_markdown_case("$$\\frac{a}{b}$$", with_katex=True)
|
||||
|
||||
assert 'data-display="true"' in html
|
||||
assert "$$" not in html
|
||||
|
||||
|
||||
def test_dotted_python_import_paths_are_not_autolinked(node_available):
|
||||
html = _run_markdown_case(
|
||||
"from imblearn.combine import SMOTETomek\n"
|
||||
|
||||
Reference in New Issue
Block a user