mirror of
https://github.com/journeyman-cc/smeagol.git
synced 2026-04-13 02:05:07 +00:00
A very long way towards extensible formatters
This commit is contained in:
parent
91367e40aa
commit
19a715c4fb
1 changed files with 72 additions and 40 deletions
|
|
@ -6,6 +6,7 @@
|
||||||
[noir.io :as io]
|
[noir.io :as io]
|
||||||
[noir.session :as session]
|
[noir.session :as session]
|
||||||
[markdown.core :as md]
|
[markdown.core :as md]
|
||||||
|
[taoensso.timbre :as timbre]
|
||||||
[smeagol.authenticate :as auth]
|
[smeagol.authenticate :as auth]
|
||||||
[clj-yaml.core :as yaml]
|
[clj-yaml.core :as yaml]
|
||||||
[clojure.data.json :as json]))
|
[clojure.data.json :as json]))
|
||||||
|
|
@ -35,7 +36,7 @@
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Right, doing the data visualisation thing is tricky. Doing it in the
|
;;;; Right, doing the data visualisation thing is tricky. Doing it in the
|
||||||
;;;; pipeline doesn't work, because the md-to-html-string filter messes up
|
;;;; pipeline doesn't work, because the md-to-html-string filter messes up
|
||||||
;;;; both YAML and JSON notation. So we need to extract the visualisation YAML
|
;;;; both YAML and JSON notation. So we need to extract the visualisation
|
||||||
;;;; fragments from the Markdown text and replace them with tokens we will
|
;;;; fragments from the Markdown text and replace them with tokens we will
|
||||||
;;;; recognise afterwards, perform md-to-html-string, and then replace our
|
;;;; recognise afterwards, perform md-to-html-string, and then replace our
|
||||||
;;;; tokens with the transformed visualisation specification.
|
;;;; tokens with the transformed visualisation specification.
|
||||||
|
|
@ -88,6 +89,63 @@
|
||||||
"\n</div>"))
|
"\n</div>"))
|
||||||
|
|
||||||
|
|
||||||
|
;; TODO: This isn't (yet) exactly what I want. The formatters ought to be configurable
|
||||||
|
;; without editing the Smeagol code directly. But it's a long way in the right direction.
|
||||||
|
(def ^:dynamic *formatters*
|
||||||
|
{"vega" process-vega
|
||||||
|
"vis" process-vega
|
||||||
|
"mermaid" process-mermaid})
|
||||||
|
|
||||||
|
|
||||||
|
(defn get-first-token
|
||||||
|
"Return the first space-separated token of this `string`."
|
||||||
|
[^String string]
|
||||||
|
(if string (first (cs/split string #"[^a-zA-Z0-9]+"))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn- process-markdown-fragment
|
||||||
|
"Within the context of `process-text`, process a fragment believed to be markdown.
|
||||||
|
|
||||||
|
As with `process-text`, this function returns a map with two top-level keys:
|
||||||
|
`:inclusions`, a map of constructed keywords to inclusion specifications,
|
||||||
|
and `:text`, an HTML text string with the keywords present where the
|
||||||
|
corresponding inclusion should be inserted."
|
||||||
|
[index result fragments processed]
|
||||||
|
(process-text
|
||||||
|
(+ index 1)
|
||||||
|
result
|
||||||
|
(rest fragments)
|
||||||
|
(cons (first fragments) processed)))
|
||||||
|
|
||||||
|
|
||||||
|
(defn- apply-formatter
|
||||||
|
"Within the context of `process-text`, process a fragment for which an explicit
|
||||||
|
§formatter has been identified.
|
||||||
|
|
||||||
|
As with `process-text`, this function returns a map with two top-level keys:
|
||||||
|
`:inclusions`, a map of constructed keywords to inclusion specifications,
|
||||||
|
and `:text`, an HTML text string with the keywords present where the
|
||||||
|
corresponding inclusion should be inserted."
|
||||||
|
[index result fragments processed fragment token formatter]
|
||||||
|
(let
|
||||||
|
[kw (keyword (str "inclusion-" index))]
|
||||||
|
(process-text
|
||||||
|
(+ index 1)
|
||||||
|
(assoc
|
||||||
|
result
|
||||||
|
:inclusions
|
||||||
|
(assoc
|
||||||
|
(:inclusions result)
|
||||||
|
kw
|
||||||
|
(apply
|
||||||
|
formatter
|
||||||
|
(list
|
||||||
|
(subs fragment (count token))
|
||||||
|
index))))
|
||||||
|
(rest fragments)
|
||||||
|
(cons kw processed))))
|
||||||
|
|
||||||
|
|
||||||
(defn process-text
|
(defn process-text
|
||||||
"Process this `text`, assumed to be markdown potentially containing both local links
|
"Process this `text`, assumed to be markdown potentially containing both local links
|
||||||
and YAML visualisation specifications, and return a map comprising JSON visualisation
|
and YAML visualisation specifications, and return a map comprising JSON visualisation
|
||||||
|
|
@ -99,6 +157,9 @@
|
||||||
([text]
|
([text]
|
||||||
(process-text 0 {:inclusions {}} (cs/split text #"```") '()))
|
(process-text 0 {:inclusions {}} (cs/split text #"```") '()))
|
||||||
([index result fragments processed]
|
([index result fragments processed]
|
||||||
|
(let [fragment (first fragments)
|
||||||
|
first-token (get-first-token fragment)
|
||||||
|
formatter (*formatters* first-token)]
|
||||||
(cond
|
(cond
|
||||||
(empty? fragments)
|
(empty? fragments)
|
||||||
(assoc result :text
|
(assoc result :text
|
||||||
|
|
@ -106,39 +167,10 @@
|
||||||
(md/md-to-html-string
|
(md/md-to-html-string
|
||||||
(cs/join "\n\n" (reverse processed))
|
(cs/join "\n\n" (reverse processed))
|
||||||
:heading-anchors true)))
|
:heading-anchors true)))
|
||||||
;;; TODO: refactor; generalise extension architecture
|
formatter
|
||||||
(clojure.string/starts-with? (first fragments) "vis")
|
(apply-formatter index result fragments processed fragment first-token formatter)
|
||||||
(let [kw (keyword (str "inclusion-" index))]
|
|
||||||
(process-text
|
|
||||||
(+ index 1)
|
|
||||||
(assoc
|
|
||||||
result
|
|
||||||
:inclusions
|
|
||||||
(assoc
|
|
||||||
(:inclusions result)
|
|
||||||
kw
|
|
||||||
(process-vega
|
|
||||||
(subs (first fragments) 3)
|
|
||||||
index)))
|
|
||||||
(rest fragments)
|
|
||||||
(cons kw processed)))
|
|
||||||
(clojure.string/starts-with? (first fragments) "mermaid")
|
|
||||||
(let [kw (keyword (str "inclusion-" index))]
|
|
||||||
(process-text
|
|
||||||
(+ index 1)
|
|
||||||
(assoc
|
|
||||||
result
|
|
||||||
:inclusions
|
|
||||||
(assoc
|
|
||||||
(:inclusions result)
|
|
||||||
kw
|
|
||||||
(process-mermaid
|
|
||||||
(subs (first fragments) 7)
|
|
||||||
index)))
|
|
||||||
(rest fragments)
|
|
||||||
(cons kw processed)))
|
|
||||||
true
|
true
|
||||||
(process-text (+ index 1) result (rest fragments) (cons (first fragments) processed)))))
|
(process-markdown-fragment index result fragments processed)))))
|
||||||
|
|
||||||
|
|
||||||
(defn reintegrate-inclusions
|
(defn reintegrate-inclusions
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue