1
1
; ; # 🧩 Parsing
2
2
(ns nextjournal.markdown.impl
3
3
(:require [" /js/markdown" :as md]
4
- [" markdown-it/lib/token" :as Token]
5
4
[applied-science.js-interop :as j]
6
5
[clojure.zip :as z]
7
6
[nextjournal.markdown.utils :as u]))
8
7
9
- (extend-type Token
10
- ILookup
11
- (-lookup
12
- ([this key] (j/get this key))
13
- ([this key not-found]
14
- (js/console.log :ilookup/not-found this key not-found)
15
- (j/get this key not-found))))
16
-
17
- (defn hlevel [{:as _token hn :tag }] (when (string? hn) (some-> (re-matches #"h([\d ])" hn) second js/parseInt)))
8
+ (defn hlevel [^js token]
9
+ (let [hn (.-tag token)]
10
+ (when (string? hn) (some-> (re-matches #"h([\d ])" hn) second js/parseInt))))
18
11
19
12
; ; leaf nodes
20
13
; ; TODO: use from utils
62
55
63
56
; ; region token handlers
64
57
(declare apply-tokens )
65
- (defmulti apply-token (fn [_doc token] (: type token)))
58
+ (defmulti apply-token (fn [_doc ^js token] (.- type token)))
66
59
(defmethod apply-token :default [doc token]
67
60
(prn :apply-token/unknown-type {:token token})
68
61
doc )
74
67
75
68
; ; for building the TOC we just care about headings at document top level (not e.g. nested under lists) ⬆
76
69
77
- (defmethod apply-token " paragraph_open" [doc { :as _token :keys [hidden]} ]
70
+ (defmethod apply-token " paragraph_open" [doc ^js token ]
78
71
; ; no trace of tight vs loose on list nodes
79
72
; ; markdown-it passes this info directly to paragraphs via this `hidden` key
80
- (open-node doc (if hidden :plain :paragraph )))
73
+ (open-node doc (if ( .- hidden token) :plain :paragraph )))
81
74
82
75
(defmethod apply-token " paragraph_close" [doc _token] (close-node doc))
83
76
84
- (defmethod apply-token " bullet_list_open" [doc {{:as attrs :keys [has-todos]} :attrs }] (open-node doc (if has-todos :todo-list :bullet-list ) attrs))
77
+ (defmethod apply-token " bullet_list_open" [doc ^js token]
78
+ (let [attrs (.-attrs token)
79
+ has-todos (:has-todos attrs)]
80
+ (open-node doc (if has-todos :todo-list :bullet-list ) attrs)))
81
+
85
82
(defmethod apply-token " bullet_list_close" [doc _token] (close-node doc))
86
83
87
- (defmethod apply-token " ordered_list_open" [doc { :keys [attrs]}] (open-node doc :numbered-list attrs))
84
+ (defmethod apply-token " ordered_list_open" [doc ^js token] (open-node doc :numbered-list ( .- attrs token) ))
88
85
(defmethod apply-token " ordered_list_close" [doc _token] (close-node doc))
89
86
90
- (defmethod apply-token " list_item_open" [doc {{:as attrs :keys [todo]} :attrs }] (open-node doc (if todo :todo-item :list-item ) attrs))
87
+ (defmethod apply-token " list_item_open" [doc ^js token]
88
+ (let [attrs (.-attrs token)
89
+ todo (:todo attrs)]
90
+ (open-node doc (if todo :todo-item :list-item ) attrs)))
91
91
(defmethod apply-token " list_item_close" [doc _token] (close-node doc))
92
92
93
- (defmethod apply-token " math_block" [doc {text :content } ] (push-node doc (block-formula text )))
93
+ (defmethod apply-token " math_block" [doc ^js token ] (push-node doc (block-formula ( .-content token) )))
94
94
(defmethod apply-token " math_block_end" [doc _token] doc )
95
95
96
96
(defmethod apply-token " hr" [doc _token] (push-node doc {:type :ruler }))
106
106
(fn [loc]
107
107
(-> loc (z/edit dissoc :content ) z/up)))))
108
108
109
- (defmethod apply-token " code_block" [doc {:as _token c :content }]
110
- (-> doc
111
- (open-node :code )
112
- (push-node (text-node c))
113
- close-node))
114
-
115
- (defmethod apply-token " fence" [doc {:as _token i :info c :content }]
116
- (-> doc
117
- (open-node :code {} (assoc (u/parse-fence-info i) :info i))
118
- (push-node (text-node c))
119
- close-node))
109
+ (defmethod apply-token " code_block" [doc ^js token]
110
+ (let [c (.-content token)]
111
+ (-> doc
112
+ (open-node :code )
113
+ (push-node (text-node c))
114
+ close-node)))
115
+
116
+ (defmethod apply-token " fence" [doc ^js token]
117
+ (let [c (.-content token)
118
+ i (.-info token)]
119
+ (-> doc
120
+ (open-node :code {} (assoc (u/parse-fence-info i) :info i))
121
+ (push-node (text-node c))
122
+ close-node)))
120
123
121
124
(defn footnote-label [{:as _ctx ::keys [footnote-offset]} token]
122
125
; ; TODO: consider initial offset in case we're parsing multiple inputs
148
151
(defmethod apply-token " footnote_close" [ctx _token]
149
152
(-> ctx (u/update-current-loc z/up)))
150
153
151
- (defmethod apply-token " footnote_block_open" [ctx token ]
154
+ (defmethod apply-token " footnote_block_open" [ctx _token ]
152
155
; ; store footnotes at a top level `:footnote` key
153
156
(assoc ctx ::root :footnotes ))
154
157
183
186
(defmethod apply-token " thead_close" [doc _token] (close-node doc))
184
187
(defmethod apply-token " tr_open" [doc _token] (open-node doc :table-row ))
185
188
(defmethod apply-token " tr_close" [doc _token] (close-node doc))
186
- (defmethod apply-token " th_open" [doc token] (open-node doc :table-header (: attrs token)))
189
+ (defmethod apply-token " th_open" [doc ^js token] (open-node doc :table-header (.- attrs token)))
187
190
(defmethod apply-token " th_close" [doc _token] (close-node doc))
188
191
(defmethod apply-token " tbody_open" [doc _token] (open-node doc :table-body ))
189
192
(defmethod apply-token " tbody_close" [doc _token] (close-node doc))
190
- (defmethod apply-token " td_open" [doc token] (open-node doc :table-data (: attrs token)))
193
+ (defmethod apply-token " td_open" [doc ^js token] (open-node doc :table-data (.- attrs token)))
191
194
(defmethod apply-token " td_close" [doc _token] (close-node doc))
192
195
193
196
(comment
211
214
_this #should be a tag_, but this [_actually #foo shouldnt_](/bar/) is not."
212
215
(parse (update empty-doc :text-tokenizers conj (u/normalize-tokenizer u/hashtag-tokenizer)))))
213
216
214
- (defmethod apply-token " text" [ctx { :keys [content]} ]
215
- (u/handle-text-token ctx content))
217
+ (defmethod apply-token " text" [ctx ^js token ]
218
+ (u/handle-text-token ctx ( .- content token) ))
216
219
217
220
(comment
218
221
(def mustache (u/normalize-tokenizer {:regex #"\{\{ ([^\{ ]+)\}\} " :handler (fn [m] {:type :eval :text (m 1 )})}))
@@ -221,17 +224,20 @@ _this #should be a tag_, but this [_actually #foo shouldnt_](/bar/) is not."
221
224
" foo [[bar]] dang #hashy taggy [[what]] #dangy foo [[great]] and {{eval}} me" ))
222
225
223
226
; ; inlines
224
- (defmethod apply-token " inline" [doc { :as _token ts :children } ] (apply-tokens doc ts ))
225
- (defmethod apply-token " math_inline" [doc {text :content } ] (push-node doc (formula text )))
226
- (defmethod apply-token " math_inline_double" [doc {text :content } ] (push-node doc (formula text )))
227
+ (defmethod apply-token " inline" [doc ^js token ] (apply-tokens doc ( .-children token) ))
228
+ (defmethod apply-token " math_inline" [doc ^js token ] (push-node doc (formula ( .-content token) )))
229
+ (defmethod apply-token " math_inline_double" [doc ^js token ] (push-node doc (formula ( .-content token) )))
227
230
228
231
; ; https://spec.commonmark.org/0.30/#softbreak
229
232
(defmethod apply-token " softbreak" [doc _token] (push-node doc {:type :softbreak }))
230
233
; ; https://spec.commonmark.org/0.30/#hard-line-break
231
234
(defmethod apply-token " hardbreak" [doc _token] (push-node doc {:type :hardbreak }))
232
235
233
236
; ; images
234
- (defmethod apply-token " image" [doc {:keys [attrs children]}] (-> doc (open-node :image attrs) (apply-tokens children) close-node))
237
+ (defmethod apply-token " image" [doc ^js token]
238
+ (let [attrs (.-attrs token)
239
+ children (.-children token)]
240
+ (-> doc (open-node :image attrs) (apply-tokens children) close-node)))
235
241
236
242
; ; marks
237
243
(defmethod apply-token " em_open" [doc _token] (open-node doc :em ))
@@ -240,9 +246,16 @@ _this #should be a tag_, but this [_actually #foo shouldnt_](/bar/) is not."
240
246
(defmethod apply-token " strong_close" [doc _token] (close-node doc))
241
247
(defmethod apply-token " s_open" [doc _token] (open-node doc :strikethrough ))
242
248
(defmethod apply-token " s_close" [doc _token] (close-node doc))
243
- (defmethod apply-token " link_open" [doc token] (open-node doc :link (: attrs token)))
249
+ (defmethod apply-token " link_open" [doc ^js token] (open-node doc :link (.- attrs token)))
244
250
(defmethod apply-token " link_close" [doc _token] (close-node doc))
245
- (defmethod apply-token " code_inline" [doc {text :content }] (-> doc (open-node :monospace ) (push-node (text-node text)) close-node))
251
+ (defmethod apply-token " code_inline" [doc ^js token] (-> doc (open-node :monospace ) (push-node (text-node (.-content token))) close-node))
252
+
253
+ ; ; html
254
+ (defmethod apply-token " html_inline" [doc token]
255
+ (-> doc (u/update-current-loc z/append-child {:type :html-inline :content [(text-node (j/get token :content ))]})))
256
+
257
+ (defmethod apply-token " html_block" [doc token]
258
+ (-> doc (u/update-current-loc z/append-child {:type :html-block :content [(text-node (j/get token :content ))]})))
246
259
247
260
; ; html
248
261
(defmethod apply-token " html_inline" [doc token]
0 commit comments