SPB Git

spb/wp29_uqo

Public
2.5 KB · 22 lines python
1"""Shared LaTeX escaping with Unicode-to-LaTeX mapping for symbols that appear in task cards and ledgers."""2UNI = {"τ": r"$\tau$", "β": r"$\beta$", "Δ": r"$\Delta$", "α": r"$\alpha$", "ρ": r"$\rho$", "σ": r"$\sigma$", "μ": r"$\mu$", "λ": r"$\lambda$", "θ": r"$\theta$", "ε": r"$\varepsilon$", "γ": r"$\gamma$", "κ": r"$\kappa$", "π": r"$\pi$", "Σ": r"$\Sigma$", "∑": r"$\sum$", "Θ": r"$\Theta$", "φ": r"$\phi$", "ω": r"$\omega$", "δ": r"$\delta$", "η": r"$\eta$", "χ": r"$\chi$",3       "≥": r"$\geq$", "≤": r"$\leq$", "×": r"$\times$", "→": r"$\rightarrow$", "←": r"$\leftarrow$", "⇒": r"$\Rightarrow$", "−": "--", "–": "--", "—": "---", "≈": r"$\approx$", "≠": r"$\neq$", "²": r"$^2$", "³": r"$^3$", "½": r"$\tfrac{1}{2}$", "∈": r"$\in$", "∞": r"$\infty$", "±": r"$\pm$", "′": r"$'$", "√": r"$\surd$", "…": r"\ldots{}", "·": r"$\cdot$", "“": "``", "”": "''", "‘": "`", "’": "'", "✔": "yes", "✓": "yes", "≍": r"$\asymp$", "∧": r"$\wedge$", "≪": r"$\ll$", "≫": r"$\gg$", "°": r"$^\circ$", "ĝ": "g", "ŷ": r"$\hat y$", "β̂": r"$\hat\beta$", "τ̂": r"$\hat\tau$", "p̂": r"$\hat p$", "Δ̂": r"$\hat\Delta$"}4import re, unicodedata5GREEK = {"β": r"\beta", "τ": r"\tau", "Δ": r"\Delta", "α": r"\alpha", "ρ": r"\rho", "σ": r"\sigma", "μ": r"\mu", "λ": r"\lambda", "θ": r"\theta", "γ": r"\gamma", "p": "p", "y": "y", "u": "u", "e": "e"}6def _hat(m):7    base = m.group(1); return "\x00$\\hat{" + GREEK.get(base, base) + "}$\x00"8def tex(s):9    s = unicodedata.normalize("NFD", str(s))10    s = re.sub(r"(.)\u0302", _hat, s)                    # combining circumflex → \hat{}11    s = re.sub(r"[\u0300-\u036f]", "", s)                # drop any other combining mark12    s = unicodedata.normalize("NFC", s)13    for k, v in sorted(UNI.items(), key=lambda kv: -len(kv[0])):14        s = s.replace(k, "\x00" + v + "\x00")   # protect replaced math from the escaping pass15    out = []16    for i, chunk in enumerate(s.split("\x00")):17        if i % 2 == 1: out.append(chunk); continue18        out.append(chunk.replace("\\", "\\textbackslash{}").replace("&", "\\&").replace("%", "\\%").replace("_", "\\_").replace("#", "\\#").replace("$", "\\$").replace("~", "\\textasciitilde{}").replace("^", "\\^{}").replace("<", "\\textless{}").replace(">", "\\textgreater{}"))19    s = "".join(out)20    # any remaining non-latin-1 char → '?' placeholder to keep pdflatex happy (logged)21    return "".join(ch if ord(ch) < 0x2000 or ch in "€" else "?" for ch in s)22
Files · 4f59ed568641ceda6f39552d5cc3a441aa812088
Menu

Theme