在ClojureScript中使用MathJax局部渲染数学公式的问题
Let's break down what's going wrong here and fix it step by step!
First: Fix the Typo and Correct the Queue Call
Your initial ClojureScript code has a critical case-sensitive typo: you wrote "TypeSet" instead of "Typeset" (note the lowercase 's'). MathJax's method name is strict about this, which is why your code ran without errors but didn’t produce any output.
Additionally, MathJax expects a native JavaScript array for the queue command—ClojureScript’s persistent vector won’t work here. Use #js to create a JS array directly. Here’s the corrected function:
(defn typeset-latex [dom-element] (when dom-element ; Guard against nil if the element doesn't exist (.Queue js/MathJax.Hub #js ["Typeset" js/MathJax.Hub dom-element])))
If you prefer to pass an element ID instead of the DOM node itself, modify the function to fetch the element first:
(defn typeset-latex-by-id [element-id] (let [dom-element (.getElementById js/document element-id)] (when dom-element (.Queue js/MathJax.Hub #js ["Typeset" js/MathJax.Hub dom-element]))))
Fixing the js* Macro Error
Your js* call failed because you passed a string ("mde-preview-id") instead of the actual DOM element. MathJax can’t process a string as a typesetting target—you need to pass the DOM node itself. Here’s the corrected version:
(js* "MathJax.Hub.Queue([\"Typeset\", MathJax.Hub, document.getElementById('mde-preview-id')]);")
Configuring Externs for Optimized Builds
When using ClojureScript’s advanced compilation (optimized production builds), the Closure Compiler will minify and rename global variables/methods unless you explicitly preserve them. For MathJax, create an externs file to protect its API:
- Create an externs file (e.g.,
resources/externs/mathjax.externs.js) with this content:
var MathJax = {}; MathJax.Hub = {}; MathJax.Hub.Queue = function() {}; // Add more methods if you use other MathJax features MathJax.Hub.Typeset = function() {};
- Link the externs file in your build config:
- For Leiningen (
project.clj)::cljsbuild { :builds [{ :id "production" :source-paths ["src/cljs"] :compiler { :output-to "target/public/js/main.js" :optimizations :advanced :externs ["resources/externs/mathjax.externs.js"] ; Optional: Disable externs validation warnings if needed :closure-warnings {:externs-validation :off} } }] } - For shadow-cljs (
shadow-cljs.edn)::builds { :app { :target :browser :output-dir "public/js" :compiler-options { :externs ["resources/externs/mathjax.externs.js"] } } } - For cljs.main (deps.edn):
:aliases { :prod {:main-opts ["-m" "cljs.main" "--optimizations" "advanced" "--externs" "resources/externs/mathjax.externs.js" "--compile" "your.app.namespace"]} }
- For Leiningen (
This tells the Closure Compiler to leave MathJax.Hub and its core methods untouched during minification.
内容的提问来源于stack exchange,提问作者clartaq

