{"id":16538207,"url":"https://github.com/bitterblue/commonmark-hiccup","last_synced_at":"2025-07-22T13:34:19.820Z","repository":{"id":27719851,"uuid":"81853366","full_name":"bitterblue/commonmark-hiccup","owner":"bitterblue","description":"Configurable Clojure library for converting markdown to HTML.","archived":false,"fork":false,"pushed_at":"2022-02-05T11:11:02.000Z","size":18,"stargazers_count":26,"open_issues_count":2,"forks_count":11,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-09T06:03:53.335Z","etag":null,"topics":["clojure","commonmark","hiccup","html-renderer","markdown"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitterblue.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-13T17:46:26.000Z","updated_at":"2025-03-20T22:31:56.000Z","dependencies_parsed_at":"2022-07-27T10:46:42.003Z","dependency_job_id":null,"html_url":"https://github.com/bitterblue/commonmark-hiccup","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/bitterblue/commonmark-hiccup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitterblue%2Fcommonmark-hiccup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitterblue%2Fcommonmark-hiccup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitterblue%2Fcommonmark-hiccup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitterblue%2Fcommonmark-hiccup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitterblue","download_url":"https://codeload.github.com/bitterblue/commonmark-hiccup/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitterblue%2Fcommonmark-hiccup/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266506182,"owners_count":23940019,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","commonmark","hiccup","html-renderer","markdown"],"created_at":"2024-10-11T18:44:40.421Z","updated_at":"2025-07-22T13:34:19.795Z","avatar_url":"https://github.com/bitterblue.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# commonmark-hiccup\n\n![build](https://github.com/bitterblue/commonmark-hiccup/actions/workflows/clojure.yml/badge.svg)\n\nA small Clojure library for converting [CommonMark][1] markdown to HTML. It is\ndesigned to make the HTML output as configurable as possible, relying\non [Hiccup][2] as an intermediary representation.\n\n[1]: http://spec.commonmark.org/\n[2]: https://github.com/weavejester/hiccup\n\n\n## Installation\n\nAdd the following dependency to `project.clj`:\n\n    [commonmark-hiccup \"0.2.0\"]\n\n\n## Documentation\n\ncommonmark-hiccup uses the [commonmark-java][3] parser and implements its own\nrenderer, which transforms the CommonMark AST to Hiccup-compatible Clojure data\nstructures. It then uses Hiccup to render them to their final HTML\nrepresentation.\n\ncommonmark-hiccup is built for configurability, not performance. I use it to\nrender static content for different web sites, each with different requirements\nfor how paragraphs, code blocks etc. should look like.\n\n[3]: https://github.com/atlassian/commonmark-java\n\n\n### Usage\n\nYou can convert a markdown string to HTML using `markdown-\u003ehtml`:\n\n```clojure\nuser=\u003e (require '[commonmark-hiccup.core :refer [markdown-\u003ehtml]])\nnil\nuser=\u003e (markdown-\u003ehtml \"This is a *test*.\")\n\"\u003cp\u003eThis is a \u003cem\u003etest\u003c/em\u003e.\u003c/p\u003e\"\n\n```\n\nYou can pass a configuration to the converter to tweak the output. This example\nrenders paragraphs without the surrounding `\u003cp\u003e\u003c/p\u003e` tags:\n\n```clojure\nuser=\u003e (let [config (update-in commonmark-hiccup.core/default-config\n                               [:renderer :nodes org.commonmark.node.Paragraph]\n                               (constantly :content))]\n         (markdown-\u003ehtml config \"This is a *test*.\"))\n\"This is a \u003cem\u003etest\u003c/em\u003e.\"\n```\n\n### Configuration\n\nThe default configuration defines the Hiccup snippets to which the different\nCommonMark AST nodes are rendered:\n\n```clojure\n(def default-config\n  {:renderer {:nodes {org.commonmark.node.Document          :content\n                      org.commonmark.node.Heading           ['(:h :node-level) :content]\n                      org.commonmark.node.Paragraph         [:p :content]\n                      org.commonmark.node.Text              :node-literal\n                      org.commonmark.node.BulletList        [:ul :content]\n                      org.commonmark.node.OrderedList       [:ol {:start :node-startNumber} :content]\n                      org.commonmark.node.ListItem          [:li :content]\n                      org.commonmark.node.BlockQuote        [:blockquote :content]\n                      org.commonmark.node.HtmlBlock         :node-literal\n                      org.commonmark.node.HtmlInline        :node-literal\n                      org.commonmark.node.FencedCodeBlock   [:pre [:code {:class :node-info} :node-literal]]\n                      org.commonmark.node.IndentedCodeBlock [:pre [:code :node-literal]]\n                      org.commonmark.node.Code              [:code :node-literal]\n                      org.commonmark.node.Link              [:a {:href :node-destination} :content]\n                      org.commonmark.node.Image             [:img {:src   :node-destination\n                                                                   :alt   :text-content\n                                                                   :title :node-title}]\n                      org.commonmark.node.Emphasis          [:em :content]\n                      org.commonmark.node.StrongEmphasis    [:strong :content]\n                      org.commonmark.node.ThematicBreak     [:hr]\n                      org.commonmark.node.SoftLineBreak     \" \"\n                      org.commonmark.node.HardLineBreak     [:br]}}\n   :parser   {:extensions nil}})\n```\n\nThe `:nodes` map uses [commonmark-java][3] node classes as keys. The values are\njust Clojure data structures. Some keywords and lists are replaced during\nrendering:\n\n* All keywords prefixed with `:node-` are replaced with the respective property\n  of the rendered node (e.g. `:node-literal` for `org.commonmark.node.HtmlBlock`\n  is replaced with the value returned by `HtmlBlock::getLiteral`).\n* Some keywords are special: `:content` is replaced with the rendered content\n  of the current node's children; `:text-content` is replaced with the\n  concatenated content of all `org.commonmark.node.Text` child nodes.\n* List elements are joined to strings. This is useful for rendering node\n  properties as part of a longer string. `['(:h :node-level) :content]`\n  uses the `level` property of the `Heading` node to render the appropriate HTML\n  tag (e.g. `\u003ch1\u003e\u003c/h1\u003e` for level 1 headings).\n\nFor the available properties for each node type, refer to\nthe [commonmark-java][3] sources.\n\n\n#### Extensions\n\nCommonMark [extensions](https://github.com/commonmark/commonmark-java#extensions)\ncan be added to the parser by including them in the `[:parser :extensions]`\nlist.\n\nFor example, to add the support for GFM tables:\n\n1. Add the dependency to your project\n```clojure\n[com.atlassian.commonmark/commonmark-ext-gfm-tables \"...\"]\n```\n\n2. Add the extension to your config along with the new renderers\n```clojure\n(require '[commonmark-hiccup.core :as md])\n(def my-config\n     (-\u003e md/default-config\n         (update-in [:parser :extensions] conj\n                    (org.commonmark.ext.gfm.tables.TablesExtension/create))\n         (update-in [:renderer :nodes] merge\n                    {org.commonmark.ext.gfm.tables.TableBlock [:table :content]\n                     org.commonmark.ext.gfm.tables.TableHead  [:thead :content]\n                     org.commonmark.ext.gfm.tables.TableBody  [:tbody :content]\n                     org.commonmark.ext.gfm.tables.TableRow   [:tr :content]\n                     org.commonmark.ext.gfm.tables.TableCell  [:td :content]})))\n\n(md/markdown-\u003ehiccup mt-config \"|head1|head2|\n|---|---|\n|foo|bar|\")\n=\u003e ([:table\n     ([:thead ([:tr ([:td (\"head1\")] [:td (\"head2\")])])]\n      [:tbody ([:tr ([:td (\"foo\")] [:td (\"bar\")])])])])\n```\n\n\n## License\n\nCopyright © 2017 Axel Schüssler\n\nDistributed under the Eclipse Public License either version 1.0 or (at\nyour option) any later version.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitterblue%2Fcommonmark-hiccup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitterblue%2Fcommonmark-hiccup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitterblue%2Fcommonmark-hiccup/lists"}