From 7c3eba77fd3de0e108efba94018233a57e66989e Mon Sep 17 00:00:00 2001 From: Asko Nõmm Date: Wed, 11 May 2022 20:42:30 +0300 Subject: Implement indented code blocks. --- src/clarktown/correctors/indented_code_block.clj | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/clarktown/correctors/indented_code_block.clj (limited to 'src/clarktown/correctors/indented_code_block.clj') 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) ""))))) -- cgit v1.2.3