init: WordFileParse docx→HTML 解析服务(含 Word EQ 域公式修复)

服务:Spring Boot 3.2 + docx4j 8.3.9,POST /api/v3/server_office_file/file/parse
      接受 .docx,返回 HTML(公式 → LaTeX,图片 → RustFS 外链)

公式支持三类来源:
- OMML(Word 2007+ 公式)      → Python omml_mathml2latex
- MathType OLE 对象            → Ruby mathtype2mathml → MathML → LaTeX
- Word EQ 域(老教辅主力)      → EqToLatexUtil(本次新增)

本次改动:
1. 新增 java-svc/.../core/EqToLatexUtil.java:
   移植自 jby backend-services office-core,EQ 语法 → LaTeX
   (\f→\dfrac、\r→\sqrt、\i→\int/\sum/\prod、\s→^{}/_{}、\b→\left\right、
     \a→array、\x→\boxed/\overline、\o\al 堆叠、圈码、化学符号、极限、连等式)
   品牌标记 JBYU* → WPU*,与采集端一致
2. CtoMathFinder:接上 EQ 分支(原为 not-ported 桩),域代码经
   EqToLatexUtil.convert 转 LaTeX 写入 eqLatexMap(WPEQNUM 占位符)
3. WordParseUtil.dealPlaceholder:EQ 的 LaTeX 同样加 \( \) 包裹
   (原先因 WPEQNUM 例外不加包裹,前端/MathJax 不渲染)

修前症状:教辅 Word 里分式/方程组/上下标整段丢失(如 {−1/3, 1} 变成 {-,1})
修后实测:46 份教辅 2908 处 EQ 域全部还原,公式总数 2954 处、零未包裹残留

安全:application.yml(含 RustFS 密钥)不入库,提供 application.yml.example;
      OssService 的 @Value 默认密钥已清空
This commit is contained in:
2026-09-29 09:43:13 +08:00
commit 3271fee5cc
360 changed files with 86082 additions and 0 deletions

View File

@@ -0,0 +1,689 @@
"""
Unicode to LaTeX symbol mappings for OMML/MathML to LaTeX conversion.
This module provides comprehensive Unicode symbol to LaTeX command mappings
for mathematical notation, chemical symbols, and special characters.
Architecture
============
This module defines three primary dictionaries that work together to handle
symbol conversion with MathJax compatibility:
1. UNICODE_TO_LATEX (dict[str, str])
- Maps Unicode symbols → LaTeX commands
- Used for symbols that SHOULD be converted to LaTeX
- Contains ~430 symbol mappings organized by category:
* Greek letters (lowercase and uppercase)
* Mathematical operators and relations
* Arrows and directional symbols
* Set theory and logic symbols
* Calculus and analysis symbols (basic integrals)
* Chemistry symbols and arrows
* Geometric shapes and special characters
2. UNICODE_PASSTHROUGH (set[str])
- Unicode symbols that should NEVER be converted to LaTeX
- These symbols are kept as-is for MathJax compatibility
- Contains ~64 advanced mathematical symbols whose LaTeX commands
are not supported or render poorly in MathJax
- Examples: advanced integrals (∯, ∰), special operators (⊛, ⊚)
- IMPORTANT: Symbols in this set are NOT in UNICODE_TO_LATEX
3. MATHJAX_UNSUPPORTED_TO_UNICODE (dict[str, str])
- Inverse of UNICODE_PASSTHROUGH: LaTeX command → Unicode
- Used in post-processing to convert unsupported LaTeX back to Unicode
- Should be exact inverse of symbols in UNICODE_PASSTHROUGH
Conversion Flow
===============
Input Unicode Symbol
↓
Is it in UNICODE_PASSTHROUGH?
├─ YES → Keep as Unicode (don't convert)
└─ NO → Look up in UNICODE_TO_LATEX
↓
Convert to LaTeX command
↓
Post-process: If command in MATHJAX_UNSUPPORTED_TO_UNICODE
↓
Convert back to Unicode for MathJax rendering
Design Principles
=================
1. **No Overlap**: Symbols should be in EITHER UNICODE_TO_LATEX OR
UNICODE_PASSTHROUGH, never both.
2. **Consistency**: MATHJAX_UNSUPPORTED_TO_UNICODE values must exactly
match UNICODE_PASSTHROUGH contents (they are inverses).
3. **Inverse Mapping**: For any symbol in UNICODE_PASSTHROUGH, if there
exists a LaTeX command in MATHJAX_UNSUPPORTED_TO_UNICODE, the command
names must be consistent.
4. **Special Patterns**:
- Empty braces ({}) only for radical symbols (√, ∛, ∜)
- Placeholders (__DDOT__, __DDDOT__) only for accent detection
- Regional preferences handled separately (see REGIONAL_SYMBOL_PREFERENCES)
Testing
=======
Symbol dictionary integrity is validated by:
- tests/test_symbol_dictionaries.py
This test suite ensures:
- No duplicate keys in any dictionary
- No overlap between UNICODE_TO_LATEX and UNICODE_PASSTHROUGH
- Consistency between MATHJAX_UNSUPPORTED and UNICODE_PASSTHROUGH
- Valid mappings and inverse consistency
"""
# Centralized symbol mappings to eliminate duplication
UNICODE_TO_LATEX = {
# Greek letters (lowercase)
"α": "\\alpha", "β": "\\beta", "γ": "\\gamma", "δ": "\\delta",
"ε": "\\varepsilon", "ζ": "\\zeta", "η": "\\eta", "θ": "\\theta",
"ι": "\\iota", "κ": "\\kappa", "λ": "\\lambda", "μ": "\\mu",
"ν": "\\nu", "ξ": "\\xi", "ο": "\\omicron", "π": "\\pi",
"ρ": "\\rho", "σ": "\\sigma", "τ": "\\tau", "υ": "\\upsilon",
"φ": "\\varphi", "χ": "\\chi", "ψ": "\\psi", "ω": "\\omega",
"ϵ": "\\epsilon", "ϑ": "\\vartheta", "ϕ": "\\phi", "ϱ": "\\varrho",
"ϖ": "\\varpi", "ς": "\\varsigma", "ϰ": "\\varkappa",
# Greek letters (uppercase)
"Α": "A", "Β": "B", "Γ": "\\Gamma", "Δ": "\\Delta",
"Ε": "E", "Ζ": "Z", "Η": "H", "Θ": "\\Theta",
"Ι": "I", "Κ": "K", "Λ": "\\Lambda", "Μ": "M",
"Ν": "N", "Ξ": "\\Xi", "Ο": "O", "Π": "\\Pi",
"Ρ": "P", "Σ": "\\Sigma", "Τ": "T", "Υ": "\\Upsilon",
"Φ": "\\Phi", "Χ": "X", "Ψ": "\\Psi", "Ω": "\\Omega",
# Mathematical constants and special symbols
"∞": "\\infty", "∅": "\\emptyset", "∇": "\\nabla", "∂": "\\partial",
"ℏ": "\\hbar", "ℓ": "\\ell", "∠": "\\angle", "∁": "\\complement",
"℘": "\\wp", "ℵ": "\\aleph", "℧": "\\mho",
# Geometric symbols
"△": "\\triangle", "▲": "\\blacktriangle", "▽": "\\triangledown",
"◁": "\\triangleleft", "▷": "\\triangleright", "◀": "\\blacktriangleleft",
"▶": "\\blacktriangleright",
# Square symbols (comprehensive coverage)
"□": "\\square", # U+25A1 WHITE SQUARE
"■": "\\blacksquare", # U+25A0 BLACK SQUARE
"▪": "\\blacksquare", # U+25AA BLACK SMALL SQUARE
"▫": "\\square", # U+25AB WHITE SMALL SQUARE
"◻": "\\square", # U+25FB WHITE MEDIUM SQUARE
"◼": "\\blacksquare", # U+25FC BLACK MEDIUM SQUARE
"◽": "\\square", # U+25FD WHITE MEDIUM SMALL SQUARE
"◾": "\\blacksquare", # U+25FE BLACK MEDIUM SMALL SQUARE
# Other geometric shapes
# NOTE: ▱ (parallelogram) is in UNICODE_PASSTHROUGH
"◇": "\\diamond", "◆": "\\blacklozenge", "○": "\\circ", "●": "\\bullet",
"☆": "\\star", "★": "\\bigstar", "◯": "\\bigcirc",
# Temperature symbols
"℃": "^\\circ\\mathrm{C}", "℉": "^\\circ\\mathrm{F}",
# Basic operators and punctuation
"∶": ":", # U+2236 RATIO to colon for assignment operators
"§": "\\S", "†": "\\dagger", "‵": "\\backprime",
"`": "\\backprime", # U+0060 GRAVE ACCENT (backtick) used as backprime in equations
"―": "\\textemdash", # U+2015 horizontal bar
# Multiplication and division
"×": "\\times", "⋅": "\\cdot", "·": "\\cdot", "÷": "\\div", "∕": "/", "⁄": "/",
"//": "/ /", # Double slash with spacing
"⧸": "/", # U+29F8 BIG SOLIDUS (used in \not patterns but also standalone)
# Mathematical script letters
"ℑ": "\\Im", # Imaginary part (Fraktur I)
"ℜ": "\\Re", # Real part (Fraktur R)
# Arrows (basic)
"→": "\\rightarrow", "←": "\\leftarrow", "↔": "\\leftrightarrow",
"⇒": "\\Longrightarrow", "⇐": "\\Longleftarrow", "⇔": "\\Longleftrightarrow",
"⟹": "\\Longrightarrow", "⟸": "\\Longleftarrow", "⟺": "\\Longleftrightarrow",
"⟷": "\\longleftrightarrow",
"↑": "\\uparrow", "↓": "\\downarrow", "⇑": "\\Uparrow", "⇓": "\\Downarrow",
"↕": "\\updownarrow", "⇕": "\\Updownarrow",
# Arrows (diagonal)
"↗": "\\nearrow", "↘": "\\searrow", "↙": "\\swarrow", "↖": "\\nwarrow",
"⤴": "\\nwarrow", "⤵": "\\searrow", "⤡": "\\swarrow", "⤢": "\\nearrow",
# Arrows (special forms)
# NOTE: Some special arrows (↤ mapsfrom, ⟻ longmapsfrom, ⇜ leftsquigarrow, ⇝ rightsquigarrow) are in UNICODE_PASSTHROUGH
"↦": "\\mapsto",
"⟼": "\\longmapsto",
"↪": "\\hookrightarrow", "↩": "\\hookleftarrow",
"⤷": "\\hookrightarrow", "⤶": "\\hookleftarrow",
"↬": "\\looparrowright", "↫": "\\looparrowleft",
"⇀": "\\rightharpoonup", "↼": "\\leftharpoonup",
"↢": "\\leftarrowtail", "↣": "\\rightarrowtail",
"↰": "\\Lsh", "↱": "\\Rsh",
# Arrows (negated)
"↛": "\\nrightarrow", "↚": "\\nleftarrow", "⇏": "\\nRightarrow", "⇍": "\\nLeftarrow",
"↮": "\\nleftrightarrow", "⇎": "\\nLeftrightarrow",
# Set theory and logic
# Set membership
"∈": "\\in", "∉": "\\notin", "∋": "\\ni", "∌": "\\notni",
"⋲": "\\in", "⋳": "\\ni", "⋴": "\\in", "⋵": "\\ni",
"⋶": "\\in", "⋷": "\\ni", "⋸": "\\pitchfork", "⋹": "\\ltimes",
# Subset and superset relations (basic)
"⊂": "\\subset", "⊃": "\\supset",
"⊆": "\\subseteq", "⊇": "\\supseteq",
"⊄": "\\not\\subset", "⊅": "\\not\\supset",
"⊈": "\\nsubseteq", "⊉": "\\nsupseteq",
"⊊": "\\subsetneq", "⊋": "\\supsetneq",
# Subset and superset relations (extended with double lines)
"⫅": "\\subseteqq", "⫆": "\\supseteqq", # U+2AC5, U+2AC6 subset/supset with double equals
"⫋": "\\subsetneqq", "⫌": "\\supsetneqq", # U+2ACB, U+2ACC not equal variant with double
"⫏": "\\sqsubset", "⫐": "\\sqsupset", # U+2ACF, U+2AD0 square subset/supset
"⫑": "\\sqsubseteq", "⫒": "\\sqsupseteq", # U+2AD1, U+2AD2 square subset/supset equal
"⊏": "\\sqsubset", "⊐": "\\sqsupset", # U+228F, U+2290 square variants
"⊑": "\\sqsubseteq", "⊒": "\\sqsupseteq", # U+2291, U+2292 square equal variants
# Set operations
# NOTE: Some symbols like ⊌ (dotcup), ⊍ (cupdot) are in UNICODE_PASSTHROUGH
"∪": "\\cup", "∩": "\\cap", "∖": "\\setminus",
"⊎": "\\uplus", "⊔": "\\sqcup", "⊓": "\\sqcap",
"⨃": "\\Cup", "⨄": "\\biguplus", "⨅": "\\bigsqcap", "⨆": "\\bigsqcup",
"⩁": "\\Cup", "⩂": "\\Cap", "⩃": "\\cupdot",
# Logical operators
"∧": "\\wedge", "∨": "\\vee", "¬": "\\neg", "⊕": "\\oplus",
"⊗": "\\otimes", "⊙": "\\odot", "⊖": "\\ominus", "⊘": "\\oslash",
"∀": "\\forall", "∃": "\\exists", "∄": "\\nexists",
"⊤": "\\top", "⊥": "\\perp", "⊢": "\\vdash", "⊣": "\\dashv",
"⊨": "\\models", "⊭": "\\not\\models",
"∴": "\\therefore", "∵": "\\because",
"⋏": "\\curlywedge", "⋎": "\\curlyvee",
# Additional logical symbols
"⊩": "\\Vdash", "⊪": "\\Vvdash", "⊫": "\\VDash", "⊬": "\\nvdash",
"⊯": "\\nVdash", "⊮": "\\nVDash", "∎": "\\qed", "◊": "\\lozenge",
"≐": "\\doteq", "≑": "\\doteqdot", "≒": "\\fallingdotseq", "≓": "\\risingdotseq",
# Relations
# Equality and equivalence
"≈": "\\approx", "≅": "\\cong", "≡": "\\equiv", "≢": "\\not\\equiv",
"≠": "\\neq", "≁": "\\not\\sim", "≄": "\\nsim", "≇": "\\ncong",
"~": "\\sim", # ASCII tilde (U+007E) - similarity operator
"∼": "\\sim", "≃": "\\simeq", "≂": "\\eqsim", "≊": "\\approxeq",
# Inequality relations (basic)
# NOTE: Triple relations ⋘ (lll), ⋙ (ggg) are in UNICODE_PASSTHROUGH
"≤": "\\leqslant", "≥": "\\geqslant", "≮": "\\nless", "≯": "\\ngtr",
"≰": "\\nleq", "≱": "\\ngeq", "≪": "\\ll", "≫": "\\gg",
# Inequality relations (extended)
"≦": "\\leqq", "≧": "\\geqq", "≨": "\\lneqq", "≩": "\\gneqq",
"⩽": "\\leqslant", "⩾": "\\geqslant", "⩿": "\\gneq",
"≶": "\\lessgtr", "≷": "\\gtrless", "≸": "\\not\\lessgtr", "≹": "\\not\\gtrless",
# NOTE: Advanced comparison symbols (⪋ lesseqgtr, ⪌ gtreqless, ⪅ lessapprox, etc.) are in UNICODE_PASSTHROUGH
"⪇": "\\lneq", "⪈": "\\gneq",
# Precedence and succession
# NOTE: Advanced precedence symbols (⋞ curlyeqprec, ⋟ curlyeqsucc, ⪷ precapprox, ⪸ succapprox) are in UNICODE_PASSTHROUGH
"≺": "\\prec", "≻": "\\succ", "⪯": "\\preceq", "⪰": "\\succeq",
"⪳": "\\preceqq", "⪴": "\\succeqq",
"⪵": "\\precneqq", "⪶": "\\succneqq",
# Similarity and comparison
"≲": "\\lesssim", "≳": "\\gtrsim", "≴": "\\not\\lesssim", "≵": "\\not\\gtrsim",
"∝": "\\propto", "∥": "\\parallel", "∦": "\\nparallel",
"≍": "\\asymp", "≎": "\\Bumpeq", "≏": "\\bumpeq",
"∽": "\\backsim", "⋍": "\\backsimeq", # U+22CD REVERSED TILDE EQUALS
"≌": "\\cong", # U+224C ALL EQUAL TO (commonly used for congruence)
"⊲": "\\lhd", "⊳": "\\rhd",
"⌢": "\\frown", "⌣": "\\smile",
# Special equality symbols
# NOTE: Some special equality symbols (≔ coloneqq, ≕ eqqcolon, ≘ arceq, ≙ wedgeq, ≚ veeeq) are in UNICODE_PASSTHROUGH
"≜": "\\triangleq", "≝": "\\overset{\\mathrm{def}}{=}", "≞": "\\overset{\\mathrm{m}}{=}",
"≟": "\\overset{?}{=}", "≗": "\\circeq", "≖": "\\eqcirc",
# Calculus and analysis
# Integrals
# NOTE: Many advanced integral symbols (∯, ∰, ∱, etc.) are in UNICODE_PASSTHROUGH
# for direct MathJax rendering, so they are NOT listed here
"∫": "\\int", "∬": "\\iint", "∭": "\\iiint", "⨌": "\\iiiint",
"∮": "\\oint",
# Differentials and operators
"∆": "\\Delta", "∂": "\\partial", "∇": "\\nabla",
"∝": "\\propto", "∞": "\\infty",
# Cardinality symbols
# NOTE: Hebrew letters ℶ (beth), ℷ (gimel), ℸ (daleth) are in UNICODE_PASSTHROUGH
"ℵ": "\\aleph",
# Number sets (use \mathbb for blackboard bold notation)
"ℕ": "\\mathbb{N}", "ℤ": "\\mathbb{Z}", "ℚ": "\\mathbb{Q}",
"ℝ": "\\mathbb{R}", "ℂ": "\\mathbb{C}", "ℍ": "\\mathbb{H}",
"ℙ": "\\mathbb{P}", "𝔽": "\\mathbb{F}", "𝔾": "\\mathbb{G}",
# Special operators
# Basic arithmetic operators
"±": "\\pm", "∓": "\\mp", "−": "-", "∔": "\\dotplus",
# Binary operators (algebraic)
"⋆": "\\star", "∗": "\\ast", "∘": "\\circ", "∙": "\\bullet",
"⋄": "\\diamond", "⋅": "\\cdot", "•": "\\bullet",
# Binary operators (lattice and semilattice)
# NOTE: ⊌ (dotcup), ⊍ (cupdot) are in UNICODE_PASSTHROUGH
"⊔": "\\sqcup", "⊓": "\\sqcap", "⊎": "\\uplus",
# Binary operators (group theory)
# NOTE: Some group theory operators (⋋ leftthreetimes, ⋌ rightthreetimes, ⋇ divideontimes) are in UNICODE_PASSTHROUGH
"⋉": "\\ltimes", "⋊": "\\rtimes",
"⨿": "\\amalg", "⋈": "\\bowtie",
# Binary operators (wreath and semidirect products)
"≀": "\\wr", "⊺": "\\intercal", "⊻": "\\veebar",
# Binary operators (extended)
# NOTE: Advanced box operators (⧄ boxbox, ⧅ boxast, ⧆ boxcirc, ⧇ boxbslash, ⧈ boxslash) are in UNICODE_PASSTHROUGH
"⊝": "\\ominus", "⊞": "\\boxplus", "⊟": "\\boxminus", "⊠": "\\boxtimes",
"⊡": "\\boxdot",
# Big operators
"∑": "\\sum", "∏": "\\prod", "∐": "\\coprod", "⋃": "\\bigcup",
"⋂": "\\bigcap", "⋁": "\\bigvee", "⋀": "\\bigwedge", "⨁": "\\bigoplus",
"⨂": "\\bigotimes", "⨄": "\\biguplus", "⨅": "\\bigsqcap", "⨆": "\\bigsqcup",
# Delimiters and brackets
# Angle brackets
"⟨": "\\langle", "⟩": "\\rangle", "⟪": "\\langle\\langle", "⟫": "\\rangle\\rangle",
"〈": "\\langle", "〉": "\\rangle", # CJK angle brackets
# Floor and ceiling
"⌊": "\\lfloor", "⌋": "\\rfloor", "⌈": "\\lceil", "⌉": "\\rceil",
# Special brackets
# NOTE: Some special brackets (⦅ llparenthesis, ⦆ rrparenthesis, 〚 llbracket, 〛 rrbracket, ⦉ Langle, ⦊ Rangle) are in UNICODE_PASSTHROUGH
"⦃": "\\{", "⦄": "\\}",
"⟦": "[\\![", "⟧": "]\\!]", "⟬": "\\llbracket", "⟭": "\\rrbracket",
"⦇": "\\llparenthesis", "⦈": "\\rrparenthesis",
# Absolute value and norm
"|": "|", "‖": "\\|", "∥": "\\parallel", # ‖ (U+2016) is double vertical line for norms → \|
# Miscellaneous symbols
# NOTE: Radical symbols must include {} braces for valid LaTeX
# Users may type these directly as text (malformed input), so we ensure valid output
"√": "\\sqrt{}", "∛": "\\sqrt[3]{}", "∜": "\\sqrt[4]{}",
"∡": "\\measuredangle", "∢": "\\sphericalangle", "°": "^\\circ",
# Prime notation - both Unicode primes and ASCII apostrophe (commonly used in Word)
"'": "\\prime", # ASCII apostrophe (U+0027) - commonly typed instead of Unicode prime
"′": "\\prime", "″": "\\prime\\prime", "‴": "\\prime\\prime\\prime", "⁗": "\\prime\\prime\\prime\\prime",
"℮": "e", "ℯ": "e", "ⅈ": "i", "ⅉ": "j",
# NOTE: ⋰ (iddots) is in UNICODE_PASSTHROUGH
"…": "\\ldots", "⋯": "\\cdots", "⋮": "\\vdots", "⋱": "\\ddots",
"♭": "\\flat", "♮": "\\natural", "♯": "\\sharp",
# Fullwidth punctuation (CJK)
",": ", ", # U+FF0C fullwidth comma (Chinese comma) → regular comma with space
# Accent marks (for detection in mover elements)
"¨": "__DDOT__", # U+00A8 diaeresis (standalone) - placeholder for ddot detection
"⃛": "__DDDOT__", # U+20DB combining three dots above - placeholder for dddot detection
"̈": "__DDOT__", # U+0308 combining diaeresis - placeholder for ddot detection
"⃛": "__DDDOT__", # U+20DB combining triple dot above - placeholder for dddot detection
# Chemistry arrows and symbols (harpoons)
"⇌": "\\rightleftharpoons", # U+21CC rightleftharpoons (equilibrium)
"⇋": "\\leftrightharpoons", # U+21CB leftrightharpoons (equilibrium reversed)
"⇀": "\\rightharpoonup", # U+21C0 rightharpoonup
"⇁": "\\rightharpoondown", # U+21C1 rightharpoondown
"↼": "\\leftharpoonup", # U+21BC leftharpoonup
"↽": "\\leftharpoondown", # U+21BD leftharpoondown
"⥂": "\\rightleftharpoons", # U+2942 alternate form
"⥃": "\\leftrightharpoons", # U+2943 alternate form
"⥄": "\\rightleftarrows", # U+2944 right over left arrows
"⥅": "\\leftrightarrows", # U+2945 left over right arrows
"⥆": "\\rightleftarrows", # U+2946 right over left arrows
"⥇": "\\leftrightarrows", # U+2947 left over right arrows
"⇄": "\\rightleftarrows", # U+21C4 right over left (already in extended arrows)
"⇆": "\\leftrightarrows", # U+21C6 left over right (already in extended arrows)
"⇉": "\\rightrightarrows", # U+21C9 double right (already in extended arrows)
"⇇": "\\leftleftarrows", # U+21C7 double left (already in extended arrows)
# Overbrace and underbrace characters
"⏞": "\\overbrace", "⏟": "\\underbrace",
# Extended mathematical operators (remaining unique ones)
# NOTE: ⊚ (ocirc), ⊛ (oast) are in UNICODE_PASSTHROUGH
# Extended relation symbols (remaining unique ones)
# NOTE: Several special equality symbols (≔ coloneqq, ≕ eqqcolon, ≘ arceq, ≙ wedgeq, ≚ veeeq) are in UNICODE_PASSTHROUGH
"≆": "\\approxeq", "≛": "\\triangleq",
# Extended arrows (remaining unique ones)
"⇈": "\\upuparrows", "⇊": "\\downdownarrows",
"⇅": "\\updownarrows", "⇵": "\\downuparrows", "↶": "\\curvearrowleft",
"↷": "\\curvearrowright", "↺": "\\circlearrowleft", "↻": "\\circlearrowright",
# Extended logical symbols
# NOTE: ⟀ (lozengeminus) is in UNICODE_PASSTHROUGH
"⟁": "\\lozengepls", "⟂": "\\perp", "⟃": "\\between",
"⟄": "\\pitchfork", "⟅": "\\varpropto", "⟆": "\\backprime", "⟇": "\\caretinsert",
# Extended geometric symbols
"⟐": "\\angle", "⟑": "\\measuredangle", "⟒": "\\sphericalangle", "⟓": "\\rightangle",
"⟔": "\\angle", "⟕": "\\measuredangle", "⟖": "\\sphericalangle", "⟗": "\\rightangle",
# Extended miscellaneous symbols
"⟘": "\\perp", "⟙": "\\diamondsuit", "⟚": "\\heartsuit", "⟛": "\\clubsuit",
"⟜": "\\spadesuit", "⟝": "\\varnothing", "⟞": "\\diameter", "⟟": "\\house",
}
# Additional Symbol Replacements (Consolidated from scattered code)
# ========================================================================
# These symbols are used in specific contexts (e.g., function subscripts)
# and should be applied consistently across the codebase
ADDITIONAL_SYMBOL_REPLACEMENTS = {
# Arrows used in function subscripts (line 1828)
'→': '\\to ',
# These are handled in UNICODE_TO_LATEX but kept for reference in subscript context
# '∞': '\\infty', # Already in UNICODE_TO_LATEX
# '≤': '\\leqslant ', # Already in UNICODE_TO_LATEX
# '≥': '\\geqslant ', # Already in UNICODE_TO_LATEX
# '≠': '\\ne ', # Already in UNICODE_TO_LATEX as \\neq
# '±': '\\pm ', # Already in UNICODE_TO_LATEX
}
# LaTeX command normalization (converting between command variants)
LATEX_COMMAND_REPLACEMENTS = {
# Logical equivalence (line 5545)
'\\Longleftrightarrow': '\\iff ',
# Arrow shorthand (line 5548)
'\\lra': '\\leftrightarrow',
}
# Summation symbols for OMML fallback parser
SUMMATION_SYMBOLS = {
'∑': 'sum',
'∏': 'prod',
'∫': 'integral',
'Σ': 'sum',
'Π': 'prod'
}
# LaTeX commands not supported by MathJax - use Unicode fallback
# Maps LaTeX command (without backslash) to Unicode character
# This comprehensive list ensures proper rendering in MathJax environments
MATHJAX_UNSUPPORTED_TO_UNICODE = {
# =========================================================================
# INTEGRAL OPERATORS - Many not in standard MathJax
# =========================================================================
# Surface and volume integrals
'oiint': '∯', # U+222F SURFACE INTEGRAL
'oiiint': '∰', # U+2230 VOLUME INTEGRAL
# Clockwise/counterclockwise integrals - NOT in MathJax
'intclockwise': '∱', # U+2231 CLOCKWISE INTEGRAL
'varointclockwise': '∲', # U+2232 CLOCKWISE CONTOUR INTEGRAL
'varointctrclockwise': '∳', # U+2233 ANTICLOCKWISE CONTOUR INTEGRAL
# Extended integrals - limited MathJax support
'fint': '⨍', # U+2A0D FINITE PART INTEGRAL
'pointint': '⨎', # U+2A0E PATH INTEGRAL (line integral)
'sqint': '⨏', # U+2A0F INTEGRAL WITH SQUARED OPERATOR
'intlarhk': '⨐', # U+2A10 CIRCULATION FUNCTION
'intbar': '⨑', # U+2A11 INTEGRAL WITH OVERBAR
'intBar': '⨒', # U+2A12 INTEGRAL WITH DOUBLE OVERBAR
'fintbar': '⨓', # U+2A13 FINITE PART INTEGRAL WITH OVERBAR
'ointbar': '⨔', # U+2A14 CONTOUR INTEGRAL WITH OVERBAR
'ointBar': '⨕', # U+2A15 CONTOUR INTEGRAL WITH DOUBLE OVERBAR
'oiintbar': '⨖', # U+2A16 SURFACE INTEGRAL WITH OVERBAR
'oiintBar': '⨗', # U+2A17 SURFACE INTEGRAL WITH DOUBLE OVERBAR
# =========================================================================
# BINARY OPERATORS - Non-standard or limited support
# =========================================================================
# Division operator
'divideontimes': '⋇', # U+22C7 DIVISION TIMES
# Circle operators - non-standard names
'oast': '⊛', # U+229B CIRCLED ASTERISK OPERATOR
'ocirc': '⊚', # U+229A CIRCLED RING OPERATOR
# Box operators - extended (standard ones like boxplus ARE supported)
'boxbox': '⧄', # U+29C4 SQUARED SQUARE
'boxast': '⧅', # U+29C5 SQUARED ASTERISK
'boxcirc': '⧆', # U+29C6 SQUARED SMALL CIRCLE
'boxbslash': '⧇', # U+29C7 SQUARED BACKSLASH
'boxslash': '⧈', # U+29C8 SQUARED SLASH
# Semidirect products
'leftthreetimes': '⋋', # U+22CB LEFT SEMIDIRECT PRODUCT
'rightthreetimes': '⋌', # U+22CC RIGHT SEMIDIRECT PRODUCT
# Set operations with dot
'dotcup': '⊌', # U+228C MULTISET
'cupdot': '⊍', # U+228D MULTISET MULTIPLICATION
# =========================================================================
# ARROWS - Extended arrows with limited MathJax support
# =========================================================================
'mapsfrom': '↤', # U+21A4 LEFTWARDS ARROW FROM BAR
'longmapsfrom': '⟻', # U+27FB LONG LEFTWARDS ARROW FROM BAR
'leftsquigarrow': '⇜', # U+21DC LEFTWARDS SQUIGGLE ARROW
'rightsquigarrow': '⇝', # U+21DD RIGHTWARDS SQUIGGLE ARROW
# 'looparrowleft': '↫', # U+21AB LEFTWARDS ARROW WITH LOOP
# 'looparrowright': '↬', # U+21AC RIGHTWARDS ARROW WITH LOOP
# 'leftarrowtail': '↢', # U+21A2 LEFTWARDS ARROW WITH TAIL
# 'rightarrowtail': '↣', # U+21A3 RIGHTWARDS ARROW WITH TAIL
# 'Lsh': '↰', # U+21B0 UPWARDS ARROW WITH TIP LEFTWARDS
# 'Rsh': '↱', # U+21B1 UPWARDS ARROW WITH TIP RIGHTWARDS
# 'curvearrowleft': '↶', # U+21B6 ANTICLOCKWISE TOP SEMICIRCLE ARROW
# 'curvearrowright': '↷', # U+21B7 CLOCKWISE TOP SEMICIRCLE ARROW
# 'circlearrowleft': '↺', # U+21BA ANTICLOCKWISE OPEN CIRCLE ARROW
# 'circlearrowright': '↻', # U+21BB CLOCKWISE OPEN CIRCLE ARROW
# 'upuparrows': '⇈', # U+21C8 UPWARDS PAIRED ARROWS
# 'downdownarrows': '⇊', # U+21CA DOWNWARDS PAIRED ARROWS
# 'updownarrows': '⇅', # U+21C5 UPWARDS ARROW LEFTWARDS OF DOWNWARDS
# 'downuparrows': '⇵', # U+21F5 DOWNWARDS ARROW LEFTWARDS OF UPWARDS
# =========================================================================
# RELATION SYMBOLS - Extended relations
# =========================================================================
# Triple comparisons
'lll': '⋘', # U+22D8 VERY MUCH LESS-THAN
'ggg': '⋙', # U+22D9 VERY MUCH GREATER-THAN
# Combined relations
'lesseqgtr': '⪋', # U+2A8B LESS-THAN EQUAL TO OR GREATER-THAN
'gtreqless': '⪌', # U+2A8C GREATER-THAN EQUAL TO OR LESS-THAN
'lessapprox': '⪅', # U+2A85 LESS-THAN OR APPROXIMATE
'gtrapprox': '⪆', # U+2A86 GREATER-THAN OR APPROXIMATE
'lnapprox': '⪉', # U+2A89 LESS-THAN AND NOT APPROXIMATE
'gnapprox': '⪊', # U+2A8A GREATER-THAN AND NOT APPROXIMATE
# Precedence relations
'precapprox': '⪷', # U+2AB7 PRECEDES ABOVE ALMOST EQUAL TO
'succapprox': '⪸', # U+2AB8 SUCCEEDS ABOVE ALMOST EQUAL TO
'curlyeqprec': '⋞', # U+22DE EQUAL TO OR PRECEDES
'curlyeqsucc': '⋟', # U+22DF EQUAL TO OR SUCCEEDS
# Similarity relations
# 'backsim': '∽', # U+223D REVERSED TILDE
# 'backsimeq': '⋍', # U+22CD REVERSED TILDE EQUALS
# Special equality symbols
'wedgeq': '≙', # U+2259 ESTIMATES (wedge equals)
'veeeq': '≚', # U+225A EQUIANGULAR TO
'arceq': '≘', # U+2258 CORRESPONDS TO
'coloneqq': '≔', # U+2254 COLON EQUALS
'eqqcolon': '≕', # U+2255 EQUALS COLON
'Coloneqq': '⩴', # U+2A74 DOUBLE COLON EQUAL
'eqcolon': '∹', # U+2239 EXCESS (-:)
# =========================================================================
# BRACKET/DELIMITER SYMBOLS
# =========================================================================
'llbracket': '〚', # U+301A LEFT WHITE SQUARE BRACKET
'rrbracket': '〛', # U+301B RIGHT WHITE SQUARE BRACKET
'llparenthesis': '⦅', # U+2985 LEFT WHITE PARENTHESIS
'rrparenthesis': '⦆', # U+2986 RIGHT WHITE PARENTHESIS
'Langle': '⦉', # U+2989 Z NOTATION LEFT BINDING BRACKET
'Rangle': '⦊', # U+298A Z NOTATION RIGHT BINDING BRACKET
# =========================================================================
# GEOMETRIC AND MISCELLANEOUS SYMBOLS
# =========================================================================
'parallelogram': '▱', # U+25B1 WHITE PARALLELOGRAM
'iddots': '⋰', # U+22F0 UP RIGHT DIAGONAL ELLIPSIS
# 'mho': '℧', # U+2127 INVERTED OHM SIGN
# 'complement': '∁', # U+2201 COMPLEMENT
# Hebrew letters (beyond aleph)
'beth': 'ℶ', # U+2136 BET SYMBOL
'gimel': 'ℷ', # U+2137 GIMEL SYMBOL
'daleth': 'ℸ', # U+2138 DALET SYMBOL
# =========================================================================
# LOGICAL AND SET OPERATORS
# =========================================================================
# Extended subset/superset relations
# 'subseteqq': '⫅', # U+2AC5 SUBSET OF ABOVE EQUALS SIGN
# 'supseteqq': '⫆', # U+2AC6 SUPERSET OF ABOVE EQUALS SIGN
# 'subsetneqq': '⫋', # U+2ACB SUBSET OF ABOVE NOT EQUAL TO
# 'supsetneqq': '⫌', # U+2ACC SUPERSET OF ABOVE NOT EQUAL TO
# Logic symbols
'lozengeminus': '⟀', # U+27C0 THREE DIMENSIONAL ANGLE
'between': '≬', # U+226C BETWEEN
}
# Regional symbol preferences (e.g., Chinese region prefers varnothing over emptyset)
# Maps standard LaTeX command to regional alternative
REGIONAL_SYMBOL_PREFERENCES = {
# Chinese region: prefer varnothing (⌀) over emptyset (∅)
# varnothing has a diagonal line which is clearer in Chinese typography
'emptyset': 'varnothing', # ∅ → ⌀
}
# Unicode symbols that should be kept as-is (NOT converted to LaTeX)
# These are symbols whose LaTeX commands are not supported or render poorly in MathJax.
# By keeping them as Unicode, they render correctly using system fonts.
# This set is the "inverse" of MATHJAX_UNSUPPORTED_TO_UNICODE - same symbols, different direction.
UNICODE_PASSTHROUGH = {
# =========================================================================
# INTEGRAL OPERATORS - Keep as Unicode for MathJax compatibility
# =========================================================================
'∯', # U+222F SURFACE INTEGRAL (oiint)
'∰', # U+2230 VOLUME INTEGRAL (oiiint)
'∱', # U+2231 CLOCKWISE INTEGRAL (intclockwise)
'∲', # U+2232 CLOCKWISE CONTOUR INTEGRAL (varointclockwise)
'∳', # U+2233 ANTICLOCKWISE CONTOUR INTEGRAL (varointctrclockwise)
'⨍', # U+2A0D FINITE PART INTEGRAL (fint)
'⨎', # U+2A0E PATH INTEGRAL (pointint)
'⨏', # U+2A0F INTEGRAL WITH SQUARED OPERATOR (sqint)
'⨐', # U+2A10 CIRCULATION FUNCTION (intlarhk)
'⨑', # U+2A11 INTEGRAL WITH OVERBAR (intbar)
'⨒', # U+2A12 INTEGRAL WITH DOUBLE OVERBAR (intBar)
'⨓', # U+2A13 FINITE PART INTEGRAL WITH OVERBAR (fintbar)
'⨔', # U+2A14 CONTOUR INTEGRAL WITH OVERBAR (ointbar)
'⨕', # U+2A15 CONTOUR INTEGRAL WITH DOUBLE OVERBAR (ointBar)
'⨖', # U+2A16 SURFACE INTEGRAL WITH OVERBAR (oiintbar)
'⨗', # U+2A17 SURFACE INTEGRAL WITH DOUBLE OVERBAR (oiintBar)
# =========================================================================
# BINARY OPERATORS - Keep as Unicode
# =========================================================================
'⋇', # U+22C7 DIVISION TIMES (divideontimes)
'⊛', # U+229B CIRCLED ASTERISK OPERATOR (oast)
'⊚', # U+229A CIRCLED RING OPERATOR (ocirc)
'⧄', # U+29C4 SQUARED SQUARE (boxbox)
'⧅', # U+29C5 SQUARED ASTERISK (boxast)
'⧆', # U+29C6 SQUARED SMALL CIRCLE (boxcirc)
'⧇', # U+29C7 SQUARED BACKSLASH (boxbslash)
'⧈', # U+29C8 SQUARED SLASH (boxslash)
'⋋', # U+22CB LEFT SEMIDIRECT PRODUCT (leftthreetimes)
'⋌', # U+22CC RIGHT SEMIDIRECT PRODUCT (rightthreetimes)
'⊌', # U+228C MULTISET (dotcup)
'⊍', # U+228D MULTISET MULTIPLICATION (cupdot)
# =========================================================================
# ARROWS - Keep as Unicode for consistency
# =========================================================================
'↤', # U+21A4 LEFTWARDS ARROW FROM BAR (mapsfrom)
'⟻', # U+27FB LONG LEFTWARDS ARROW FROM BAR (longmapsfrom)
'⇜', # U+21DC LEFTWARDS SQUIGGLE ARROW (leftsquigarrow)
'⇝', # U+21DD RIGHTWARDS SQUIGGLE ARROW (rightsquigarrow)
# '↫', # U+21AB LEFTWARDS ARROW WITH LOOP (looparrowleft)
# '↬', # U+21AC RIGHTWARDS ARROW WITH LOOP (looparrowright)
# '↢', # U+21A2 LEFTWARDS ARROW WITH TAIL (leftarrowtail)
# '↣', # U+21A3 RIGHTWARDS ARROW WITH TAIL (rightarrowtail)
# '↰', # U+21B0 UPWARDS ARROW WITH TIP LEFTWARDS (Lsh)
# '↱', # U+21B1 UPWARDS ARROW WITH TIP RIGHTWARDS (Rsh)
# '↶', # U+21B6 ANTICLOCKWISE TOP SEMICIRCLE ARROW (curvearrowleft)
# '↷', # U+21B7 CLOCKWISE TOP SEMICIRCLE ARROW (curvearrowright)
# '↺', # U+21BA ANTICLOCKWISE OPEN CIRCLE ARROW (circlearrowleft)
# '↻', # U+21BB CLOCKWISE OPEN CIRCLE ARROW (circlearrowright)
# '⇈', # U+21C8 UPWARDS PAIRED ARROWS (upuparrows)
# '⇊', # U+21CA DOWNWARDS PAIRED ARROWS (downdownarrows)
# '⇅', # U+21C5 UPWARDS ARROW LEFTWARDS OF DOWNWARDS (updownarrows)
# '⇵', # U+21F5 DOWNWARDS ARROW LEFTWARDS OF UPWARDS (downuparrows)
# =========================================================================
# RELATION SYMBOLS - Keep as Unicode
# =========================================================================
'⋘', # U+22D8 VERY MUCH LESS-THAN (lll)
'⋙', # U+22D9 VERY MUCH GREATER-THAN (ggg)
'⪋', # U+2A8B LESS-THAN EQUAL TO OR GREATER-THAN (lesseqgtr)
'⪌', # U+2A8C GREATER-THAN EQUAL TO OR LESS-THAN (gtreqless)
'⪅', # U+2A85 LESS-THAN OR APPROXIMATE (lessapprox)
'⪆', # U+2A86 GREATER-THAN OR APPROXIMATE (gtrapprox)
'⪉', # U+2A89 LESS-THAN AND NOT APPROXIMATE (lnapprox)
'⪊', # U+2A8A GREATER-THAN AND NOT APPROXIMATE (gnapprox)
'⪷', # U+2AB7 PRECEDES ABOVE ALMOST EQUAL TO (precapprox)
'⪸', # U+2AB8 SUCCEEDS ABOVE ALMOST EQUAL TO (succapprox)
'⋞', # U+22DE EQUAL TO OR PRECEDES (curlyeqprec)
'⋟', # U+22DF EQUAL TO OR SUCCEEDS (curlyeqsucc)
# '∽', # U+223D REVERSED TILDE (backsim)
# '⋍', # U+22CD REVERSED TILDE EQUALS (backsimeq)
'≙', # U+2259 ESTIMATES (wedgeq)
'≚', # U+225A EQUIANGULAR TO (veeeq)
'≘', # U+2258 CORRESPONDS TO (arceq)
'≔', # U+2254 COLON EQUALS (coloneqq)
'≕', # U+2255 EQUALS COLON (eqqcolon)
'⩴', # U+2A74 DOUBLE COLON EQUAL (Coloneqq)
'∹', # U+2239 EXCESS (eqcolon)
'≬', # U+226C BETWEEN (between)
# =========================================================================
# BRACKET/DELIMITER SYMBOLS - Keep as Unicode
# =========================================================================
'〚', # U+301A LEFT WHITE SQUARE BRACKET (llbracket)
'〛', # U+301B RIGHT WHITE SQUARE BRACKET (rrbracket)
'⦅', # U+2985 LEFT WHITE PARENTHESIS (llparenthesis)
'⦆', # U+2986 RIGHT WHITE PARENTHESIS (rrparenthesis)
'⦉', # U+2989 Z NOTATION LEFT BINDING BRACKET (Langle)
'⦊', # U+298A Z NOTATION RIGHT BINDING BRACKET (Rangle)
# =========================================================================
# GEOMETRIC AND MISCELLANEOUS SYMBOLS - Keep as Unicode
# =========================================================================
'▱', # U+25B1 WHITE PARALLELOGRAM (parallelogram)
'⋰', # U+22F0 UP RIGHT DIAGONAL ELLIPSIS (iddots)
# '℧', # U+2127 INVERTED OHM SIGN (mho)
# '∁', # U+2201 COMPLEMENT (complement)
'ℶ', # U+2136 BET SYMBOL (beth)
'ℷ', # U+2137 GIMEL SYMBOL (gimel)
'ℸ', # U+2138 DALET SYMBOL (daleth)
'⟀', # U+27C0 THREE DIMENSIONAL ANGLE (lozengeminus)
# =========================================================================
# LOGICAL AND SET OPERATORS - Keep as Unicode
# =========================================================================
# '⫅', # U+2AC5 SUBSET OF ABOVE EQUALS SIGN (subseteqq)
# '⫆', # U+2AC6 SUPERSET OF ABOVE EQUALS SIGN (supseteqq)
# '⫋', # U+2ACB SUBSET OF ABOVE NOT EQUAL TO (subsetneqq)
# '⫌', # U+2ACC SUPERSET OF ABOVE NOT EQUAL TO (supsetneqq)
}