summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAsko Nõmm <ano@ano.ee>2022-05-11 20:42:30 +0300
committerAsko Nõmm <ano@ano.ee>2022-05-11 20:42:30 +0300
commit7c3eba77fd3de0e108efba94018233a57e66989e (patch)
treeae7e3c28a7b097d9dffd60a005c96fdb9758f039 /src
parent94c1c0ca639f55ff9073cb1fdf2ad6015bb6bae1 (diff)
Implement indented code blocks.
Diffstat (limited to 'src')
-rw-r--r--src/clarktown/correctors.clj3
-rw-r--r--src/clarktown/correctors/atx_heading_block.clj2
-rw-r--r--src/clarktown/correctors/indented_code_block.clj57
-rw-r--r--src/clarktown/engine.clj8
-rw-r--r--src/clarktown/matchers/indented_code_block.clj10
-rw-r--r--src/clarktown/parsers.clj10
-rw-r--r--src/clarktown/renderers/indented_code_block.clj17
7 files changed, 101 insertions, 6 deletions
diff --git a/src/clarktown/correctors.clj b/src/clarktown/correctors.clj
index 6b7cc1c..cd5e7e8 100644
--- a/src/clarktown/correctors.clj
+++ b/src/clarktown/correctors.clj
@@ -1,6 +1,7 @@
(ns clarktown.correctors
(:require
[clarktown.correctors.fenced-code-block :as fenced-code-block]
+ [clarktown.correctors.indented-code-block :as indented-code-block]
[clarktown.correctors.atx-heading-block :as atx-heading-block]
[clarktown.correctors.list-block :as list-block]))
@@ -10,10 +11,12 @@
default-block-separation-correctors
{:newline-above
[fenced-code-block/newline-above?
+ indented-code-block/newline-above?
atx-heading-block/newline-above?
list-block/newline-above?]
:newline-below
[fenced-code-block/newline-below?
+ indented-code-block/newline-below?
atx-heading-block/newline-below?
list-block/newline-below?]})
diff --git a/src/clarktown/correctors/atx_heading_block.clj b/src/clarktown/correctors/atx_heading_block.clj
index 6668700..5a5f713 100644
--- a/src/clarktown/correctors/atx_heading_block.clj
+++ b/src/clarktown/correctors/atx_heading_block.clj
@@ -20,7 +20,7 @@
there's no empty newline above, we need to create one, and
so this function must then return `true`."
[lines line index]
- (and (is-atx-heading? (string/trim line))
+ (and (is-atx-heading? line)
(> index 0)
(not (= (-> (nth lines (- index 1))
string/trim) ""))
diff --git a/src/clarktown/correctors/indented_code_block.clj b/src/clarktown/correctors/indented_code_block.clj
new file mode 100644
index 0000000..47deeb7
--- /dev/null
+++ b/src/clarktown/correctors/indented_code_block.clj
@@ -0,0 +1,57 @@
+(ns clarktown.correctors.indented-code-block
+ (:require
+ [clojure.string :as string]
+ [clarktown.matchers.list-block :as list-block-matcher]))
+
+
+(defn- in-code-block?
+ "Determines whether the current `line` is within a code block."
+ [lines index]
+ (->> (take index lines)
+ (filter #(string/starts-with? (string/trim %) "```"))
+ count
+ odd?))
+
+
+(defn newline-above?
+ "Determines whether there's a need for an empty new line
+ above the `line` at the current `index`. In the case of a
+ code block, which starts with three backticks (```), if there's
+ no empty newline above, we need to create one, and so this
+ function must then return `true`."
+ [lines line index]
+ (let [space-count (count (take-while #{\space} line))
+ not-first? (> index 0)
+ prev-line (when not-first?
+ (nth lines (- index 1)))
+ space-count-prev-line (count (take-while #{\space} prev-line))]
+ (and (>= space-count 4)
+ not-first?
+ (not (in-code-block? lines index))
+ (not (list-block-matcher/match? line))
+ (not (list-block-matcher/match? prev-line))
+ (not (>= space-count-prev-line 4))
+ (not (= (-> prev-line
+ string/trim)
+ "")))))
+
+(defn newline-below?
+ "Determines whether there's a need for an empty new line
+ below the `line` at the current `index`. In the case of a
+ code block, which ends with three backticks (```), if there's
+ no empty newline above, we need to create one, and so this
+ function must then return `true`."
+ [lines line index]
+ (let [space-count (count (take-while #{\space} line))
+ not-last? (< index (- (count lines) 1))
+ next-line (when not-last?
+ (nth lines (+ index 1)))
+ space-count-next-line (count (take-while #{\space} next-line))]
+ (and (>= space-count 4)
+ not-last?
+ (not (in-code-block? lines index))
+ (not (list-block-matcher/match? line))
+ (not (list-block-matcher/match? next-line))
+ (not (>= space-count-next-line 4))
+ (not (= (-> next-line
+ string/trim) "")))))
diff --git a/src/clarktown/engine.clj b/src/clarktown/engine.clj
index 5eb22d5..dc07e9f 100644
--- a/src/clarktown/engine.clj
+++ b/src/clarktown/engine.clj
@@ -70,7 +70,7 @@
(defn- remove-excess-newlines
- "Replaces all occurences of 3 or more concecutive newlines into
+ "Replaces all occurrences of 3 or more consecutive newlines into
two newlines."
[markdown]
(string/replace markdown #"\n{3,}" "\n\n"))
@@ -133,10 +133,8 @@
[blocks given-parsers given-correctors]
(for [block blocks]
(if-let [parser (find-parser-by-block given-parsers block)]
- (->> (string/trim block)
- (parse-block-with-known-parser parser given-parsers given-correctors))
- (->> (string/trim block)
- (parse-block-with-unknown-parsers given-parsers given-correctors)))))
+ (parse-block-with-known-parser parser given-parsers given-correctors block)
+ (parse-block-with-unknown-parsers given-parsers given-correctors block))))
(defn render
diff --git a/src/clarktown/matchers/indented_code_block.clj b/src/clarktown/matchers/indented_code_block.clj
new file mode 100644
index 0000000..b7cf563
--- /dev/null
+++ b/src/clarktown/matchers/indented_code_block.clj
@@ -0,0 +1,10 @@
+(ns clarktown.matchers.indented-code-block
+ (:require
+ [clojure.string :as string]))
+
+
+(defn match?
+ "Determines whether the given block is a indented code block."
+ [block]
+ (->> (string/split-lines block)
+ (every? #(>= (count (take-while #{\space} %)) 4)))) \ No newline at end of file
diff --git a/src/clarktown/parsers.clj b/src/clarktown/parsers.clj
index 0d3b019..8ca27b3 100644
--- a/src/clarktown/parsers.clj
+++ b/src/clarktown/parsers.clj
@@ -10,6 +10,8 @@
[clarktown.renderers.quote-block]
[clarktown.matchers.fenced-code-block]
[clarktown.renderers.fenced-code-block]
+ [clarktown.matchers.indented-code-block]
+ [clarktown.renderers.indented-code-block]
[clarktown.matchers.list-block]
[clarktown.renderers.list-block]
[clarktown.renderers.paragraph-block]
@@ -61,6 +63,13 @@
(def
+ ^{:doc "Detects, parses and renders a indented code block."}
+ indented-code-block-parser
+ {:matcher clarktown.matchers.indented-code-block/match?
+ :renderers [clarktown.renderers.indented-code-block/render]})
+
+
+(def
^{:doc "Detects, parses and renders a list block."}
list-block-parser
{:matcher clarktown.matchers.list-block/match?
@@ -91,5 +100,6 @@
heading-block-parser
quote-block-parser
fenced-code-block-parser
+ indented-code-block-parser
list-block-parser
paragraph-block-parser])
diff --git a/src/clarktown/renderers/indented_code_block.clj b/src/clarktown/renderers/indented_code_block.clj
new file mode 100644
index 0000000..b3828ec
--- /dev/null
+++ b/src/clarktown/renderers/indented_code_block.clj
@@ -0,0 +1,17 @@
+(ns clarktown.renderers.indented-code-block
+ (:require
+ [clojure.string :as string]))
+
+
+(defn render
+ "Renders the indented code block."
+ [block _ _]
+ (str
+ "<pre><code>"
+ (-> (->> (string/split-lines block)
+ (map #(subs % 4))
+ (string/join \newline))
+ (string/replace #"&" "&amp;")
+ (string/replace #"<" "&lt;")
+ (string/replace #">" "&gt;"))
+ "</code></pre>")) \ No newline at end of file