Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/nextjournal/markdown

A cross-platform clojure/script parser for Markdown
https://github.com/nextjournal/markdown

clojure clojurescript markdown

Last synced: 5 days ago
JSON representation

A cross-platform clojure/script parser for Markdown

Awesome Lists containing this project

README

        

# nextjournal markdown

[![Clojars Project](https://img.shields.io/clojars/v/io.github.nextjournal/markdown.svg)](https://clojars.org/io.github.nextjournal/markdown) [![Notebooks](https://img.shields.io/static/v1?label=clerk&message=notebooks&color=rgb(155,187,157))](https://nextjournal.github.io/markdown)

A cross-platform clojure library for [Markdown](https://en.wikipedia.org/wiki/Markdown) parsing and transformation.

🚧 _ALPHA_ status, subject to frequent change. For a richer reading experience [read this readme as a clerk notebook](https://nextjournal.github.io/markdown/README).

## Features

* _Focus on data_: parsing yields an AST ([Ă  la Pandoc](https://nextjournal.github.io/markdown/notebooks/pandoc)) of nested data representing a structured document.
* _Cross Platform_: using [commonmark-java](https://github.com/commonmark/commonmark-java) on the JVM and [markdown-it](https://github.com/markdown-it/markdown-it) for clojurescript
* _Configurable [Hiccup](https://github.com/weavejester/hiccup) conversion_.

## Try

[Try it online](https://nextjournal.github.io/markdown/notebooks/try).

## Flavor

We adhere to [CommonMark Spec](https://spec.commonmark.org/0.30/) and comply with extensions from [Github flavoured Markdown](https://github.github.com/gfm). Additionally, we parse $\LaTeX$ formulas (delimited by a $ for inline rendering or $$ for display mode).

## Usage

```clojure
(ns hello-markdown
(:require [nextjournal.markdown :as md]
[nextjournal.markdown.transform :as md.transform]))
```

Parsing markdown into an AST:

```clojure
(def data
(md/parse "> et tout autour, la longue cohorte de ses personnages, avec leur histoire, leur passé, leurs légendes:
> 1. PĂ©lage vainqueur d'Alkhamah se faisant couronner Ă  Covadonga
> 2. La cantatrice exilée de Russie suivant Schönberg à Amsterdam
> 3. Le petit chat sourd aux yeux vairons vivant au dernier Ă©tage
> 4. ...

**Georges Perec**, _La Vie mode d'emploi_.

---
"))
```
;; =>
{:type :doc,
:content [{:type :blockquote,
:content [{:type :paragraph,
:content [{:type :text,
:text "et tout autour, la longue cohorte de ses personnage, avec leur histoire, leur passé, leurs légendes:"}]}
{:type :numbered-list,
:content [{:type :list-item,
:content [{:type :plain,
:content [{:type :text,
:text "PĂ©lage vainqueur d'Alkhamah se faisant couronner Ă  Covadonga"}]}]}
{:type :list-item,
:content [{:type :plain,
:content [{:type :text,
:text "La cantatrice exilée de Russie suivant Schönberg à Amsterdam"}]}]}
{:type :list-item,
:content [{:type :plain,
:content [{:type :text,
:text "Le petit chat sourd aux yeux vairons vivant au dernier Ă©tage"}]}]}]}]}
{:type :paragraph,
:content [{:type :strong, :content [{:type :text, :text "Georges Perec"}]}
{:type :text, :text ", "}
{:type :em, :content [{:type :text, :text "La Vie mode d'emploi"}]}
{:type :text, :text "."}]}
{:type :ruler}]}

and transform that AST into `hiccup` syntax.

```clojure
(md.transform/->hiccup data)
```
;; =>
[:div
[:blockquote
[:p "et tout autour, la longue cohorte de ses personnage, avec leur histoire, leur passé, leurs légendes:"]
[:ol
[:li [:<> "PĂ©lage vainqueur d'Alkhamah se faisant couronner Ă  Covadonga"]]
[:li [:<> "La cantatrice exilée de Russie suivant Schönberg à Amsterdam"]]
[:li [:<> "Le petit chat sourd aux yeux vairons vivant au dernier Ă©tage"]]]]
[:p [:strong "Georges Perec"] ", " [:em "La Vie mode d'emploi"] "."]
[:hr]]

We've built hiccup transformation in for convenience, but the same approach can be used to target [more formats](https://nextjournal.github.io/markdown/notebooks/pandoc).

This library is one of the building blocks of [Clerk](https://github.com/nextjournal/clerk) where it is used for rendering _literate fragments_.

```clojure
^{:nextjournal.clerk/viewer 'nextjournal.clerk.viewer/markdown-viewer}
data
```

The transformation of markdown node types can be customised like this:

```clojure
^{:nextjournal.clerk/viewer 'nextjournal.clerk.viewer/html-viewer}
(md.transform/->hiccup
(assoc md.transform/default-hiccup-renderers
;; :doc specify a custom container for the whole doc
:doc (partial md.transform/into-markup [:div.viewer-markdown])
;; :text is funkier when it's zinc toned
:text (fn [_ctx node] [:span {:style {:color "#71717a"}} (:text node)])
;; :plain fragments might be nice, but paragraphs help when no reagent is at hand
:plain (partial md.transform/into-markup [:p {:style {:margin-top "-1.2rem"}}])
;; :ruler gets to be funky, too
:ruler (constantly [:hr {:style {:border "2px dashed #71717a"}}]))
data)
```

## Extensibility

We added minimal tooling for [extending markdown expressions](https://nextjournal.github.io/markdown/notebooks/parsing_extensibility).