-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
tex.cljs
91 lines (74 loc) · 2.35 KB
/
tex.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
(ns emmy.portal.tex
"Portal viewer for rendering strings (and any expression that that responds
to [[emmy.expression.render/->TeX]]) as LaTeX
via [KaTeX](https://katex.org/).
To use this viewer, first install the `katex` npm package:
```bash
npm install katex@0.16.7
```
Then install the viewer:
```clojure
(emmy.portal/install! \"emmy/portal/tex.cljs\")
```
The viewer is automatically installed by the functions in [[emmy.portal]]."
(:require [emmy.portal.css :as css]
["katex" :as k]
[portal.ui.api :as p]
[portal.ui.options :as o]
[portal.ui.rpc :as rpc]
["react" :as react]))
(css/inject!
"https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/katex.min.css")
(def viewer-name :emmy.portal/tex)
(def default-options
{:throwOnError false
:displayMode true})
(defn get-opts
"Returns a map of [KaTeX options](https://katex.org/docs/options.html) generated
by merging [[default-options]] with user-supplied options.
To configure this viewer, supply a map of options to [[portal.api/open]] via
the `:emmy.portal/tex` key. See the [KaTeX options
documentation](https://katex.org/docs/options.html) for details on what's
allowed.
For example:
```clojure
(def portal
(portal.api/open
{:emmy.portal/tex
{:macros {\"\\f\" \"#1f(#2)\"}}}))
```"
[]
(let [opts (get (o/use-options) viewer-name {})]
(merge default-options opts)))
(defn tex [_]
(let [opts (clj->js (get-opts))]
(fn [text]
[:span
{:dangerouslySetInnerHTML
{:__html
(k/renderToString text opts)}}])))
(defn expand
"This component is used for any non-string value, and attempts to convert the
value into a string calling [[emmy.expression.render/->TeX]].
There are currently no guards in place, so if you attempt to render something
that isn't supported by Emmy you'll see an error."
[v]
(let [[form set-form!] (react/useState nil)]
(react/useEffect
(fn []
(-> (rpc/call 'emmy.expression.render/->TeX v)
(.then set-form!))
js/undefined)
#js [])
(when form
[tex form])))
(defn show-expr
"Render `x` directly with katex or via `->TeX` and then via katex."
[x]
(if (string? x)
[tex x]
[:f> expand x]))
(p/register-viewer!
{:name viewer-name
:component show-expr
:predicate (constantly true)})