1 | Blackfriday
|
---|
2 | [![Build Status][BuildV2SVG]][BuildV2URL]
|
---|
3 | [![PkgGoDev][PkgGoDevV2SVG]][PkgGoDevV2URL]
|
---|
4 | ===========
|
---|
5 |
|
---|
6 | Blackfriday is a [Markdown][1] processor implemented in [Go][2]. It
|
---|
7 | is paranoid about its input (so you can safely feed it user-supplied
|
---|
8 | data), it is fast, it supports common extensions (tables, smart
|
---|
9 | punctuation substitutions, etc.), and it is safe for all utf-8
|
---|
10 | (unicode) input.
|
---|
11 |
|
---|
12 | HTML output is currently supported, along with Smartypants
|
---|
13 | extensions.
|
---|
14 |
|
---|
15 | It started as a translation from C of [Sundown][3].
|
---|
16 |
|
---|
17 |
|
---|
18 | Installation
|
---|
19 | ------------
|
---|
20 |
|
---|
21 | Blackfriday is compatible with modern Go releases in module mode.
|
---|
22 | With Go installed:
|
---|
23 |
|
---|
24 | go get github.com/russross/blackfriday/v2
|
---|
25 |
|
---|
26 | will resolve and add the package to the current development module,
|
---|
27 | then build and install it. Alternatively, you can achieve the same
|
---|
28 | if you import it in a package:
|
---|
29 |
|
---|
30 | import "github.com/russross/blackfriday/v2"
|
---|
31 |
|
---|
32 | and `go get` without parameters.
|
---|
33 |
|
---|
34 | Legacy GOPATH mode is unsupported.
|
---|
35 |
|
---|
36 |
|
---|
37 | Versions
|
---|
38 | --------
|
---|
39 |
|
---|
40 | Currently maintained and recommended version of Blackfriday is `v2`. It's being
|
---|
41 | developed on its own branch: https://github.com/russross/blackfriday/tree/v2 and the
|
---|
42 | documentation is available at
|
---|
43 | https://pkg.go.dev/github.com/russross/blackfriday/v2.
|
---|
44 |
|
---|
45 | It is `go get`-able in module mode at `github.com/russross/blackfriday/v2`.
|
---|
46 |
|
---|
47 | Version 2 offers a number of improvements over v1:
|
---|
48 |
|
---|
49 | * Cleaned up API
|
---|
50 | * A separate call to [`Parse`][4], which produces an abstract syntax tree for
|
---|
51 | the document
|
---|
52 | * Latest bug fixes
|
---|
53 | * Flexibility to easily add your own rendering extensions
|
---|
54 |
|
---|
55 | Potential drawbacks:
|
---|
56 |
|
---|
57 | * Our benchmarks show v2 to be slightly slower than v1. Currently in the
|
---|
58 | ballpark of around 15%.
|
---|
59 | * API breakage. If you can't afford modifying your code to adhere to the new API
|
---|
60 | and don't care too much about the new features, v2 is probably not for you.
|
---|
61 | * Several bug fixes are trailing behind and still need to be forward-ported to
|
---|
62 | v2. See issue [#348](https://github.com/russross/blackfriday/issues/348) for
|
---|
63 | tracking.
|
---|
64 |
|
---|
65 | If you are still interested in the legacy `v1`, you can import it from
|
---|
66 | `github.com/russross/blackfriday`. Documentation for the legacy v1 can be found
|
---|
67 | here: https://pkg.go.dev/github.com/russross/blackfriday.
|
---|
68 |
|
---|
69 |
|
---|
70 | Usage
|
---|
71 | -----
|
---|
72 |
|
---|
73 | For the most sensible markdown processing, it is as simple as getting your input
|
---|
74 | into a byte slice and calling:
|
---|
75 |
|
---|
76 | ```go
|
---|
77 | output := blackfriday.Run(input)
|
---|
78 | ```
|
---|
79 |
|
---|
80 | Your input will be parsed and the output rendered with a set of most popular
|
---|
81 | extensions enabled. If you want the most basic feature set, corresponding with
|
---|
82 | the bare Markdown specification, use:
|
---|
83 |
|
---|
84 | ```go
|
---|
85 | output := blackfriday.Run(input, blackfriday.WithNoExtensions())
|
---|
86 | ```
|
---|
87 |
|
---|
88 | ### Sanitize untrusted content
|
---|
89 |
|
---|
90 | Blackfriday itself does nothing to protect against malicious content. If you are
|
---|
91 | dealing with user-supplied markdown, we recommend running Blackfriday's output
|
---|
92 | through HTML sanitizer such as [Bluemonday][5].
|
---|
93 |
|
---|
94 | Here's an example of simple usage of Blackfriday together with Bluemonday:
|
---|
95 |
|
---|
96 | ```go
|
---|
97 | import (
|
---|
98 | "github.com/microcosm-cc/bluemonday"
|
---|
99 | "github.com/russross/blackfriday/v2"
|
---|
100 | )
|
---|
101 |
|
---|
102 | // ...
|
---|
103 | unsafe := blackfriday.Run(input)
|
---|
104 | html := bluemonday.UGCPolicy().SanitizeBytes(unsafe)
|
---|
105 | ```
|
---|
106 |
|
---|
107 | ### Custom options
|
---|
108 |
|
---|
109 | If you want to customize the set of options, use `blackfriday.WithExtensions`,
|
---|
110 | `blackfriday.WithRenderer` and `blackfriday.WithRefOverride`.
|
---|
111 |
|
---|
112 | ### `blackfriday-tool`
|
---|
113 |
|
---|
114 | You can also check out `blackfriday-tool` for a more complete example
|
---|
115 | of how to use it. Download and install it using:
|
---|
116 |
|
---|
117 | go get github.com/russross/blackfriday-tool
|
---|
118 |
|
---|
119 | This is a simple command-line tool that allows you to process a
|
---|
120 | markdown file using a standalone program. You can also browse the
|
---|
121 | source directly on github if you are just looking for some example
|
---|
122 | code:
|
---|
123 |
|
---|
124 | * <https://github.com/russross/blackfriday-tool>
|
---|
125 |
|
---|
126 | Note that if you have not already done so, installing
|
---|
127 | `blackfriday-tool` will be sufficient to download and install
|
---|
128 | blackfriday in addition to the tool itself. The tool binary will be
|
---|
129 | installed in `$GOPATH/bin`. This is a statically-linked binary that
|
---|
130 | can be copied to wherever you need it without worrying about
|
---|
131 | dependencies and library versions.
|
---|
132 |
|
---|
133 | ### Sanitized anchor names
|
---|
134 |
|
---|
135 | Blackfriday includes an algorithm for creating sanitized anchor names
|
---|
136 | corresponding to a given input text. This algorithm is used to create
|
---|
137 | anchors for headings when `AutoHeadingIDs` extension is enabled. The
|
---|
138 | algorithm has a specification, so that other packages can create
|
---|
139 | compatible anchor names and links to those anchors.
|
---|
140 |
|
---|
141 | The specification is located at https://pkg.go.dev/github.com/russross/blackfriday/v2#hdr-Sanitized_Anchor_Names.
|
---|
142 |
|
---|
143 | [`SanitizedAnchorName`](https://pkg.go.dev/github.com/russross/blackfriday/v2#SanitizedAnchorName) exposes this functionality, and can be used to
|
---|
144 | create compatible links to the anchor names generated by blackfriday.
|
---|
145 | This algorithm is also implemented in a small standalone package at
|
---|
146 | [`github.com/shurcooL/sanitized_anchor_name`](https://pkg.go.dev/github.com/shurcooL/sanitized_anchor_name). It can be useful for clients
|
---|
147 | that want a small package and don't need full functionality of blackfriday.
|
---|
148 |
|
---|
149 |
|
---|
150 | Features
|
---|
151 | --------
|
---|
152 |
|
---|
153 | All features of Sundown are supported, including:
|
---|
154 |
|
---|
155 | * **Compatibility**. The Markdown v1.0.3 test suite passes with
|
---|
156 | the `--tidy` option. Without `--tidy`, the differences are
|
---|
157 | mostly in whitespace and entity escaping, where blackfriday is
|
---|
158 | more consistent and cleaner.
|
---|
159 |
|
---|
160 | * **Common extensions**, including table support, fenced code
|
---|
161 | blocks, autolinks, strikethroughs, non-strict emphasis, etc.
|
---|
162 |
|
---|
163 | * **Safety**. Blackfriday is paranoid when parsing, making it safe
|
---|
164 | to feed untrusted user input without fear of bad things
|
---|
165 | happening. The test suite stress tests this and there are no
|
---|
166 | known inputs that make it crash. If you find one, please let me
|
---|
167 | know and send me the input that does it.
|
---|
168 |
|
---|
169 | NOTE: "safety" in this context means *runtime safety only*. In order to
|
---|
170 | protect yourself against JavaScript injection in untrusted content, see
|
---|
171 | [this example](https://github.com/russross/blackfriday#sanitize-untrusted-content).
|
---|
172 |
|
---|
173 | * **Fast processing**. It is fast enough to render on-demand in
|
---|
174 | most web applications without having to cache the output.
|
---|
175 |
|
---|
176 | * **Thread safety**. You can run multiple parsers in different
|
---|
177 | goroutines without ill effect. There is no dependence on global
|
---|
178 | shared state.
|
---|
179 |
|
---|
180 | * **Minimal dependencies**. Blackfriday only depends on standard
|
---|
181 | library packages in Go. The source code is pretty
|
---|
182 | self-contained, so it is easy to add to any project, including
|
---|
183 | Google App Engine projects.
|
---|
184 |
|
---|
185 | * **Standards compliant**. Output successfully validates using the
|
---|
186 | W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional.
|
---|
187 |
|
---|
188 |
|
---|
189 | Extensions
|
---|
190 | ----------
|
---|
191 |
|
---|
192 | In addition to the standard markdown syntax, this package
|
---|
193 | implements the following extensions:
|
---|
194 |
|
---|
195 | * **Intra-word emphasis supression**. The `_` character is
|
---|
196 | commonly used inside words when discussing code, so having
|
---|
197 | markdown interpret it as an emphasis command is usually the
|
---|
198 | wrong thing. Blackfriday lets you treat all emphasis markers as
|
---|
199 | normal characters when they occur inside a word.
|
---|
200 |
|
---|
201 | * **Tables**. Tables can be created by drawing them in the input
|
---|
202 | using a simple syntax:
|
---|
203 |
|
---|
204 | ```
|
---|
205 | Name | Age
|
---|
206 | --------|------
|
---|
207 | Bob | 27
|
---|
208 | Alice | 23
|
---|
209 | ```
|
---|
210 |
|
---|
211 | * **Fenced code blocks**. In addition to the normal 4-space
|
---|
212 | indentation to mark code blocks, you can explicitly mark them
|
---|
213 | and supply a language (to make syntax highlighting simple). Just
|
---|
214 | mark it like this:
|
---|
215 |
|
---|
216 | ```go
|
---|
217 | func getTrue() bool {
|
---|
218 | return true
|
---|
219 | }
|
---|
220 | ```
|
---|
221 |
|
---|
222 | You can use 3 or more backticks to mark the beginning of the
|
---|
223 | block, and the same number to mark the end of the block.
|
---|
224 |
|
---|
225 | To preserve classes of fenced code blocks while using the bluemonday
|
---|
226 | HTML sanitizer, use the following policy:
|
---|
227 |
|
---|
228 | ```go
|
---|
229 | p := bluemonday.UGCPolicy()
|
---|
230 | p.AllowAttrs("class").Matching(regexp.MustCompile("^language-[a-zA-Z0-9]+$")).OnElements("code")
|
---|
231 | html := p.SanitizeBytes(unsafe)
|
---|
232 | ```
|
---|
233 |
|
---|
234 | * **Definition lists**. A simple definition list is made of a single-line
|
---|
235 | term followed by a colon and the definition for that term.
|
---|
236 |
|
---|
237 | Cat
|
---|
238 | : Fluffy animal everyone likes
|
---|
239 |
|
---|
240 | Internet
|
---|
241 | : Vector of transmission for pictures of cats
|
---|
242 |
|
---|
243 | Terms must be separated from the previous definition by a blank line.
|
---|
244 |
|
---|
245 | * **Footnotes**. A marker in the text that will become a superscript number;
|
---|
246 | a footnote definition that will be placed in a list of footnotes at the
|
---|
247 | end of the document. A footnote looks like this:
|
---|
248 |
|
---|
249 | This is a footnote.[^1]
|
---|
250 |
|
---|
251 | [^1]: the footnote text.
|
---|
252 |
|
---|
253 | * **Autolinking**. Blackfriday can find URLs that have not been
|
---|
254 | explicitly marked as links and turn them into links.
|
---|
255 |
|
---|
256 | * **Strikethrough**. Use two tildes (`~~`) to mark text that
|
---|
257 | should be crossed out.
|
---|
258 |
|
---|
259 | * **Hard line breaks**. With this extension enabled newlines in the input
|
---|
260 | translate into line breaks in the output. This extension is off by default.
|
---|
261 |
|
---|
262 | * **Smart quotes**. Smartypants-style punctuation substitution is
|
---|
263 | supported, turning normal double- and single-quote marks into
|
---|
264 | curly quotes, etc.
|
---|
265 |
|
---|
266 | * **LaTeX-style dash parsing** is an additional option, where `--`
|
---|
267 | is translated into `–`, and `---` is translated into
|
---|
268 | `—`. This differs from most smartypants processors, which
|
---|
269 | turn a single hyphen into an ndash and a double hyphen into an
|
---|
270 | mdash.
|
---|
271 |
|
---|
272 | * **Smart fractions**, where anything that looks like a fraction
|
---|
273 | is translated into suitable HTML (instead of just a few special
|
---|
274 | cases like most smartypant processors). For example, `4/5`
|
---|
275 | becomes `<sup>4</sup>⁄<sub>5</sub>`, which renders as
|
---|
276 | <sup>4</sup>⁄<sub>5</sub>.
|
---|
277 |
|
---|
278 |
|
---|
279 | Other renderers
|
---|
280 | ---------------
|
---|
281 |
|
---|
282 | Blackfriday is structured to allow alternative rendering engines. Here
|
---|
283 | are a few of note:
|
---|
284 |
|
---|
285 | * [github_flavored_markdown](https://pkg.go.dev/github.com/shurcooL/github_flavored_markdown):
|
---|
286 | provides a GitHub Flavored Markdown renderer with fenced code block
|
---|
287 | highlighting, clickable heading anchor links.
|
---|
288 |
|
---|
289 | It's not customizable, and its goal is to produce HTML output
|
---|
290 | equivalent to the [GitHub Markdown API endpoint](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode),
|
---|
291 | except the rendering is performed locally.
|
---|
292 |
|
---|
293 | * [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt,
|
---|
294 | but for markdown.
|
---|
295 |
|
---|
296 | * [LaTeX output](https://gitlab.com/ambrevar/blackfriday-latex):
|
---|
297 | renders output as LaTeX.
|
---|
298 |
|
---|
299 | * [bfchroma](https://github.com/Depado/bfchroma/): provides convenience
|
---|
300 | integration with the [Chroma](https://github.com/alecthomas/chroma) code
|
---|
301 | highlighting library. bfchroma is only compatible with v2 of Blackfriday and
|
---|
302 | provides a drop-in renderer ready to use with Blackfriday, as well as
|
---|
303 | options and means for further customization.
|
---|
304 |
|
---|
305 | * [Blackfriday-Confluence](https://github.com/kentaro-m/blackfriday-confluence): provides a [Confluence Wiki Markup](https://confluence.atlassian.com/doc/confluence-wiki-markup-251003035.html) renderer.
|
---|
306 |
|
---|
307 | * [Blackfriday-Slack](https://github.com/karriereat/blackfriday-slack): converts markdown to slack message style
|
---|
308 |
|
---|
309 |
|
---|
310 | TODO
|
---|
311 | ----
|
---|
312 |
|
---|
313 | * More unit testing
|
---|
314 | * Improve Unicode support. It does not understand all Unicode
|
---|
315 | rules (about what constitutes a letter, a punctuation symbol,
|
---|
316 | etc.), so it may fail to detect word boundaries correctly in
|
---|
317 | some instances. It is safe on all UTF-8 input.
|
---|
318 |
|
---|
319 |
|
---|
320 | License
|
---|
321 | -------
|
---|
322 |
|
---|
323 | [Blackfriday is distributed under the Simplified BSD License](LICENSE.txt)
|
---|
324 |
|
---|
325 |
|
---|
326 | [1]: https://daringfireball.net/projects/markdown/ "Markdown"
|
---|
327 | [2]: https://golang.org/ "Go Language"
|
---|
328 | [3]: https://github.com/vmg/sundown "Sundown"
|
---|
329 | [4]: https://pkg.go.dev/github.com/russross/blackfriday/v2#Parse "Parse func"
|
---|
330 | [5]: https://github.com/microcosm-cc/bluemonday "Bluemonday"
|
---|
331 |
|
---|
332 | [BuildV2SVG]: https://travis-ci.org/russross/blackfriday.svg?branch=v2
|
---|
333 | [BuildV2URL]: https://travis-ci.org/russross/blackfriday
|
---|
334 | [PkgGoDevV2SVG]: https://pkg.go.dev/badge/github.com/russross/blackfriday/v2
|
---|
335 | [PkgGoDevV2URL]: https://pkg.go.dev/github.com/russross/blackfriday/v2
|
---|