diff options
| author | Asko Nõmm <ano@ano.ee> | 2022-05-11 18:09:16 +0300 |
|---|---|---|
| committer | Asko Nõmm <ano@ano.ee> | 2022-05-11 18:09:16 +0300 |
| commit | 9276a14c41e95e5ca17c648fe71c162f35551057 (patch) | |
| tree | 8f941e88d070118acf4c807bee380b013912e4c9 | |
| parent | b97891cc45b9a087a372767e25aa36788bc979bf (diff) | |
Add `id` attributes to headings based on value.
| -rw-r--r-- | resources/test/core_result.html | 8 | ||||
| -rw-r--r-- | src/clarktown/renderers/heading_block.clj | 28 | ||||
| -rw-r--r-- | test/clarktown/renderers/heading_block_test.clj | 26 |
3 files changed, 39 insertions, 23 deletions
diff --git a/resources/test/core_result.html b/resources/test/core_result.html index 54273e0..01f91aa 100644 --- a/resources/test/core_result.html +++ b/resources/test/core_result.html @@ -48,7 +48,7 @@ function markdownToHTML(markdown) { <p>This is <em><strong>bold italic text</strong></em> and <em><strong>this is also</strong></em>. <em>What about italic text that <strong>has bold text</strong></em>?</p> -<h2>Hi there, world!</h2> +<h2 id="hi-there-world">Hi there, world!</h2> <ul><li>List item</li><li>Another list <del>item</del><ul><li>Sub list item</li><li>Another sub list item<ul><li>Sub sub list item</li><li>Continuing sub list item</li></ul></li></ul></li><li>Continuing list item</li></ul> @@ -59,14 +59,14 @@ function markdownToHTML(markdown) { <pre><code>code goes here. # This is a heading.</code></pre> -<h1>This is a H1 heading with settext</h1> +<h1 id="this-is-a-h1-heading-with-settext">This is a H1 heading with settext</h1> -<h2>And this is a H2 heading with settext</h2> +<h2 id="and-this-is-a-h2-heading-with-settext">And this is a H2 heading with settext</h2> <p>Testing paragraph right before a code block</p> <pre><code>code goes here</code></pre> -<h1>Heading goes here</h1> +<h1 id="heading-goes-here">Heading goes here</h1> <p>Paragraph right after heading</p>
\ No newline at end of file diff --git a/src/clarktown/renderers/heading_block.clj b/src/clarktown/renderers/heading_block.clj index 7f4c7de..563508e 100644 --- a/src/clarktown/renderers/heading_block.clj +++ b/src/clarktown/renderers/heading_block.clj @@ -1,9 +1,23 @@ (ns clarktown.renderers.heading-block (:require [clojure.string :as string] - [clarktown.matchers.heading-block :as matcher])) + [clarktown.matchers.heading-block :as matcher]) + (:import + (java.text Normalizer Normalizer$Form))) +(defn- slugify + "Turn `input` in a URL slug." + [input] + (let [split-s(-> (Normalizer/normalize input Normalizer$Form/NFD) + (string/replace #"[\P{ASCII}]+" "") + string/lower-case + string/triml + (string/split #"[\p{Space}\p{P}]+")) + combined (string/join "-" split-s)] + (apply str (take 250 combined)))) + + (defn render-atx-heading "Renders the hashbang heading block." [block] @@ -15,8 +29,9 @@ value (->> (string/split single-line-block #" ") next (string/join " ") - string/trim)] - (str "<h" size ">" value "</h" size ">"))) + string/trim) + id (slugify value)] + (str "<h" size " id=\"" id "\">" value "</h" size ">"))) (defn render-settext-heading @@ -29,10 +44,11 @@ h1? (= "=" (-> (last lines) string/trim (string/split #"") - first))] + first)) + id (slugify value)] (if h1? - (str "<h1>" value "</h1>") - (str "<h2>" value "</h2>")))) + (str "<h1 id=\"" id "\">" value "</h1>") + (str "<h2 id=\"" id "\">" value "</h2>")))) (defn render diff --git a/test/clarktown/renderers/heading_block_test.clj b/test/clarktown/renderers/heading_block_test.clj index 8f229fb..a0852e8 100644 --- a/test/clarktown/renderers/heading_block_test.clj +++ b/test/clarktown/renderers/heading_block_test.clj @@ -6,27 +6,27 @@ (deftest atx-heading-renderer-test (testing "ATX heading block that's a H1" - (is (= "<h1>This is a heading block.</h1>" + (is (= "<h1 id=\"this-is-a-heading-block\">This is a heading block.</h1>" (heading-block/render "# This is a heading block." nil nil)))) (testing "ATX heading block that's a H2" - (is (= "<h2>This is a heading block.</h2>" + (is (= "<h2 id=\"this-is-a-heading-block\">This is a heading block.</h2>" (heading-block/render "## This is a heading block." nil nil)))) (testing "ATX heading block that's a H3" - (is (= "<h3>This is a heading block.</h3>" + (is (= "<h3 id=\"this-is-a-heading-block\">This is a heading block.</h3>" (heading-block/render "### This is a heading block." nil nil)))) (testing "ATX heading block that's a H4" - (is (= "<h4>This is a heading block.</h4>" + (is (= "<h4 id=\"this-is-a-heading-block\">This is a heading block.</h4>" (heading-block/render "#### This is a heading block." nil nil)))) (testing "ATX heading block that's a H5" - (is (= "<h5>This is a heading block.</h5>" + (is (= "<h5 id=\"this-is-a-heading-block\">This is a heading block.</h5>" (heading-block/render "##### This is a heading block." nil nil)))) (testing "ATX heading block that's a H6" - (is (= "<h6>This is a heading block.</h6>" + (is (= "<h6 id=\"this-is-a-heading-block\">This is a heading block.</h6>" (heading-block/render "###### This is a heading block." nil nil)))) (testing "No H tag when 7 or more # characters" @@ -38,11 +38,11 @@ (heading-block/render "#This is not a heading block." nil nil)))) (testing "ATX heading can precede up to 3 spaces" - (is (= "<h1>This is a heading.</h1>" + (is (= "<h1 id=\"this-is-a-heading\">This is a heading.</h1>" (heading-block/render " # This is a heading." nil nil))) - (is (= "<h1>This is a heading.</h1>" + (is (= "<h1 id=\"this-is-a-heading\">This is a heading.</h1>" (heading-block/render " # This is a heading." nil nil))) - (is (= "<h1>This is a heading.</h1>" + (is (= "<h1 id=\"this-is-a-heading\">This is a heading.</h1>" (heading-block/render " # This is a heading." nil nil)))) (testing "But no more than 3 spaces" @@ -53,17 +53,17 @@ (deftest settext-heading-renderer-text (testing "Settext heading block that's a H1" - (is (= "<h1>This is a heading block.</h1>" + (is (= "<h1 id=\"this-is-a-heading-block\">This is a heading block.</h1>" (heading-block/render "This is a heading block.\n=========" nil nil)))) (testing "Settext heading block that's a H1 spanning multiple lines" - (is (= "<h1>This is a \nheading block spanning multiple lines.</h1>" + (is (= "<h1 id=\"this-is-a-heading-block-spanning-multiple-lines\">This is a \nheading block spanning multiple lines.</h1>" (heading-block/render "This is a \nheading block spanning multiple lines.\n========" nil nil)))) (testing "Settext heading block that's a H2" - (is (= "<h2>This is a heading block.</h2>" + (is (= "<h2 id=\"this-is-a-heading-block\">This is a heading block.</h2>" (heading-block/render "This is a heading block.\n---------" nil nil)))) (testing "Settext heading block that's a H2 spanning multiple lines" - (is (= "<h2>This is a \nheading block spanning multiple lines.</h2>" + (is (= "<h2 id=\"this-is-a-heading-block-spanning-multiple-lines\">This is a \nheading block spanning multiple lines.</h2>" (heading-block/render "This is a \nheading block spanning multiple lines.\n--------" nil nil))))) |
