Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
sicmutils ->TeX w/ equate symbol
(ns render
(:require [clojure.string :as s]
[sicmutils.ratio :as r]
[sicmutils.expression.render :refer :all]))
(def ->TeX2
"Convert the given (simplified) expression to TeX format, as a string."
(let [TeX-accent (fn [accent]
(fn [[_ stem]]
(str "\\" accent " " (#'sicmutils.expression.render/maybe-brace (->TeX stem)))))
dot (TeX-accent "dot")
ddot (TeX-accent "ddot")
hat (TeX-accent "hat")
bar (TeX-accent "bar")
vec (TeX-accent "vec")
tilde (TeX-accent "tilde")]
(#'sicmutils.expression.render/make-infix-renderer
;; here we set / to a very low precedence because the fraction bar we will
;; use in the rendering groups things very strongly.
:precedence-map '{= 0, D 9, expt 8, :apply 7, u- 6, * 5, + 3, - 3, / 1}
:parenthesize #(str "\\left(" % "\\right)")
:infix? '#{* + - / expt u- =}
:juxtapose-multiply "\\,"
:rewrite-trig-squares true
:special-handlers
{'expt (fn [[x e]] (str (#'sicmutils.expression.render/maybe-brace x) "^" (#'sicmutils.expression.render/maybe-brace e)))
'partial (fn [ds] (str "\\partial_" (#'sicmutils.expression.render/maybe-brace (s/join "," ds))))
'/ (fn [xs]
(when (= (count xs) 2)
(str "\\frac" (#'sicmutils.expression.render/brace (first xs)) (#'sicmutils.expression.render/brace (second xs)))))
'up (fn [x]
(let [body (->> (map #'sicmutils.expression.render/displaystyle x)
(s/join " \\cr \\cr "))]
(str "\\begin{pmatrix}"
body
"\\end{pmatrix}")))
'down (fn [x]
(let [sep (if *TeX-vertical-down-tuples*
" \\cr \\cr "
"&")
body (->> (map #'sicmutils.expression.render/displaystyle x)
(s/join sep))]
(str "\\begin{bmatrix}"
body
"\\end{bmatrix}")))
'sqrt #(str "\\sqrt " (#'sicmutils.expression.render/maybe-brace (first %)))}
:render-primitive
(fn r [v]
(cond (r/ratio? v)
(str "\\frac" (#'sicmutils.expression.render/brace (r/numerator v)) (#'sicmutils.expression.render/brace (r/denominator v)))
:else
(let [s (str v)]
(cond (#'sicmutils.expression.render/TeX-letters s) (str "\\" s)
(#'sicmutils.expression.render/TeX-map s) (#'sicmutils.expression.render/TeX-map s)
:else (condp re-find s
;; TODO: add support for superscripts
#"(.+)_([0-9a-zA-Zαωθφ]+)$"
:>> (fn [[_ stem subscript]]
(str (#'sicmutils.expression.render/maybe-brace (r stem)) "_" (#'sicmutils.expression.render/maybe-brace (r subscript))))
;; KaTeX doesn't do \dddot.
#"(.+)dotdot$" :>> ddot
#"(.+)dot$" :>> dot
#"(.+)hat$" :>> hat
#"(.+)bar$" :>> bar
#"(.+)vec$" :>> vec
#"(.+)tilde$" :>> tilde
;; wrap it if it's a multiletter variable... unless it looks
;; like a differential. (Too hacky?)
(if (and (symbol? v)
(> (count s) 1)
(not (re-matches #"^d[a-zαωθφ]" s)))
(str "\\mathsf" (#'sicmutils.expression.render/brace s))
v)))))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment