module MathRender

Overview

Math rendering helpers shared by the renderers.

Two layers:

Defined in:

math_render.cr

Constant Summary

COMMANDS = {"\\infty" => "∞", "\\int" => "∫", "\\sum" => "∑", "\\prod" => "∏", "\\partial" => "∂", "\\nabla" => "∇", "\\sqrt" => "√", "\\times" => "×", "\\div" => "÷", "\\pm" => "±", "\\cdot" => "⋅", "\\leq" => "≤", "\\geq" => "≥", "\\neq" => "≠", "\\ne" => "≠", "\\approx" => "≈", "\\equiv" => "≡", "\\sim" => "∼", "\\propto" => "∝", "\\rightarrow" => "→", "\\to" => "→", "\\leftarrow" => "←", "\\Rightarrow" => "⇒", "\\Leftarrow" => "⇐", "\\uparrow" => "↑", "\\downarrow" => "↓", "\\ldots" => "…", "\\dots" => "…", "\\cdots" => "⋯", "\\alpha" => "α", "\\beta" => "β", "\\gamma" => "γ", "\\delta" => "δ", "\\epsilon" => "ε", "\\varepsilon" => "ε", "\\zeta" => "ζ", "\\eta" => "η", "\\theta" => "θ", "\\vartheta" => "ϑ", "\\iota" => "ι", "\\kappa" => "κ", "\\lambda" => "λ", "\\mu" => "μ", "\\nu" => "ν", "\\xi" => "ξ", "\\pi" => "π", "\\rho" => "ρ", "\\sigma" => "σ", "\\tau" => "τ", "\\upsilon" => "υ", "\\phi" => "φ", "\\varphi" => "φ", "\\chi" => "χ", "\\psi" => "ψ", "\\omega" => "ω", "\\Gamma" => "Γ", "\\Delta" => "Δ", "\\Theta" => "Θ", "\\Lambda" => "Λ", "\\Xi" => "Ξ", "\\Pi" => "Π", "\\Sigma" => "Σ", "\\Phi" => "Φ", "\\Psi" => "Ψ", "\\Omega" => "Ω", "\\degree" => "°", "\\circ" => "∘", "\\ell" => "ℓ", "\\hbar" => "ℏ", "\\forall" => "∀", "\\exists" => "∃", "\\in" => "∈", "\\notin" => "∉", "\\subset" => "⊂", "\\supset" => "⊃", "\\subseteq" => "⊆", "\\supseteq" => "⊇", "\\cup" => "∪", "\\cap" => "∩", "\\emptyset" => "∅", "\\land" => "∧", "\\lor" => "∨", "\\neg" => "¬", "\\angle" => "∠", "\\perp" => "⊥", "\\parallel" => "∥", "\\quad" => " ", "\\qquad" => "  ", "\\," => " ", "\\;" => " ", "\\:" => " ", "\\ " => " ", "\\{" => "{", "\\}" => "}", "\\_" => "_", "\\^" => "^", "\\$" => "$", "\\&" => "&", "\\#" => "#", "\\%" => "%", "\\\\" => "\n"}

LaTeX commands mapped to Unicode symbols (or HTML-safe entities for the HTML renderer). Keys include the leading backslash; substitution is longest-first.

DISPLAY_MATH = Regex.new("\\$\\$([\\s\\S]*?)\\$\\$")
INLINE_MATH = Regex.new("\\$(?=[^\\s\\d])([^$\\n]*?[^\\s$])\\$(?!\\d)")
PLACEHOLDER = Regex.new("\uE000(\\d+)\uE001")
SEGMENT_SPLIT = Regex.new("(<code[^>]*>[\\s\\S]*?</code>|<pre[^>]*>[\\s\\S]*?</pre>|<[^>]*>)")

Rewrite display ($$...$$) and inline ($...$) math in generated HTML. Content inside code elements and inside tags is left alone, so code spans and attributes never become math. Display math renders as text art in a mono pre block when libtexprintf is available, with a styled Unicode span as fallback; inline math always uses the styled span.

SUBSCRIPT = {'0' => "₀", '1' => "₁", '2' => "₂", '3' => "₃", '4' => "₄", '5' => "₅", '6' => "₆", '7' => "₇", '8' => "₈", '9' => "₉", '+' => "₊", '-' => "₋", '=' => "₌", '(' => "₍", ')' => "₎", 'a' => "ₐ", 'e' => "ₑ", 'o' => "ₒ", 'x' => "ₓ"}
SUPERSCRIPT = {'0' => "⁰", '1' => "¹", '2' => "²", '3' => "³", '4' => "⁴", '5' => "⁵", '6' => "⁶", '7' => "⁷", '8' => "⁸", '9' => "⁹", '+' => "⁺", '-' => "⁻", '=' => "⁼", '(' => "⁽", ')' => "⁾", 'n' => "ⁿ", 'i' => "ⁱ"}

Unicode super/subscripts for the terminal renderer, where HTML sub/sup is not available (single characters only).

Class Method Summary

Class Method Detail

def self.cleanup(s : String) : String #

Drop environment markers and grouping braces that only carry meaning in real math layout.


[View source]
def self.commands_regex : Regex #

[View source]
def self.display_art(latex : String) : String | Nil #

Display art comes from the shim's litepdf_render_math.


[View source]
def self.escape_html(s : String) : String #

Terminal-safe art: escape HTML specials for embedding in HTML.


[View source]
def self.rewrite_html(html : String) : String #

Rewrite display ($$...$$) and inline ($...$) math in generated HTML. Content inside code elements and inside tags is left alone, so code spans and attributes never become math. Display math renders as text art in a mono pre block when libtexprintf is available, with a styled Unicode span as fallback; inline math always uses the styled span. Rendered pieces are held aside behind placeholders so later passes cannot re-process them.


[View source]
def self.rewrite_markdown_math(source : String) : String #

Markdown-source rewrite for the terminal renderer: display math becomes a fenced block holding the rendered art (when available), inline math is converted to Unicode text. Fenced code blocks and inline code spans are skipped: $ inside backticks is code, not math, and rewriting it unbalances the spans and corrupts the parse of everything after it.


[View source]
def self.stylize_html(latex : String) : String #

HTML styling pass: Unicode symbols plus real sub/superscripts. Input is HTML-escaped text from the generated document; the output introduces no unescaped characters.


[View source]
def self.substitute_commands(s : String) : String #

Replace LaTeX commands with their Unicode symbols.


[View source]
def self.unicode(latex : String) : String #

Plain-text pass for the terminal renderer: Unicode symbols plus Unicode super/subscripts where a mapping exists. Entities produced by the command table decode to real characters.


[View source]