From 6d113cc003c776090b6506b83ed5c43e1360afa2 Mon Sep 17 00:00:00 2001 From: Andrea Amantini Date: Thu, 15 Aug 2024 15:59:25 +0200 Subject: [PATCH] Equalize code and links + add tests --- src/nextjournal/markdown.cljc | 3 + src/nextjournal/markdown/parser/impl.clj | 22 +++++-- .../markdown/parser/impl/utils.cljc | 2 +- test/nextjournal/markdown_test.cljc | 60 +++++++++++++++++++ 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/src/nextjournal/markdown.cljc b/src/nextjournal/markdown.cljc index 9662aa0..190e95d 100644 --- a/src/nextjournal/markdown.cljc +++ b/src/nextjournal/markdown.cljc @@ -41,6 +41,9 @@ - [x] ~~thing~~ ") + (-> (nextjournal.markdown.graaljs/parse "[alt](https://this/is/a.link)") :content first :content first) + (-> (parse "[alt](https://this/is/a.link)") :content first :content first) + (with-new-parser (parse "# Hello Markdown - [ ] what diff --git a/src/nextjournal/markdown/parser/impl.clj b/src/nextjournal/markdown/parser/impl.clj index 3fc5f6e..988d684 100644 --- a/src/nextjournal/markdown/parser/impl.clj +++ b/src/nextjournal/markdown/parser/impl.clj @@ -109,8 +109,14 @@ id (assoc-in [:attrs :id] id) emoji (assoc :emoji emoji)))) (as-> l - (if (= 1 (u/zdepth l)) ;; only add top level headings to ToC - (-> l z/up (z/edit u/add-to-toc (z/node l)) z/down z/rightmost) + (if (= 1 (u/zdepth l)) + ;; only add top level headings to ToC + (-> l z/up + (z/edit (fn [doc] + (-> doc + (u/add-to-toc (z/node l)) + (u/set-title-when-missing (z/node l))))) + z/down z/rightmost) l)) z/up))))) @@ -137,19 +143,23 @@ (defmethod open-node Link [ctx ^Link node] (update-current ctx (fn [loc] (-> loc (z/append-child {:type :link - :attrs {:href (.getDestination node) :title (.getTitle node)} - :content []}) z/down z/rightmost)))) + :content [] + :attrs (cond-> {:href (.getDestination node)} + (.getTitle node) + (assoc :title (.getTitle node)))}) z/down z/rightmost)))) (defmethod open-node IndentedCodeBlock [ctx ^IndentedCodeBlock node] (update-current ctx (fn [loc] (-> loc (z/append-child {:type :code - :content [{:text (.getLiteral node)}]}) z/down z/rightmost)))) + :content [{:type :text + :text (.getLiteral node)}]}) z/down z/rightmost)))) (defmethod open-node FencedCodeBlock [ctx ^FencedCodeBlock node] (update-current ctx (fn [loc] (-> loc (z/append-child (merge {:type :code :info (.getInfo node) - :content [{:text (.getLiteral node)}]} + :content [{:type :text + :text (.getLiteral node)}]} (u/parse-fence-info (.getInfo node)))) z/down z/rightmost)))) (defmethod open-node Image [ctx ^Image node] diff --git a/src/nextjournal/markdown/parser/impl/utils.cljc b/src/nextjournal/markdown/parser/impl/utils.cljc index e77bca2..5ad4e54 100644 --- a/src/nextjournal/markdown/parser/impl/utils.cljc +++ b/src/nextjournal/markdown/parser/impl/utils.cljc @@ -308,7 +308,7 @@ end" (defn parse-fence-info [info-str] (try - (when (string? info-str) + (when (and (string? info-str) (seq info-str)) (let [tokens (-> info-str str/trim (str/replace #"[\{\}\,]" "") ;; remove Pandoc/Rmarkdown brackets and commas diff --git a/test/nextjournal/markdown_test.cljc b/test/nextjournal/markdown_test.cljc index e10bb0e..ca4406e 100644 --- a/test/nextjournal/markdown_test.cljc +++ b/test/nextjournal/markdown_test.cljc @@ -862,6 +862,66 @@ some text #### Section 3.1 ")))))) + +(deftest link-test + (testing "links with a title" + (is (= {:type :link + :attrs {:href "/some/path" :title "this is the link title"} + :content [{:type :text :text "ahoi"}]} + (-> (md/parse "[ahoi](/some/path 'this is the link title')") + :content first :content first)))) + (testing "links with no title" + (is (= {:type :link + :attrs {:href "/some/path"} + :content [{:type :text :text "ahoi"}]} + (-> (md/parse "[ahoi](/some/path)") + :content first :content first)))) + (testing "links with nested content" + (is (= {:type :link + :attrs {:href "/some/path"} + :content [{:type :text :text "some "} + {:type :em :content [{:type :text :text "markup"}]} + {:type :text :text " here"}]} + (-> (md/parse "[some _markup_ here](/some/path)") + :content first :content first))))) + +(deftest code-test + (testing "inline code" + (is (= {:type :paragraph + :content [{:type :text :text "some "} + {:type :monospace :content [{:text "inline code" :type :text}]} + {:type :text :text " here"}]} + (-> (md/parse "some `inline code` here") + :content first)))) + (testing "indented code blocks" + (is (= {:type :code + :content [{:type :text :text "and indented\ncode here\n"}]} + (-> (md/parse "some text + + and indented + code here + +back to text") :content second))) + + (testing "fenced code blocks" + (is (= {:type :code :info "" + :content [{:type :text :text "and fenced\ncode here\n"}]} + (-> (md/parse "some text +``` +and fenced +code here +``` +back to text") :content second))) + + (is (= {:type :code + :content [{:type :text :text "(this is code)\n"}] + :info "clojure id=12345 no-exec" + :language "clojure" :id "12345" :no-exec true} + (-> (md/parse "```clojure id=12345 no-exec +(this is code) +```") + :content first)))))) + (comment (clojure.test/run-test-var #'formulas)