|
|
@@ -20,152 +20,207 @@
|
|
|
|
|
|
(str (hiccup-without-style hiccup))))
|
|
|
|
|
|
+(def allowed-tags
|
|
|
+ #{:address, :article, :aside, :footer, :header,
|
|
|
+ :h1, :h2, :h3, :h4, :h5, :h6, :hgroup,
|
|
|
+ :main, :nav, :section,
|
|
|
+ :blockquote, :dd, :div, :dl, :dt, :figcaption, :figure,
|
|
|
+ :hr, :li, :ol, :p, :pre, :ul,
|
|
|
+ :a, :abbr, :b, :bdi, :bdo, :br, :cite, :code, :data, :dfn,
|
|
|
+ :em, :i, :kbd, :mark, :q,
|
|
|
+ :rb, :rp, :rt, :rtc, :ruby,
|
|
|
+ :s, :samp, :small, :span, :strong, :sub, :sup, :time, :u, :var, :wbr,
|
|
|
+ :caption, :col, :colgroup, :table, :tbody, :td, :tfoot, :th,
|
|
|
+ :thead, :tr
|
|
|
+ :body :html})
|
|
|
+
|
|
|
(defn ^:large-vars/cleanup-todo hiccup->doc-inner
|
|
|
- [format hiccup]
|
|
|
- (let [transform-fn (fn [hiccup]
|
|
|
- (hiccup->doc-inner format hiccup))
|
|
|
- block-pattern (config/get-block-pattern format)
|
|
|
- map-join (fn [children] (apply str (map transform-fn children)))
|
|
|
+ [format hiccup opts]
|
|
|
+ (let [transform-fn (fn [hiccup opts]
|
|
|
+ (hiccup->doc-inner format hiccup opts))
|
|
|
+ block-pattern (if (= format :markdown)
|
|
|
+ "#"
|
|
|
+ (config/get-block-pattern format))
|
|
|
+ map-join (fn [children] (apply str (map #(transform-fn % opts) children)))
|
|
|
block-transform (fn [level children]
|
|
|
(str (apply str (repeat level block-pattern))
|
|
|
" "
|
|
|
- (->> (map transform-fn children)
|
|
|
+ (->> (map #(transform-fn % opts) children)
|
|
|
(string/join " "))
|
|
|
"\n"))
|
|
|
- emphasis-transform (fn [tag _attrs children]
|
|
|
- (let [pattern (cond
|
|
|
+ emphasis-transform (fn [tag attrs children]
|
|
|
+ (let [style (:style attrs)
|
|
|
+ [bold? italic? underline? strike-through? mark?]
|
|
|
+ (when style
|
|
|
+ [(or (string/includes? style "font-weight:700")
|
|
|
+ (string/includes? style "font-weight:600"))
|
|
|
+ (string/includes? style "font-style:italic")
|
|
|
+ (string/includes? style "text-decoration:underline")
|
|
|
+ (string/includes? style "text-decoration:line-through")
|
|
|
+ (string/includes? style "background-color:#")])
|
|
|
+ pattern (cond
|
|
|
(contains? #{:b :strong} tag)
|
|
|
- (config/get-bold format)
|
|
|
+ (when-not (and style (string/includes? style "font-weight:normal"))
|
|
|
+ (config/get-bold format))
|
|
|
(contains? #{:i :em} tag)
|
|
|
- (config/get-italic format)
|
|
|
+ (when-not (and style (string/includes? style "font-style:normal"))
|
|
|
+ (config/get-italic format))
|
|
|
(contains? #{:ins} tag)
|
|
|
- (config/get-underline format)
|
|
|
+ (when-not (and style (string/includes? style "text-decoration:normal"))
|
|
|
+ (config/get-underline format))
|
|
|
(contains? #{:del} tag)
|
|
|
- (config/get-strike-through format)
|
|
|
+ (when-not (and style (string/includes? style "text-decoration:normal"))
|
|
|
+ (config/get-strike-through format))
|
|
|
(contains? #{:mark} tag)
|
|
|
- (config/get-highlight format)
|
|
|
+ (when-not (and style (string/includes? style "background-color:transparent"))
|
|
|
+ (config/get-highlight format))
|
|
|
+ (and (contains? #{:span} tag)
|
|
|
+ (not (every? string/blank? children)))
|
|
|
+ (remove nil?
|
|
|
+ [(when bold? (config/get-bold format))
|
|
|
+ (when italic? (config/get-italic format))
|
|
|
+ (when underline? (config/get-underline format))
|
|
|
+ (when strike-through? (config/get-strike-through format))
|
|
|
+ (when mark? (config/get-highlight format))])
|
|
|
:else
|
|
|
- nil)]
|
|
|
- (str pattern (map-join children) pattern)))
|
|
|
+ nil)
|
|
|
+ children' (map-join children)]
|
|
|
+ (when-not (string/blank? children')
|
|
|
+ (str (if (string? pattern) pattern (apply str pattern))
|
|
|
+ children'
|
|
|
+ (if (string? pattern) pattern (apply str (reverse pattern)))))))
|
|
|
wrapper (fn [tag content]
|
|
|
- (cond
|
|
|
- (contains? #{:p :hr :ul :ol :dl :table :pre :blockquote :aside :canvas
|
|
|
- :center :figure :figcaption :fieldset :div :footer
|
|
|
- :header} tag)
|
|
|
- (str "\n\n" content "\n\n")
|
|
|
+ (let [content (cond
|
|
|
+ (not (contains? allowed-tags tag))
|
|
|
+ nil
|
|
|
+
|
|
|
+ (contains? #{:comment :head :style :xml} tag)
|
|
|
+ nil
|
|
|
+
|
|
|
+ (and (= tag :p) (:in-table? opts))
|
|
|
+ content
|
|
|
|
|
|
- (contains? #{:thead :tr :li} tag)
|
|
|
- (str content "\n")
|
|
|
+ (contains? #{:p :hr :ul :ol :dl :table :pre :blockquote :aside :canvas
|
|
|
+ :center :figure :figcaption :fieldset :div :footer
|
|
|
+ :header} tag)
|
|
|
+ (str "\n\n" content "\n\n")
|
|
|
|
|
|
- :else
|
|
|
- content))
|
|
|
+ (contains? #{:thead :tr :li} tag)
|
|
|
+ (str content "\n")
|
|
|
+
|
|
|
+ :else
|
|
|
+ content)]
|
|
|
+ (some-> content
|
|
|
+ (string/replace "<!--StartFragment-->" "")
|
|
|
+ (string/replace "<!--EndFragment-->" ""))))
|
|
|
single-hiccup-transform
|
|
|
(fn [x]
|
|
|
(cond
|
|
|
(vector? x)
|
|
|
(let [[tag attrs & children] x
|
|
|
result (match tag
|
|
|
- :head nil
|
|
|
- :h1 (block-transform 1 children)
|
|
|
- :h2 (block-transform 2 children)
|
|
|
- :h3 (block-transform 3 children)
|
|
|
- :h4 (block-transform 4 children)
|
|
|
- :h5 (block-transform 5 children)
|
|
|
- :h6 (block-transform 6 children)
|
|
|
- :a (let [href (:href attrs)
|
|
|
- label (map-join children)
|
|
|
- has-img-tag? (util/safe-re-find #"\[:img" (str x))]
|
|
|
- (if has-img-tag?
|
|
|
- (export-hiccup x)
|
|
|
- (case format
|
|
|
- :markdown (util/format "[%s](%s)" label href)
|
|
|
- :org (util/format "[[%s][%s]]" href label)
|
|
|
- nil)))
|
|
|
- :img (let [src (:src attrs)
|
|
|
- alt (:alt attrs)]
|
|
|
- (case format
|
|
|
- :markdown (util/format "" alt src)
|
|
|
- :org (util/format "[[%s][%s]]" src alt)
|
|
|
- nil))
|
|
|
- :p (util/format "%s"
|
|
|
- (map-join children))
|
|
|
-
|
|
|
- :hr (config/get-hr format)
|
|
|
-
|
|
|
- (_ :guard #(contains? #{:b :strong
|
|
|
- :i :em
|
|
|
- :ins
|
|
|
- :del
|
|
|
- :mark} %))
|
|
|
- (emphasis-transform tag attrs children)
|
|
|
-
|
|
|
- :code (if @*inside-pre?
|
|
|
- (map-join children)
|
|
|
- (let [pattern (config/get-code format)]
|
|
|
- (str " "
|
|
|
- (str pattern (first children) pattern)
|
|
|
- " ")))
|
|
|
-
|
|
|
- :pre
|
|
|
- (do
|
|
|
- (reset! *inside-pre? true)
|
|
|
- (let [content (string/trim (doall (map-join children)))]
|
|
|
- (reset! *inside-pre? false)
|
|
|
- (case format
|
|
|
- :markdown (if (util/starts-with? content "```")
|
|
|
- content
|
|
|
- (str "```\n" content "\n```"))
|
|
|
- :org (if (util/starts-with? content "#+BEGIN_SRC")
|
|
|
+ :head nil
|
|
|
+ :h1 (block-transform 1 children)
|
|
|
+ :h2 (block-transform 2 children)
|
|
|
+ :h3 (block-transform 3 children)
|
|
|
+ :h4 (block-transform 4 children)
|
|
|
+ :h5 (block-transform 5 children)
|
|
|
+ :h6 (block-transform 6 children)
|
|
|
+ :a (let [href (:href attrs)
|
|
|
+ label (or (map-join children) "")
|
|
|
+ has-img-tag? (util/safe-re-find #"\[:img" (str x))]
|
|
|
+ (if has-img-tag?
|
|
|
+ (export-hiccup x)
|
|
|
+ (case format
|
|
|
+ :markdown (util/format "[%s](%s)" label href)
|
|
|
+ :org (util/format "[[%s][%s]]" href label)
|
|
|
+ nil)))
|
|
|
+ :img (let [src (:src attrs)
|
|
|
+ alt (or (:alt attrs) "")]
|
|
|
+ (case format
|
|
|
+ :markdown (util/format "" alt src)
|
|
|
+ :org (util/format "[[%s][%s]]" src alt)
|
|
|
+ nil))
|
|
|
+ :p (util/format "%s"
|
|
|
+ (map-join children))
|
|
|
+
|
|
|
+ :hr (config/get-hr format)
|
|
|
+
|
|
|
+ (_ :guard #(contains? #{:b :strong
|
|
|
+ :i :em
|
|
|
+ :ins
|
|
|
+ :del
|
|
|
+ :mark
|
|
|
+ :span} %))
|
|
|
+ (emphasis-transform tag attrs children)
|
|
|
+
|
|
|
+ :code (if @*inside-pre?
|
|
|
+ (map-join children)
|
|
|
+ (let [pattern (config/get-code format)]
|
|
|
+ (str " "
|
|
|
+ (str pattern (first children) pattern)
|
|
|
+ " ")))
|
|
|
+
|
|
|
+ :pre
|
|
|
+ (do
|
|
|
+ (reset! *inside-pre? true)
|
|
|
+ (let [content (string/trim (doall (map-join children)))]
|
|
|
+ (reset! *inside-pre? false)
|
|
|
+ (case format
|
|
|
+ :markdown (if (util/starts-with? content "```")
|
|
|
content
|
|
|
- (util/format "#+BEGIN_SRC\n%s\n#+END_SRC" content))
|
|
|
- nil)))
|
|
|
-
|
|
|
- :blockquote
|
|
|
- (case format
|
|
|
- :markdown (str "> " (map-join children))
|
|
|
- :org (util/format "#+BEGIN_QUOTE\n%s\n#+END_QUOTE" (map-join children))
|
|
|
- nil)
|
|
|
-
|
|
|
- :li
|
|
|
- (str "- " (map-join children))
|
|
|
-
|
|
|
- :dt
|
|
|
- (case format
|
|
|
- :org (str "- " (map-join children) " ")
|
|
|
- :markdown (str (map-join children) "\n")
|
|
|
- nil)
|
|
|
-
|
|
|
- :dd
|
|
|
- (case format
|
|
|
- :markdown (str ": " (map-join children) "\n")
|
|
|
- :org (str ":: " (map-join children) "\n")
|
|
|
- nil)
|
|
|
-
|
|
|
- :thead
|
|
|
- (case format
|
|
|
- :markdown (let [columns (count (last (first children)))]
|
|
|
- (str
|
|
|
- (map-join children)
|
|
|
- (str "| " (string/join " | "
|
|
|
- (repeat columns "----"))
|
|
|
- " |")))
|
|
|
- :org (let [columns (count (last (first children)))]
|
|
|
+ (str "```\n" content "\n```"))
|
|
|
+ :org (if (util/starts-with? content "#+BEGIN_SRC")
|
|
|
+ content
|
|
|
+ (util/format "#+BEGIN_SRC\n%s\n#+END_SRC" content))
|
|
|
+ nil)))
|
|
|
+
|
|
|
+ :blockquote
|
|
|
+ (case format
|
|
|
+ :markdown (str "> " (map-join children))
|
|
|
+ :org (util/format "#+BEGIN_QUOTE\n%s\n#+END_QUOTE" (map-join children))
|
|
|
+ nil)
|
|
|
+
|
|
|
+ :li
|
|
|
+ (str "- " (map-join children))
|
|
|
+
|
|
|
+ :dt
|
|
|
+ (case format
|
|
|
+ :org (str "- " (map-join children) " ")
|
|
|
+ :markdown (str (map-join children) "\n")
|
|
|
+ nil)
|
|
|
+
|
|
|
+ :dd
|
|
|
+ (case format
|
|
|
+ :markdown (str ": " (map-join children) "\n")
|
|
|
+ :org (str ":: " (map-join children) "\n")
|
|
|
+ nil)
|
|
|
+
|
|
|
+ :thead
|
|
|
+ (case format
|
|
|
+ :markdown (let [columns (count (last (first children)))]
|
|
|
(str
|
|
|
(map-join children)
|
|
|
- (str "|" (string/join "+"
|
|
|
- (repeat columns "----"))
|
|
|
- "|")))
|
|
|
- nil)
|
|
|
- :tr
|
|
|
- (str "| "
|
|
|
- (->> (map transform-fn children)
|
|
|
- (string/join " | "))
|
|
|
- " |")
|
|
|
-
|
|
|
- (_ :guard #(contains? #{:aside :center :figure :figcaption :fieldset :footer :header} %))
|
|
|
- (export-hiccup x)
|
|
|
-
|
|
|
- :else (map-join children))]
|
|
|
+ (str "| " (string/join " | "
|
|
|
+ (repeat columns "----"))
|
|
|
+ " |")))
|
|
|
+ :org (let [columns (count (last (first children)))]
|
|
|
+ (str
|
|
|
+ (map-join children)
|
|
|
+ (str "|" (string/join "+"
|
|
|
+ (repeat columns "----"))
|
|
|
+ "|")))
|
|
|
+ nil)
|
|
|
+ :tr
|
|
|
+ (str "| "
|
|
|
+ (->> (map #(transform-fn % (assoc opts :in-table? true)) children)
|
|
|
+ (string/join " | "))
|
|
|
+ " |")
|
|
|
+
|
|
|
+ (_ :guard #(contains? #{:aside :center :figure :figcaption :fieldset :footer :header} %))
|
|
|
+ (export-hiccup x)
|
|
|
+
|
|
|
+ :else (map-join children))]
|
|
|
(wrapper tag result))
|
|
|
|
|
|
(string? x)
|
|
|
@@ -181,7 +236,7 @@
|
|
|
|
|
|
(defn hiccup->doc
|
|
|
[format hiccup]
|
|
|
- (let [s (hiccup->doc-inner format hiccup)]
|
|
|
+ (let [s (hiccup->doc-inner format hiccup {})]
|
|
|
(if (string/blank? s)
|
|
|
""
|
|
|
(-> s
|
|
|
@@ -196,7 +251,7 @@
|
|
|
(goog.string.unescapeEntities f)
|
|
|
f)) hiccup))
|
|
|
|
|
|
-(defn parse
|
|
|
+(defn convert
|
|
|
[format html]
|
|
|
(when-not (string/blank? html)
|
|
|
(let [hiccup (hickory/as-hiccup (hickory/parse html))
|