Generate Markdown from Hiccup-style Clojure data structures. miccup is to Markdown what Hiccup is to HTML.
deps.edn:
io.github.radish-miyazaki/miccup {:mvn/version "0.1.0"}
(require '[miccup.core :as m])
(str (m/md [:h1 "Hello world"]))
;; => "# Hello world"
[:h1 ...]) are Markdown elements.:html/* tags ([:html/div ...]) are embedded as raw HTML (delegated to hiccup).md accepts one or more forms and returns a RawString; wrap it in str to get the final string.md is variadic. Multiple top-level forms are joined as blocks separated by a blank line:
(str (m/md [:h1 "Title"] [:p "Body"]))
;; => "# Title\n\nBody"
Elements nest freely; inline children are concatenated.
(str (m/md [:h1 "Hello " [:strong "world"]]))
;; => "# Hello **world**"
(str (m/md [:em "it"])) ;; => "*it*" (alias: :i)
(str (m/md [:strong "bold"])) ;; => "**bold**" (alias: :b)
(str (m/md [:del "gone"])) ;; => "~~gone~~" (alias: :s)
(str (m/md [:code "(+ 1 2)"])) ;; => "`(+ 1 2)`"
(str (m/md [:a {:href "https://clojure.org" :title "home"} "Clojure"]))
;; => "[Clojure](https://clojure.org \"home\")"
(str (m/md [:img {:src "logo.png" :alt "Logo"}]))
;; => ""
(str (m/md [:ul [:li "Apple"] [:li "Orange"]]))
;; => "- Apple\n- Orange"
(str (m/md [:ol [:li "first"] [:li "second"]]))
;; => "1. first\n2. second"
;; Nested lists are indented by two spaces
(str (m/md [:ul [:li "a" [:ul [:li "a1"]]] [:li "b"]]))
;; => "- a\n - a1\n- b"
;; Task lists via {:checked ...}
(str (m/md [:ul [:li {:checked true} "done"] [:li {:checked false} "todo"]]))
;; => "- [x] done\n- [ ] todo"
(str (m/md [:pre {:lang "clojure"} "(+ 1 2)"]))
;; => "```clojure\n(+ 1 2)\n```"
(str (m/md [:blockquote "quoted"]))
;; => "> quoted"
(str (m/md [:hr]))
;; => "---"
(str (m/md [:table
[:thead [:tr [:th "A"] [:th {:align :right} "B"]]]
[:tbody [:tr [:td "1"] [:td "2"]]]]))
;; => "| A | B |\n| --- | ---: |\n| 1 | 2 |"
Table column alignment is set per header cell with {:align :left | :right | :center}.
Seqs (e.g. from for) are spliced into their parent, nil is skipped, numbers are stringified, and text is Markdown-escaped automatically:
(str (m/md (into [:ul] (for [x ["a" "b"]] [:li x]))))
;; => "- a\n- b"
(str (m/md [:p "a*b_c"]))
;; => "a\\*b\\_c"
:html/* tags are rendered as raw HTML (delegated to hiccup) and embedded directly, which Markdown permits:
(str (m/md [:p "see " [:html/sub "x"]]))
;; => "see <sub>x</sub>"
Start an nREPL server:
clojure -M:dev
Run tests:
clojure -M:test
Build a jar:
clojure -T:build jar
Install into the local Maven repository (~/.m2):
clojure -T:build install
Deploy to Clojars (requires a Clojars deploy token):
clojure -T:build jar
CLOJARS_USERNAME=<username> CLOJARS_PASSWORD=<deploy-token> clojure -X:deploy
Contributions are welcome!
clojure -M:test — all tests must pass.:table expects both a :thead and a :tbody; omitting :thead produces malformed output rather than an error.:title and :href/:src attribute values are emitted as-is; a literal " inside a :title is not escaped.EPL-1.0
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |