From 52203a49aa544b2c11c96445d8732893160c436b Mon Sep 17 00:00:00 2001 From: Asko Nõmm Date: Tue, 19 Apr 2022 17:50:19 +0300 Subject: WIP #16 Pretty much done. Needs more testing. And new documentation. --- src/clarktown/parsers/bold.clj | 18 ---- src/clarktown/parsers/code_block.clj | 30 ------ src/clarktown/parsers/empty_block.clj | 17 ---- src/clarktown/parsers/heading_block.clj | 72 -------------- src/clarktown/parsers/horizontal_line_block.clj | 16 --- src/clarktown/parsers/inline_code.clj | 21 ---- src/clarktown/parsers/italic.clj | 18 ---- src/clarktown/parsers/link_and_image.clj | 27 ----- src/clarktown/parsers/list_block.clj | 127 ------------------------ src/clarktown/parsers/paragraph_block.clj | 9 -- src/clarktown/parsers/quote_block.clj | 24 ----- src/clarktown/parsers/strikethrough.clj | 18 ---- 12 files changed, 397 deletions(-) delete mode 100644 src/clarktown/parsers/bold.clj delete mode 100644 src/clarktown/parsers/code_block.clj delete mode 100644 src/clarktown/parsers/empty_block.clj delete mode 100644 src/clarktown/parsers/heading_block.clj delete mode 100644 src/clarktown/parsers/horizontal_line_block.clj delete mode 100644 src/clarktown/parsers/inline_code.clj delete mode 100644 src/clarktown/parsers/italic.clj delete mode 100644 src/clarktown/parsers/link_and_image.clj delete mode 100644 src/clarktown/parsers/list_block.clj delete mode 100644 src/clarktown/parsers/paragraph_block.clj delete mode 100644 src/clarktown/parsers/quote_block.clj delete mode 100644 src/clarktown/parsers/strikethrough.clj (limited to 'src/clarktown/parsers') diff --git a/src/clarktown/parsers/bold.clj b/src/clarktown/parsers/bold.clj deleted file mode 100644 index 79579bf..0000000 --- a/src/clarktown/parsers/bold.clj +++ /dev/null @@ -1,18 +0,0 @@ -(ns clarktown.parsers.bold - (:require - [clojure.string :as string])) - - -(defn render - "Renders all occurring bold text as bold." - [block _] - (loop [block block - matches (-> (re-seq #"(\*{2}|\_{2})[^\*|\_](.*?)[^\*|\_](\*{2}|\_{2})" block) - distinct)] - (if (empty? matches) - block - (let [match (ffirst matches) - value (subs match 2 (- (count match) 2)) - replacement (str "" value "")] - (recur (string/replace block match replacement) - (drop 1 matches)))))) diff --git a/src/clarktown/parsers/code_block.clj b/src/clarktown/parsers/code_block.clj deleted file mode 100644 index c6ecfea..0000000 --- a/src/clarktown/parsers/code_block.clj +++ /dev/null @@ -1,30 +0,0 @@ -(ns clarktown.parsers.code-block - (:require - [clojure.string :as string])) - - -(defn is? - "Determines whether we're dealing with a code block." - [block] - (and (string/starts-with? block "```") - (string/ends-with? block "```"))) - - -(defn render - "Renders the code block." - [block _] - (let [language (->> block - (re-find #"\`\`\`(\w+)") - second) - lines (string/split-lines block) - block* (->> (next lines) - (take (- (count lines) 2)) - (string/join \newline)) - code (-> block* - (string/replace #"&" "&") - (string/replace #"<" "<") - (string/replace #">" ">") - string/trim)] - (if language - (str "
" code "
") - (str "
" code "
")))) diff --git a/src/clarktown/parsers/empty_block.clj b/src/clarktown/parsers/empty_block.clj deleted file mode 100644 index 0ed5a08..0000000 --- a/src/clarktown/parsers/empty_block.clj +++ /dev/null @@ -1,17 +0,0 @@ -(ns clarktown.parsers.empty-block - (:require - [clojure.string :as string])) - - -(defn is? - "Determines if the current block is an empty block or not." - [block] - (-> (string/replace block #"\n" "") - string/trim - string/blank?)) - - -(defn render - "Renders an empty block." - [_ _] - "") diff --git a/src/clarktown/parsers/heading_block.clj b/src/clarktown/parsers/heading_block.clj deleted file mode 100644 index def2394..0000000 --- a/src/clarktown/parsers/heading_block.clj +++ /dev/null @@ -1,72 +0,0 @@ -(ns clarktown.parsers.heading-block - (:require - [clojure.string :as string])) - - -(defn is-hashbang-heading? - "Determines whether the given block is a hashbang heading." - [block] - (-> (string/replace block #"\n" "") - string/trim - (string/starts-with? "#"))) - - -(defn is-settext-heading? - "Determines whether the given block is a settext heading." - [block] - (let [lines (-> (string/split-lines block)) - chars (-> (last lines) - string/trim - (string/split #""))] - (and (> (count lines) 1) - (every? #{"-" "="} chars)))) - - -(defn is? - "Determines whether the given block is a heading block." - [block] - (or (is-hashbang-heading? block) - (is-settext-heading? block))) - - -(defn render-hashbang-heading - "Renders the hashbang heading block." - [block] - (let [single-line-block (-> (string/replace block #"\n" "") - string/trim) - size (-> (string/split single-line-block #" ") - first - string/trim - count) - value (->> (string/split single-line-block #" ") - next - (string/join " ") - string/trim)] - (str "" value ""))) - - -(defn render-settext-heading - "Renders the settext heading block." - [block] - (let [lines (string/split-lines block) - value (->> (split-at (- (count lines) 1) lines) - first - (string/join "\n")) - h1? (= "=" (-> (last lines) - string/trim - (string/split #"") - first))] - (if h1? - (str "

" value "

") - (str "

" value "

")))) - - -(render-settext-heading "Hello world\nAnd you too\n===") - - -(defn render - "Renders the heading block." - [block _] - (if (is-hashbang-heading? block) - (render-hashbang-heading block) - (render-settext-heading block))) diff --git a/src/clarktown/parsers/horizontal_line_block.clj b/src/clarktown/parsers/horizontal_line_block.clj deleted file mode 100644 index b1d1e05..0000000 --- a/src/clarktown/parsers/horizontal_line_block.clj +++ /dev/null @@ -1,16 +0,0 @@ -(ns clarktown.parsers.horizontal-line-block - (:require - [clojure.string :as string])) - - -(defn is? - "Determines whether the given block is a horizontal line block." - [block] - (or (= "***" (string/trim block)) - (= "---" (string/trim block)))) - - -(defn render - "Renders the horizontal line block." - [_ _] - "
") diff --git a/src/clarktown/parsers/inline_code.clj b/src/clarktown/parsers/inline_code.clj deleted file mode 100644 index 1de73bf..0000000 --- a/src/clarktown/parsers/inline_code.clj +++ /dev/null @@ -1,21 +0,0 @@ -(ns clarktown.parsers.inline-code - (:require - [clojure.string :as string])) - - -(defn render - "Renders all occurring inline code." - [block _] - (loop [block block - matches (-> (re-seq #"\`.*?\`" block) - distinct)] - (if (empty? matches) - block - (let [match (first matches) - value (-> (subs match 1 (- (count match) 1)) - (string/replace #"&" "&") - (string/replace #"<" "<") - (string/replace #">" ">")) - replacement (str "" value "")] - (recur (string/replace block match replacement) - (drop 1 matches)))))) diff --git a/src/clarktown/parsers/italic.clj b/src/clarktown/parsers/italic.clj deleted file mode 100644 index 915a017..0000000 --- a/src/clarktown/parsers/italic.clj +++ /dev/null @@ -1,18 +0,0 @@ -(ns clarktown.parsers.italic - (:require - [clojure.string :as string])) - - -(defn render - "Renders all occurring italic text as italic." - [block _] - (loop [block block - matches (-> (re-seq #"(\*{1,}?|\_{1,}?)(.*?)(\*{1,}?|\_{1,}?)" block) - distinct)] - (if (empty? matches) - block - (let [match (ffirst matches) - value (subs match 1 (- (count match) 1)) - replacement (str "" value "")] - (recur (string/replace block match replacement) - (drop 1 matches)))))) diff --git a/src/clarktown/parsers/link_and_image.clj b/src/clarktown/parsers/link_and_image.clj deleted file mode 100644 index 3be2efe..0000000 --- a/src/clarktown/parsers/link_and_image.clj +++ /dev/null @@ -1,27 +0,0 @@ -(ns clarktown.parsers.link-and-image - (:require - [clojure.string :as string])) - - -(defn encode-href - [href] - (-> href - (string/replace "_" "_"))) - - -(defn render - "Renders all occurring links and images." - [block _] - (loop [block block - matches (-> (re-seq #"\!?\[([a-zA-Z0-9\-\.\,]+( [a-zA-Z0-9\-\.\,]+)*)\]\((.*?)\)" block) - distinct)] - (if (empty? matches) - block - (let [[whole-match label _ href] (first matches) - image? (string/starts-with? whole-match "!") - image (str "\""") - link (str "" label "")] - (recur (if image? - (string/replace block whole-match image) - (string/replace block whole-match link)) - (drop 1 matches)))))) \ No newline at end of file diff --git a/src/clarktown/parsers/list_block.clj b/src/clarktown/parsers/list_block.clj deleted file mode 100644 index 52f955f..0000000 --- a/src/clarktown/parsers/list_block.clj +++ /dev/null @@ -1,127 +0,0 @@ -(ns clarktown.parsers.list-block - (:require - [clojure.string :as string])) - - -(defn is? - "Determines whether we're dealing with a list block or not." - [block] - (->> (string/trim block) - (re-matches #"(?s)^(\d\.\s|\*{1}\s|\-{1}\s).*$"))) - - -(defn string->indent-n - "Returns the indentation count from left of `str`, which must be - in spaces and not tabs." - [str] - (count (take-while #{\space} str))) - - -(defn compose-items-with-indent-guides - "Composes a vector of maps from given `block` that adds a unique - ID to each line as well as its `indent-n` which is used later - on to determine hierarchies. " - [block] - (->> (string/split-lines block) - (mapv - (fn [line] - {:id (random-uuid) - :indent-n (string->indent-n line) - :value (-> line - string/trim)})))) - - -(defn find-parent-id - "Assuming a 1-level `items`, will attempt to find the parent `id` - of the item at given `index`. Will return `nil` otherwise." - [items index] - (let [indent-n-at-index (:indent-n (nth items index))] - (-> (->> (split-at index items) - first - reverse - (remove #(or (> (:indent-n %) indent-n-at-index) - (= (:indent-n %) indent-n-at-index))) - first - :id)))) - - -(defn compose-items-with-parents - "Composes a 1-level list of items from `block` and adds parent - information to each if they belong to another item. The result - of this is used to build the final data tree." - [block] - (let [items (compose-items-with-indent-guides block)] - (->> items - (map-indexed - (fn [index line] - (merge line {:parent (find-parent-id items index)})))))) - - -(defn add-to-parent - "Recursively scans `items`, which can be multiple levels deep, - and tries to find a home for `item` according to its parent ID." - [items item] - (->> items - (mapv - (fn [i] - (if (= (:id i) (:parent item)) - (if (:items i) - (assoc i :items (concat (:items i) [item])) - (assoc i :items [item])) - (if (:items i) - (assoc i :items (add-to-parent (:items i) item)) - i)))))) - - -(defn compose-item-tree - "Given a `block`, composes a data representation of it based on - the indentation of each line." - [block] - (loop [result [] - items (compose-items-with-parents block)] - (if (empty? items) - result - (let [item (first items) - parent (:parent item) - new-item {:id (:id item) - :value (:value item)}] - (recur (if parent - (add-to-parent result item) - (concat result [new-item])) - (drop 1 items)))))) - - -(defn render-items - "Renders an ordered/un-ordered list hierarchy from given `items`." - [items] - (loop [result "" - inner-items items] - (if (empty? inner-items) - (if (or (string/starts-with? (:value (first items)) "*") - (string/starts-with? (:value (first items)) "-")) - (str "") - (str "
    " result "
")) - (let [inner-item (first inner-items) - value (cond - ; * unordered list - (string/starts-with? (:value inner-item) "*") - (-> (string/replace-first (:value inner-item) "*" "") - string/trim) - ; - unordered list - (string/starts-with? (:value inner-item) "-") - (-> (string/replace-first (:value inner-item) "-" "") - string/trim) - :else - (-> (string/replace-first (:value inner-item) #"\d\." "") - string/trim))] - (recur (if (:items inner-item) - (str result "
  • " value (render-items (:items inner-item)) "
  • ") - (str result "
  • " value "
  • ")) - (drop 1 inner-items)))))) - - -(defn render - "Renders the list block" - [block _] - (-> (compose-item-tree block) - (render-items))) \ No newline at end of file diff --git a/src/clarktown/parsers/paragraph_block.clj b/src/clarktown/parsers/paragraph_block.clj deleted file mode 100644 index 3a7c633..0000000 --- a/src/clarktown/parsers/paragraph_block.clj +++ /dev/null @@ -1,9 +0,0 @@ -(ns clarktown.parsers.paragraph-block - (:require - [clojure.string :as string])) - - -(defn render - "Renders the paragraph block." - [block _] - (str "

    " (string/trim block) "

    ")) diff --git a/src/clarktown/parsers/quote_block.clj b/src/clarktown/parsers/quote_block.clj deleted file mode 100644 index ff2dda8..0000000 --- a/src/clarktown/parsers/quote_block.clj +++ /dev/null @@ -1,24 +0,0 @@ -(ns clarktown.parsers.quote-block - (:require - [clojure.string :as string] - [clarktown.parser :as parser])) - - -(defn is? - "Determines whether the given block is a quote block." - [block] - (-> (string/replace block #"\n" "") - string/trim - (string/starts-with? ">"))) - - -(defn render - "Renders a quote block." - [block parsers] - (let [matches (re-seq #">.*" block) - blocks (->> (for [match matches] - (-> (subs match 1) - string/trim)) - (string/join "\n")) - block (parser/parse blocks parsers)] - (str "
    " block "
    "))) diff --git a/src/clarktown/parsers/strikethrough.clj b/src/clarktown/parsers/strikethrough.clj deleted file mode 100644 index 6f03152..0000000 --- a/src/clarktown/parsers/strikethrough.clj +++ /dev/null @@ -1,18 +0,0 @@ -(ns clarktown.parsers.strikethrough - (:require - [clojure.string :as string])) - - -(defn render - "Renders all occurring strikethrough text." - [block _] - (loop [block block - matches (-> (re-seq #"~~.*?~~" block) - distinct)] - (if (empty? matches) - block - (let [match (first matches) - value (subs match 2 (- (count match) 2)) - replacement (str "" value "")] - (recur (string/replace block match replacement) - (drop 1 matches)))))) -- cgit v1.2.3