• Stars
    star
    540
  • Rank 82,257 (Top 2 %)
  • Language
    Clojure
  • License
    Eclipse Public Li...
  • Created about 13 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Markdown parser in Clojure

Markdown parser written in Clojure/Script

CircleCI Downloads

Demo

You can try out the parser here.

Installation

A markdown parser that compiles to both Clojure and ClojureScript.

Clojars Project

Note: markdown-clj versions prior to 0.9.68 requires Clojure 1.2+ to run, versions 0.9.68+ require Clojure 1.7.

NPM

Usage Clojure

Markdown-clj can be invoked either by calling md-to-html or md-to-html-string functions.

The md-to-html function accepts an input containing Markdown markup and an output where the resulting HTML will be written. The input and output parameters will be passed to a reader and a writer respectively:

(ns foo
  (:use markdown.core))

(md-to-html "input.md" "output.html")

(md-to-html (input-stream "input.md") (output-stream "test.txt"))

The md-to-html-string function accepts a string with markdown content and returns a string with the resulting HTML:

(md-to-html-string "# This is a test\nsome code follows\n```clojure\n(defn foo [])\n```")
<h1> This is a test</h1>some code follows<pre><code class="clojure">&#40;defn foo &#91;&#93;&#41;
</code></pre>

Both md-to-html and md-to-html-string accept optional parameters:

Specifying :heading-anchors will create anchors for the heading tags, eg:

(markdown/md-to-html-string "###foo bar BAz" :heading-anchors true)
<h3 id=\"foo&#95;bar&#95;baz\">foo bar BAz</h3>

The code blocks default to a highlight.js compatible format of:

<pre><code class="clojure">some code</code></pre>

Specifying :code-style will override the default code class formatting for code blocks, eg:

(md-to-html-string "# This is a test\nsome code follows\n```clojure\n(defn foo [])\n```"
                   :code-style #(str "class=\"brush: " % "\""))
<h1> This is a test</h1>some code follows<pre><code class="brush: clojure">
&#40;defn foo &#91;&#93;&#41;
</code></pre>

reference style links

The parser defaults to using inline reference for performance reasons, to enable reference style links pass in the :reference-links? true option:

(md-to-html-string
  "This is [an example][id] reference-style link.

   [id]: http://example.com/ 'Optional Title Here'"
   :reference-links? true)

footnotes

To enable footnotes, pass the :footnotes? true option:

(md-to-html-string
  "Footnotes will appear automatically numbered with a link to the footnote at bottom of the page [^footnote1].

  [^footnote1]: The footnote will contain a back link to to the referring text."
  :footnotes? true)

Metadata

The metadata encoded using the syntax described by MultiMarkdown can be optionally extracted from the document.

The md-to-html function will attempt to parse the metadata when passed the :parse-meta? true option and return it as its output. Additionally, md-to-html-string-with-meta function can be used to parse string input. The function returns a map with two keys, :html containing the parsed HTML, and :metadata containing a map with the metadata included at the top of the document.

To parse only the metadata, use md-to-meta. This function returns a metadata map for the given input, but does not otherwise parse the Markdown or return HTML. It can run more quickly than either of the functions that return HTML and can be useful in scenarios where the metadata can be useful by itself.

The value of each key in the metadata map will be a list of either 0, 1 or many strings. If a metadata value ends in two spaces then the string will end in a newline. If a line does not contain a header and has at least 4 spaces in front of it then it will be considered to be a member of the last key that was found.

(let [input    (new StringReader text)
      output   (new StringWriter)
      metadata (md-to-html input output :parse-meta? true)
      html     (.toString output)]
  {:metadata metadata :html html})

(md-to-html-string-with-meta
  "Author: Rexella van Imp
    Kim Jong-un
Date: October 31, 2015

   # Hello!")

{:metadata {:author ["Rexella van Imp"
                     "Kim Jong-un"],
            :date ["October 31, 2015"]},
 :html "<h1>Hello!</h1>"}

Selectively inhibiting the Parser

If you pass :inhibit-separator "some-string", then any text within occurrences of some-string will be output verbatim, eg:

(md-to-html-string "For all %$a_0, a_1, ..., a_n in R$% there is _at least one_ %$b_n in R$% such that..."
                   :inhibit-separator "%")
For all $a_0, a_1, ..., a_n in R$ there is <i>at least one</i> $b_n in R$ such that...

This may be useful to use markdown-clj along with other parsers of languages with conflicting syntax (e.g. asciimath2jax).

If you need to output the separator itself, enter it twice without any text inside. Eg:

(md-to-html-string "This is one of those 20%% vs 80%% cases."
                   :inhibit-separator "%")
This is one of those 20% vs 80% cases.

Some caveats:

  • Like other tags, this only works within a single line.

  • If you remove the default transformers with :replacement-transformers (which see below), inhibiting will stop working.

  • Currently, dashes (-- and ---) can't be suppressed this way.

Customizing the Parser

Additional transformers can be specified using the :custom-transformers key. A transformer function must accept two arguments. First argument is the string representing the current line and the second is the map representing the current state.

The default state keys are:

  • :code - inside a code section
  • :codeblock - inside a code block
  • :eof - end of file
  • :heading - in a heading
  • :hr - in a horizontal line
  • :lists - inside a list
  • :blockquote - inside a blockquote
  • :paragraph - in a paragraph
  • :last-line-empty? - was last line an empty line?

For example, if we wanted to add a transformer that would capitalize all text we could do the following:

(defn capitalize [text state]
  [(.toUpperCase text) state])

(markdown/md-to-html-string "#foo" :custom-transformers [capitalize])
<H1>FOO</H1>

Alternatively, you could provide a custom set of transformers to replace the default transformers using the :replacement-transformers key.

(markdown/md-to-html-string "#foo" :replacement-transformers [capitalize])

This can also be used to add preprocessor transformers. For example, if we wanted to sanitize any image links and escape HTML we could do the following:

(use 'markdown.transformers 'markdown.core)

(defn escape-images [text state]
  [(clojure.string/replace text #"(!\[.*?\]\()(.+?)(\))" "") state])

(defn escape-html
    "Change special characters into HTML character entities."
    [text state]
    [(if-not (or (:code state) (:codeblock state))
       (clojure.string/escape
         text
         {\& "&amp;"
          \< "&lt;"
          \> "&gt;"
          \" "&quot;"
          \' "&#39;"})
       text) state])
       
(markdown/md-to-html-string
  "<h1>escaped</h1>foo ![Alt text](/path/to/img.jpg \"Optional Title\") bar [text](http://test)"
  :replacement-transformers (into [escape-images escape-html] transformer-vector))
"<p>&lt;h1&gt;escaped&lt;/h1&gt;foo  bar <a href='http://test'>text</a></p>"

Usage ClojureScript

The ClojureScript portion works the same as above except that the entry function is called md->html. It accepts a string followed by the options as its input, and returns the resulting HTML string:

(ns myscript
  (:require [markdown.core :refer [md->html]]))

(.log js/console
  (md->html "##This is a heading\nwith a paragraph following it"))

(.log js/console
  (md->html "# This is a test\nsome code follows\n```clojure\n(defn foo [])\n```"
               :code-style #(str "class=\"" % "\"")))

(md->html-with-meta "# This is a test\nsome code follows\n```clojure\n(defn foo [])\n```")

Usage JavaScript

console.log(markdown.core.mdToHtml("##This is a heading\nwith a paragraph following it"));

Supported syntax

Control characters can be escaped using \

\\ backslash
\` backtick
\* asterisk
\_ underscore
\{ curly braces
\}
\[ square brackets
\]
\( parentheses
\)
\# hash mark
\+ plus sign
\- minus sign (hyphen)
\. dot
\! exclamation mark
\^ caret / circumflex accent

Basic Elements

Blockquote, Strong, Bold, Bold-Italic, Emphasis, Italics, Heading, Line, Linebreak, Paragraph, Strikethrough

Links

Image, Link

Automatic Links

This is a shortcut style for creating “automatic” links for URLs and email addresses:

<http://example.com/>

will be turned this into:

<a href="http://example.com/">http://example.com/</a>

Automatic links for email addresses work similarly, except that they are hex encoded:

will be turned into:

<a href=\"&#x61&#x64&#x64&#x72&#x65&#x73&#x73&#x40&#x65&#x78&#x61&#x6d&#x70&#x6c&#x65&#x2e&#x63&#x6f&#x6d\">&#x61&#x64&#x64&#x72&#x65&#x73&#x73&#x40&#x65&#x78&#x61&#x6d&#x70&#x6c&#x65&#x2e&#x63&#x6f&#x6d</a>

Lists

Ordered List, Unordered List

Code

Code Block, Indented Code, Inline Code


Heading

the number of hashes indicates the level of the heading

# Heading

##Sub-heading

### Sub-sub-heading

headings can also be defined using = and - for h1 and h2 respectively

Heading 1
=========

Heading 2
---------

Line

***

* * *

*****

- - -

______

Linebreak

If a line ends with two or more spaces a <br /> tag will be inserted at the end.

Emphasis

*foo*

Italics

_foo_

Strong

**foo**

Bold

__foo__

Bold-Italic

***bold italic***

Blockquote

> prefixes regular blockquote paragraphs. >- prefixes a blockquote footer that can be used for author attribution.

>This is a blockquote
with some content

>this is another blockquote

> Everyone thinks of changing the world,
but no one thinks of changing himself.
>- Leo Tolstoy

Paragraph

This is a paragraph, it's
split into separate lines.

This is another paragraph.

Unordered List

indenting an item makes it into a sublist of the item above it, ordered and unordered lists can be nested within one another. List items can be split over multiple lines.

* Foo
* Bar
 * Baz
* foo
* bar

   * baz
     1. foo
     2. bar
        more content
        ## subheading
        ***
        **strong text** in the list

   * fuzz

      * blah
      * blue
* brass

Ordered List

1. Foo
2. Bar
3. Baz

Inline Code

Any special characters in code will be escaped with their corresponding HTML codes.

Here's some code `x + y = z` that's inlined.

Code block

Using three backquotes indicates a start of a code block, the next three backquotes ends the code block section. Optionally, the language name can be put after the backquotes to produce a tag compatible with highlight.js, eg:

```clojure

(defn foo [bar] "baz")

```

Indented Code

indenting by at least 4 spaces creates a code block

some
code
here

note: XML is escaped in code sections

Strikethrough

~~foo~~

Superscript

a^2 + b^2 = c^2

Link

[github](http://github.com)
Reference Link
This is [an example][id] reference-style link.

[id]: http://example.com/  "Optional Title Here"

note: reference links require the :reference-links? option to be set to true

Footnote

"Footnotes will appear automatically numbered with a link to the footnote at bottom of the page [^footnote1].
[^footnote1]: The footnote will contain a back link to to the referring text."

note: to enable footnotes, the :footnotes? option must be set to true.

Image

![Alt text](http://server/path/to/img.jpg)
![Alt text](/path/to/img.jpg "Optional Title")
Image Reference
This is ![an example][id] reference-style image descriptor.

[id]: http://example.com/  "Optional Title Here"

note: reference links require the :reference-links? option to be set to true

Image Link

[![Continuous Integration status](https://secure.travis-ci.org/yogthos/markdown-clj.png)](http://travis-ci.org/yogthos/markdown-clj)

Table

You can create tables by assembling a list of words and dividing them with hyphens - (for the first row), and then separating each column with a pipe |:

| First Header  | Second Header |
| ------------- | ------------- |
| Content Cell  | Content Cell  |
| Content Cell  | Content Cell  |

By including colons : within the header row, you can define text to be left-aligned, right-aligned, or center-aligned:

| Left-Aligned  | Center Aligned    | Right Aligned |
| :------------ | :---------------: | ------------: |
| col 3 is      |  some wordy text  | $1600         |
| col 2 is      |  centered         |   $12         |
| zebra stripes |  are neat         |    $1         |

A colon on the left-most side indicates a left-aligned column; a colon on the right-most side indicates a right-aligned column; a colon on both sides indicates a center-aligned column.

Limitations

The parser reads the content line by line, this means that tag content is not allowed to span multiple lines.

License

Copyright © 2015 Dmitri Sotnikov

Distributed under the Eclipse Public License, the same as Clojure.

More Repositories

1

Selmer

A fast, Django inspired template system in Clojure.
Clojure
982
star
2

migratus

MIGRATE ALL THE THINGS!
Clojure
642
star
3

clojure-error-message-catalog

a catalog of common Clojure errors and their meaning
448
star
4

memory-hole

Memory Hole is a support issue organizer application
Clojure
261
star
5

mastodon-bot

a bot for mirroring Twitter/Tumblr accounts and RSS feeds on Mastodon
Clojure
192
star
6

json-html

Provide EDN/JSON and get a DOM node with a human representation of the data
Clojure
160
star
7

config

Library for managing environment variables in Clojure using EDN configuration files
Clojure
155
star
8

yuggoth

my blog engine (no longer maintained)
Clojure
147
star
9

graal-web-app-example

example web application using HTTP Kit and Reitit compiled with GraalVM
Clojure
122
star
10

instant-pdf

A reporting service which generates PDFs from JSON encoded text
Clojure
109
star
11

json-to-pdf

A Library for easily generating PDF documents given JSON markup
Clojure
99
star
12

maestro

FSM library for managing workflows
Clojure
90
star
13

clj-rss

a library for generating RSS feeds
Clojure
59
star
14

compojure-template

A Leiningen template for batteries included projects using Compojure.
Clojure
52
star
15

doc-builder

data driven HTML/PDF document builder using Hiccup and EDN
Clojure
48
star
16

clj-tetris

Example Tetris in Clojure
Clojure
44
star
17

cheatsheets

Shell
40
star
18

lein-asset-minifier

Leiningen plugin for CSS/Js asset minifcation
Clojure
40
star
19

cljs-eval-example

Example of using ClojureSript eval with Reagent
Clojure
32
star
20

gif-to-html

converts GIFs to HTML animation
Clojure
28
star
21

migratus-lein

Clojure
27
star
22

asset-minifier

a library to minify CSS/Js resources
Clojure
27
star
23

reagent-example

Clojure
27
star
24

clj-log

structural logging for Clojure
Clojure
24
star
25

graviton

a small game written in ClojureScript and Pixi.js
Clojure
24
star
26

lein-sass

SASS plugin for Leiningen using Sass.js
Clojure
20
star
27

emoji-id

converts a numeric id to emoji because reasons
Clojure
20
star
28

pg-feed-demo

example application for push notifications from PostgreSQL
Clojure
19
star
29

genetic-algorithm-example

Example of a simple GA using Clojure
Clojure
18
star
30

reagent-secretary-example

Clojure
17
star
31

quil-reagent-demo

example of using Quil with Reagent
Clojure
17
star
32

resume

Clojure
17
star
33

reagent-serverside

example of using Hiccup to generate Reagent elements server-side
Clojure
16
star
34

boids

boids example using Quil and PixiJS
Clojure
14
star
35

components-example

example of creating reusable re-frame components
Clojure
14
star
36

swagger-service

swagger-service tutorial using Duct
Clojure
13
star
37

figwheel-library-template

a template for developing ClojureScript libraries using Figwheel
Clojure
13
star
38

clojure-maven-examples

Some examples for building Clojure with the clojure-maven-plugin
Clojure
12
star
39

krueger

federated news
Clojure
12
star
40

reagent-dnd

Reagent wrapper for react-dnd
Clojure
11
star
41

pulsar-example

Clojure
11
star
42

reagent-server-rendering

An example using Nashorn to render Reagent on the server
Clojure
10
star
43

alpha-id

creates a short alphanumeric ID from a numeric ID
Clojure
10
star
44

prag-prog-re-frame-article

source code for the re-frame article
Clojure
10
star
45

ReagentPerf

Reagent version of the VueReactPerf benchmark
Clojure
9
star
46

semantic-ui-react-example

Example of using semantic-ui-react with shadow-cljs
HTML
8
star
47

markov-chains

a simple markov-chain generator example
Clojure
7
star
48

hiccup-template

a minimal Clojure/Script library for Hiccup style templating
Clojure
6
star
49

Space-Invaders

Sample Java 2D game of Space Invaders
Java
6
star
50

semantic-ui-example

an example of using React Semantic UI from Reagent
Clojure
6
star
51

yogthos.net

source for my blog yogthos.net
HTML
5
star
52

liberator-example

Sample project for Liberator
Clojure
5
star
53

particle-constellations

Clojure
4
star
54

escher-mask

example of using Escher.js from Reagent
Clojure
4
star
55

ring-http-cat-status

Ring middleware for serving status images from https://http.cat/
Clojure
4
star
56

kit-workshop

Clojure
4
star
57

reagent-pythagorean-tree

Clojure
4
star
58

clojurescript-error-reporting-example

Sample project illustrating reporting client-side errors to the server with source maps
Clojure
3
star
59

configs

my configs
Shell
3
star
60

selmer-java

Java wrapper for Selmer
Clojure
3
star
61

guestbook-with-auth

Guestbook example for Web Development With Clojure
Clojure
3
star
62

cli-test

CLI example using GraalVM
Clojure
3
star
63

guestbook

Web development with Clojure (2nd edition) - Guestbook application
Clojure
3
star
64

clj-forum

a forum for Clojure related news and discussions
Clojure
3
star
65

oauth-example

Clojure
3
star
66

json-to-pdf-example

example project for the json-to-pdf library
Java
2
star
67

picture-gallery

sample Reagent project
Clojure
2
star
68

buddhabrot

Nakkaya's Buddhabrot Fractal (http://nakkaya.com/2009/10/04/fractals-in-clojure-buddhabrot-fractal/)
Clojure
2
star
69

Lorenz-Attractor

Clojure
2
star
70

repo-tracker

Clojure
2
star
71

hoplon-app

sample Hoplon project using Leiningen and Figwheel
Clojure
2
star
72

Noir-tutorial

the project for my Noir tutorial http://yogthos.net/blog/22-Noir+tutorial+-+part+1
Clojure
2
star
73

luminusdiff

Clojure
1
star
74

guestbook-sente

sample sente app
Clojure
1
star
75

ring-external-assets

Ring middleware to serve static assets from the specified fielsystem location
Clojure
1
star
76

lein-js

updated version of https://github.com/maravillas/lein-js
Clojure
1
star
77

mojs-reagent

Clojure
1
star
78

kit-ruuter-example

Clojure
1
star
79

reagent-talk

example for the Reagent lightning talk
Clojure
1
star
80

undertow-test

Clojure
1
star
81

selmer-test

Clojure
1
star
82

yogthos.github.com

docs
HTML
1
star
83

instant-html-pdf

HTML to PDF generation service
Clojure
1
star
84

quil-lorenz-attractor

Clojure
1
star
85

re-frame-mobile-test

Clojure
1
star
86

rewrite-clj-experiments

Clojure
1
star
87

forms-test

test project for reagent-forms
Clojure
1
star
88

jar-migrations

Clojure
1
star
89

hyperfiler

fork from https://codeberg.org/chowderman/hyperfiler
TypeScript
1
star
90

puppeteer-service

a service for generating PDF documents from HTML
Clojure
1
star
91

luminus-reitit-swagger

Clojure
1
star
92

bb-htmx-examples

Clojure
1
star
93

metaballs

metaballs test in Clojure
Clojure
1
star
94

jipsi

an implementation of the Java Print Service API (JPS) for IPP / CUPS
Java
1
star
95

clojure.jdbc

JDBC library for Clojure
Clojure
1
star
96

http-kit-ws-benchmark

HTTP Kit WebSocket benchmark
Clojure
1
star
97

parity-translator

translates through languages until parity is reached :)
Clojure
1
star
98

ga-image-evolver-test

An experminet in evolving an image using polygons, based on the Clojure-Genetic-Algorithm-Example
Clojure
1
star