1# Markdown Parser and HTML Renderer for Go
2
3[](https://godoc.org/github.com/gomarkdown/markdown) [](https://codecov.io/gh/gomarkdown/markdown)
4
5Package `github.com/gomarkdown/markdown` is a very fast Go library for parsing [Markdown](https://daringfireball.net/projects/markdown/) documents and rendering them to HTML.
6
7It's fast and supports common extensions.
8
9## Installation
10
11 go get -u github.com/gomarkdown/markdown
12
13API Docs:
14
15- https://godoc.org/github.com/gomarkdown/markdown : top level package
16- https://godoc.org/github.com/gomarkdown/markdown/ast : defines abstract syntax tree of parsed markdown document
17- https://godoc.org/github.com/gomarkdown/markdown/parser : parser
18- https://godoc.org/github.com/gomarkdown/markdown/html : html renderer
19
20## Usage
21
22To convert markdown text to HTML using reasonable defaults:
23
24```go
25md := []byte("## markdown document")
26output := markdown.ToHTML(md, nil, nil)
27```
28
29## Customizing markdown parser
30
31Markdown format is loosely specified and there are multiple extensions invented after original specification was created.
32
33The parser supports several [extensions](https://godoc.org/github.com/gomarkdown/markdown/parser#Extensions).
34
35Default parser uses most common `parser.CommonExtensions` but you can easily use parser with custom extension:
36
37```go
38import (
39 "github.com/gomarkdown/markdown"
40 "github.com/gomarkdown/markdown/parser"
41)
42
43extensions := parser.CommonExtensions | parser.AutoHeadingIDs
44parser := parser.NewWithExtensions(extensions)
45
46md := []byte("markdown text")
47html := markdown.ToHTML(md, parser, nil)
48```
49
50## Customizing HTML renderer
51
52Similarly, HTML renderer can be configured with different [options](https://godoc.org/github.com/gomarkdown/markdown/html#RendererOptions)
53
54Here's how to use a custom renderer:
55
56```go
57import (
58 "github.com/gomarkdown/markdown"
59 "github.com/gomarkdown/markdown/html"
60)
61
62htmlFlags := html.CommonFlags | html.HrefTargetBlank
63opts := html.RendererOptions{Flags: htmlFlags}
64renderer := html.NewRenderer(opts)
65
66md := []byte("markdown text")
67html := markdown.ToHTML(md, nil, renderer)
68```
69
70HTML renderer also supports reusing most of the logic and overriding rendering of only specifc nodes.
71
72You can provide [RenderNodeFunc](https://godoc.org/github.com/gomarkdown/markdown/html#RenderNodeFunc) in [RendererOptions](https://godoc.org/github.com/gomarkdown/markdown/html#RendererOptions).
73
74The function is called for each node in AST, you can implement custom rendering logic and tell HTML renderer to skip rendering this node.
75
76Here's the simplest example that drops all code blocks from the output:
77
78````go
79import (
80 "github.com/gomarkdown/markdown"
81 "github.com/gomarkdown/markdown/ast"
82 "github.com/gomarkdown/markdown/html"
83)
84
85// return (ast.GoToNext, true) to tell html renderer to skip rendering this node
86// (because you've rendered it)
87func renderHookDropCodeBlock(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) {
88 // skip all nodes that are not CodeBlock nodes
89 if _, ok := node.(*ast.CodeBlock); !ok {
90 return ast.GoToNext, false
91 }
92 // custom rendering logic for ast.CodeBlock. By doing nothing it won't be
93 // present in the output
94 return ast.GoToNext, true
95}
96
97opts := html.RendererOptions{
98 Flags: html.CommonFlags,
99 RenderNodeHook: renderHookDropCodeBlock,
100}
101renderer := html.NewRenderer(opts)
102md := "test\n```\nthis code block will be dropped from output\n```\ntext"
103html := markdown.ToHTML([]byte(s), nil, renderer)
104````
105
106## Sanitize untrusted content
107
108We don't protect against malicious content. When dealing with user-provided
109markdown, run renderer HTML through HTML sanitizer such as [Bluemonday](https://github.com/microcosm-cc/bluemonday).
110
111Here's an example of simple usage with Bluemonday:
112
113```go
114import (
115 "github.com/microcosm-cc/bluemonday"
116 "github.com/gomarkdown/markdown"
117)
118
119// ...
120maybeUnsafeHTML := markdown.ToHTML(md, nil, nil)
121html := bluemonday.UGCPolicy().SanitizeBytes(maybeUnsafeHTML)
122```
123
124## mdtohtml command-line tool
125
126https://github.com/gomarkdown/mdtohtml is a command-line markdown to html
127converter built using this library.
128
129You can also use it as an example of how to use the library.
130
131You can install it with:
132
133 go get -u github.com/gomarkdown/mdtohtml
134
135To run: `mdtohtml input-file [output-file]`
136
137## Features
138
139- **Compatibility**. The Markdown v1.0.3 test suite passes with
140 the `--tidy` option. Without `--tidy`, the differences are
141 mostly in whitespace and entity escaping, where this package is
142 more consistent and cleaner.
143
144- **Common extensions**, including table support, fenced code
145 blocks, autolinks, strikethroughs, non-strict emphasis, etc.
146
147- **Safety**. Markdown is paranoid when parsing, making it safe
148 to feed untrusted user input without fear of bad things
149 happening. The test suite stress tests this and there are no
150 known inputs that make it crash. If you find one, please let me
151 know and send me the input that does it.
152
153 NOTE: "safety" in this context means _runtime safety only_. In order to
154 protect yourself against JavaScript injection in untrusted content, see
155 [this example](https://github.com/gomarkdown/markdown#sanitize-untrusted-content).
156
157- **Fast**. It is fast enough to render on-demand in
158 most web applications without having to cache the output.
159
160- **Thread safety**. You can run multiple parsers in different
161 goroutines without ill effect. There is no dependence on global
162 shared state.
163
164- **Minimal dependencies**. Only depends on standard library packages in Go.
165
166- **Standards compliant**. Output successfully validates using the
167 W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional.
168
169## Extensions
170
171In addition to the standard markdown syntax, this package
172implements the following extensions:
173
174- **Intra-word emphasis supression**. The `_` character is
175 commonly used inside words when discussing code, so having
176 markdown interpret it as an emphasis command is usually the
177 wrong thing. We let you treat all emphasis markers as
178 normal characters when they occur inside a word.
179
180- **Tables**. Tables can be created by drawing them in the input
181 using a simple syntax:
182
183 ```
184 Name | Age
185 --------|------
186 Bob | 27
187 Alice | 23
188 ```
189
190 Table footers are supported as well and can be added with equal signs (`=`):
191
192 ```
193 Name | Age
194 --------|------
195 Bob | 27
196 Alice | 23
197 ========|======
198 Total | 50
199 ```
200
201- **Fenced code blocks**. In addition to the normal 4-space
202 indentation to mark code blocks, you can explicitly mark them
203 and supply a language (to make syntax highlighting simple). Just
204 mark it like this:
205
206 ```go
207 func getTrue() bool {
208 return true
209 }
210 ```
211
212 You can use 3 or more backticks to mark the beginning of the
213 block, and the same number to mark the end of the block.
214
215- **Definition lists**. A simple definition list is made of a single-line
216 term followed by a colon and the definition for that term.
217
218 Cat
219 : Fluffy animal everyone likes
220
221 Internet
222 : Vector of transmission for pictures of cats
223
224 Terms must be separated from the previous definition by a blank line.
225
226- **Footnotes**. A marker in the text that will become a superscript number;
227 a footnote definition that will be placed in a list of footnotes at the
228 end of the document. A footnote looks like this:
229
230 This is a footnote.[^1]
231
232 [^1]: the footnote text.
233
234- **Autolinking**. We can find URLs that have not been
235 explicitly marked as links and turn them into links.
236
237- **Strikethrough**. Use two tildes (`~~`) to mark text that
238 should be crossed out.
239
240- **Hard line breaks**. With this extension enabled newlines in the input
241 translate into line breaks in the output. This extension is off by default.
242
243- **Non blocking space**. With this extension enabled spaces preceeded by an backslash n the input
244 translate non-blocking spaces in the output. This extension is off by default.
245
246- **Smart quotes**. Smartypants-style punctuation substitution is
247 supported, turning normal double- and single-quote marks into
248 curly quotes, etc.
249
250- **LaTeX-style dash parsing** is an additional option, where `--`
251 is translated into `–`, and `---` is translated into
252 `—`. This differs from most smartypants processors, which
253 turn a single hyphen into an ndash and a double hyphen into an
254 mdash.
255
256- **Smart fractions**, where anything that looks like a fraction
257 is translated into suitable HTML (instead of just a few special
258 cases like most smartypant processors). For example, `4/5`
259 becomes `<sup>4</sup>⁄<sub>5</sub>`, which renders as
260 <sup>4</sup>⁄<sub>5</sub>.
261
262- **MathJaX Support** is an additional feature which is supported by
263 many markdown editor. It translate inline math equation quoted by `$`
264 and display math block quoted by `$$` into MathJax compatible format.
265 hyphen `_` won't break LaTeX render within a math element any more.
266
267 ```
268 $$
269 \left[ \begin{array}{a} a^l_1 \\ ⋮ \\ a^l_{d_l} \end{array}\right]
270 = \sigma(
271 \left[ \begin{matrix}
272 w^l_{1,1} & ⋯ & w^l_{1,d_{l-1}} \\
273 ⋮ & ⋱ & ⋮ \\
274 w^l_{d_l,1} & ⋯ & w^l_{d_l,d_{l-1}} \\
275 \end{matrix}\right] ·
276 \left[ \begin{array}{x} a^{l-1}_1 \\ ⋮ \\ ⋮ \\ a^{l-1}_{d_{l-1}} \end{array}\right] +
277 \left[ \begin{array}{b} b^l_1 \\ ⋮ \\ b^l_{d_l} \end{array}\right])
278 $$
279 ```
280
281- **Ordered list start number**. With this extension enabled an ordered list will start with the
282 the number that was used to start it.
283
284- **Super and subscript**. With this extension enabled sequences between ^ will indicate
285 superscript and ~ will become a subscript. For example: H~2~O is a liquid, 2^10^ is 1024.
286
287- **Block level attributes**, allow setting attributes (ID, classes and key/value pairs) on block
288 level elements. The attribute must be enclosed with braces and be put on a line before the
289 element.
290
291 ```
292 {#id3 .myclass fontsize="tiny"}
293 # Header 1
294 ```
295
296 Will convert into `<h1 id="id3" class="myclass" fontsize="tiny">Header 1</h1>`.
297
298- **Mmark support**, see <https://mmark.miek.nl/post/syntax/> for all new syntax elements this adds.
299
300## Todo
301
302- port https://github.com/russross/blackfriday/issues/348
303- port [LaTeX output](https://github.com/Ambrevar/Blackfriday-LaTeX):
304 renders output as LaTeX.
305- port https://github.com/shurcooL/github_flavored_markdown to markdown
306- port [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt,
307 but for markdown.
308- More unit testing
309- Improve unicode support. It does not understand all unicode
310 rules (about what constitutes a letter, a punctuation symbol,
311 etc.), so it may fail to detect word boundaries correctly in
312 some instances. It is safe on all utf-8 input.
313
314## History
315
316markdown is a fork of v2 of https://github.com/russross/blackfriday that is:
317
318- actively maintained (sadly in Feb 2018 blackfriday was inactive for 5 months with many bugs and pull requests accumulated)
319- refactored API (split into ast/parser/html sub-packages)
320
321Blackfriday itself was based on C implementation [sundown](https://github.com/vmg/sundown) which in turn was based on [libsoldout](http://fossil.instinctive.eu/libsoldout/home).
322
323## License
324
325[Simplified BSD License](LICENSE.txt)