Skip to content

Commit eaf3ad3

Browse files
authored
Merge pull request #428 from kivikakk/commonmark-gfm
Support both upstream CommonMark and GFM's differences in the base spec.
2 parents 09f7188 + 7c99585 commit eaf3ad3

File tree

20 files changed

+509
-364
lines changed

20 files changed

+509
-364
lines changed

.gitmodules

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
[submodule "vendor/cmark-gfm"]
22
path = vendor/cmark-gfm
3-
url = https://github.com/github/cmark-gfm.git
3+
url = https://github.com/kivikakk/cmark-gfm.git
44
[submodule "vendor/pulldown-cmark"]
55
path = vendor/pulldown-cmark
66
url = https://github.com/raphlinus/pulldown-cmark.git
77
[submodule "vendor/markdown-it"]
88
path = vendor/markdown-it
99
url = https://github.com/rlidwka/markdown-it.rs.git
10+
[submodule "vendor/commonmark-spec"]
11+
path = vendor/commonmark-spec
12+
url = https://github.com/commonmark/commonmark-spec

Cargo.lock

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ slug = "0.1.4"
4646
emojis = { version = "0.6.2", optional = true }
4747
arbitrary = { version = "1", optional = true, features = ["derive"] }
4848
derive_builder = "0.20.0"
49+
caseless = "0.2.1"
4950

5051
[dev-dependencies]
5152
ntest = "0.9"

README.md

Lines changed: 92 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
# [Comrak](https://github.com/kivikakk/comrak)
22

3-
[![Build Status](https://github.com/kivikakk/comrak/actions/workflows/rust.yml/badge.svg)](https://github.com/kivikakk/comrak/actions/workflows/rust.yml) ![Spec
4-
Status: 671/671](https://img.shields.io/badge/specs-671%2F671-brightgreen.svg)
3+
[![Build status](https://github.com/kivikakk/comrak/actions/workflows/rust.yml/badge.svg)](https://github.com/kivikakk/comrak/actions/workflows/rust.yml)
4+
[![CommonMark: 652/652](https://img.shields.io/badge/commonmark-652%2F652-brightgreen.svg)](https://github.com/commonmark/commonmark-spec/blob/9103e341a973013013bb1a80e13567007c5cef6f/spec.txt)
5+
[![GFM: 670/670](https://img.shields.io/badge/gfm-670%2F670-brightgreen.svg)](https://github.com/kivikakk/cmark-gfm/blob/2f13eeedfe9906c72a1843b03552550af7bee29a/test/spec.txt)
56
[![crates.io version](https://img.shields.io/crates/v/comrak.svg)](https://crates.io/crates/comrak)
67
[![docs.rs](https://docs.rs/comrak/badge.svg)](https://docs.rs/comrak)
78

8-
Rust port of [github's `cmark-gfm`](https://github.com/github/cmark). *Currently synced with release `0.29.0.gfm.13`*.
9+
Rust port of [github's `cmark-gfm`](https://github.com/github/cmark-gfm).
910

10-
- [Installation](#installation)
11-
- [Usage](#usage)
12-
- [Security](#security)
13-
- [Extensions](#extensions)
14-
- [Related projects](#related-projects)
15-
- [Contributing](#contributing)
16-
- [Legal](#legal)
11+
Compliant with [CommonMark 0.31.2](https://spec.commonmark.org/0.31.2/) in default mode.
12+
GFM support synced with release `0.29.0.gfm.13`.
1713

1814
## Installation
1915

@@ -26,22 +22,31 @@ comrak = "0.24"
2622

2723
Comrak's library supports Rust <span class="msrv">1.62.1</span>+.
2824

29-
### Mac & Linux Binaries
25+
### CLI
3026

31-
``` bash
32-
curl https://webinstall.dev/comrak | bash
33-
```
27+
- Anywhere with a Rust toolchain:
28+
- `cargo install comrak`
29+
- Many Unix distributions:
30+
- `pacman -S comrak`
31+
- `brew install comrak`
32+
- `dnf install comrak`
33+
- `nix run nixpkgs#comrak`
3434

35-
### Windows 10 Binaries
36-
37-
``` powershell
38-
curl.exe -A "MS" https://webinstall.dev/comrak | powershell
39-
```
35+
You can also find builds I've published in [GitHub Releases](https://github.com/kivikakk/comrak/releases), but they're limited to machines I have access to at the time of making them\! [webinstall.dev](https://webinstall.dev/comrak/) offers `curl | shell`-style installation of the latest of these for your OS.
4036

4137
## Usage
4238

39+
<details>
40+
41+
<summary>Click to expand the CLI <code>--help</code> output.
42+
4343
``` console
4444
$ comrak --help
45+
```
46+
47+
</summary>
48+
49+
```
4550
A 100% CommonMark-compatible GitHub Flavored Markdown parser and formatter
4651
4752
Usage: comrak [OPTIONS] [FILE]...
@@ -54,7 +59,7 @@ Options:
5459
-c, --config-file <PATH>
5560
Path to config file containing command-line arguments, or 'none'
5661
57-
[default: /home/runner/.config/comrak/config]
62+
[default: /Users/kivikakk/.config/comrak/config]
5863
5964
-i, --inplace
6065
To perform an in-place formatting
@@ -73,7 +78,11 @@ Options:
7378
7479
--gfm
7580
Enable GitHub-flavored markdown extensions: strikethrough, tagfilter, table, autolink, and
76-
tasklist. Also enables --github-pre-lang
81+
tasklist. Also enables --github-pre-lang and --gfm-quirks
82+
83+
--gfm-quirks
84+
Enables GFM-style quirks in output HTML, such as not nesting <strong> tags, which
85+
otherwise breaks CommonMark compatibility
7786
7887
--relaxed-tasklist-character
7988
Enable relaxing which character is allowed in a tasklists
@@ -104,7 +113,7 @@ Options:
104113
105114
[possible values: strikethrough, tagfilter, table, autolink, tasklist, superscript,
106115
footnotes, description-lists, multiline-block-quotes, math-dollars, math-code,
107-
wikilinks-title-after-pipe, wikilinks-title-before-pipe]
116+
wikilinks-title-after-pipe, wikilinks-title-before-pipe, underline, spoiler, greentext]
108117
109118
-t, --to <FORMAT>
110119
Specify output format
@@ -140,6 +149,12 @@ Options:
140149
--sourcepos
141150
Include source position attribute in HTML and XML output
142151
152+
--ignore-setext
153+
Ignore setext headers
154+
155+
--ignore-empty-links
156+
Ignore empty links
157+
143158
-h, --help
144159
Print help information (use `-h` for a summary)
145160
@@ -151,6 +166,8 @@ By default, Comrak will attempt to read command-line options from a config file
151166
the file does not exist.
152167
```
153168

169+
</details>
170+
154171
And there's a Rust interface. You can use `comrak::markdown_to_html` directly:
155172

156173
``` rust
@@ -162,7 +179,6 @@ assert_eq!(markdown_to_html("Hello, **世界**!", &Options::default()),
162179
Or you can parse the input into an AST yourself, manipulate it, and then use your desired formatter:
163180

164181
``` rust
165-
extern crate comrak;
166182
use comrak::nodes::NodeValue;
167183
use comrak::{format_html, parse_document, Arena, Options};
168184

@@ -194,42 +210,24 @@ fn main() {
194210
let html = replace_text(&doc, &orig, &repl);
195211

196212
println!("{}", html);
213+
// Output:
214+
//
215+
// <p>This is your input.</p>
216+
// <ol>
217+
// <li>Also <a href="#">your</a> input.</li>
218+
// <li>Certainly <em>your</em> input.</li>
219+
// </ol>
197220
}
198221
```
199222

200-
## Benchmarking
201-
202-
For running benchmarks, you will need to [install hyperfine](https://github.com/sharkdp/hyperfine#installation) and optionally cmake.
203-
204-
If you want to just run the benchmark for `comrak`, with the current state of the repo, you can simply run
205-
206-
``` bash
207-
make bench-comrak
208-
```
209-
210-
This will build comrak in release mode, and run benchmark on it. You will see the time measurements as reported by hyperfine in the console.
211-
212-
Makefile also provides a way to run benchmarks for `comrak` current state (with your changes), `comrak` main branch, [`cmark-gfm`](https://github.com/github/cmark-gfm), [`pulldown-cmark`](https://github.com/raphlinus/pulldown-cmark) and [`markdown-it.rs`](https://github.com/rlidwka/markdown-it.rs). For this you will need to install `cmake`. After that make sure that you have set-up the git submodules. In case you have not installed submodules when cloning, you can do it by running
213-
214-
``` bash
215-
git submodule update --init
216-
```
217-
218-
After this is done, you can run
219-
220-
``` bash
221-
make bench-all
222-
```
223-
224-
which will run benchmarks across all, and report the time take by each as well as relative time.
225-
226-
Apart from this, CI is also setup for running benchmarks when a pull request is first opened. It will add a comment with the results on the pull request in a tabular format comparing the 5 versions. After that you can manually trigger this CI by commenting `/run-bench` on the PR, this will update the existing comment with new results. Note benchmarks won't be automatically run on each push.
223+
For a slightly more real-world example, see how I [generate my GitHub user README](https://github.com/kivikakk/kivikakk) from a base document with embedded YAML, which itself has embedded Markdown, or
224+
[check out some of Comrak's dependents on crates.io](https://crates.io/crates/comrak/reverse_dependencies) or [on GitHub](https://github.com/kivikakk/comrak/network/dependents).
227225

228226
## Security
229227

230228
As with [`cmark`](https://github.com/commonmark/cmark) and [`cmark-gfm`](https://github.com/github/cmark-gfm#security),
231229
Comrak will scrub raw HTML and potentially dangerous links. This change was introduced in Comrak 0.4.0 in support of a
232-
safe-by-default posture.
230+
safe-by-default posture, and later adopted by our contemporaries. :)
233231

234232
To allow these, use the `unsafe_` option (or `--unsafe` with the command line program). If doing so, we recommend the
235233
use of a sanitisation library like [`ammonia`](https://github.com/notriddle/ammonia) configured specific to your needs.
@@ -252,29 +250,33 @@ Comrak additionally supports its own extensions, which are yet to be specced out
252250
- Footnotes
253251
- Description lists
254252
- Front matter
255-
- Shortcodes
253+
- Multi-line blockquotes
256254
- Math
257-
- Multiline Blockquotes
255+
- Emoji shortcodes
256+
- Wikilinks
257+
- Underline
258+
- Spoiler text
259+
- "Greentext"
258260

259261
By default none are enabled; they are individually enabled with each parse by setting the appropriate values in the
260-
[`ComrakExtensionOptions` struct](https://docs.rs/comrak/newest/comrak/type.ComrakExtensionOptions.html).
262+
[`ExtensionOptions` struct](https://docs.rs/comrak/latest/comrak/struct.ExtensionOptions.html).
261263

262264
## Plugins
263265

264-
### Codefence syntax highlighter
266+
### Fenced code block syntax highlighting
265267

266-
At the moment syntax highlighting of codefence blocks is the only feature that can be enhanced with plugins.
268+
You can provide your own syntax highlighting engine.
267269

268270
Create an implementation of the `SyntaxHighlighterAdapter` trait, and then provide an instance of such adapter to
269-
`Plugins.render.codefence_syntax_highlighter`. For formatting a markdown document with plugins, use the
270-
`markdown_to_html_with_plugins` function, which accepts your plugin as a parameter.
271+
`Plugins.render.codefence_syntax_highlighter`. For formatting a Markdown document with plugins, use the
272+
`markdown_to_html_with_plugins` function, which accepts your plugins object as a parameter.
271273

272274
See the `syntax_highlighter.rs` and `syntect.rs` examples for more details.
273275

274276
#### Syntect
275277

276278
[`syntect`](https://github.com/trishume/syntect) is a syntax highlighting library for Rust. By default, `comrak` offers
277-
a plugin for it. In order to utilize it, create an instance of `plugins::syntect::SyntectAdapter` and use it as your
279+
a plugin for it. In order to utilize it, create an instance of `plugins::syntect::SyntectAdapter` and use it in your
278280
`Plugins` option.
279281

280282
## Related projects
@@ -284,8 +286,8 @@ in terms of code structure. The upside of this is that a change in `cmark-gfm` h
284286
Likewise, any bug in `cmark-gfm` is likely to be reproduced in Comrak. This could be considered a pro or a con,
285287
depending on your use case.
286288

287-
The downside, of course, is that the code is not what I'd call idiomatic Rust (*so many `RefCell`s*), and while
288-
contributors and I have made it as fast as possible, it simply won't be as fast as some other CommonMark parsers
289+
The downside, of course, is that the code often diverges from idiomatic Rust, especially in the AST's extensive use of `RefCell`, and while
290+
contributors have made it as fast as possible, it simply won't be as fast as some other CommonMark parsers
289291
depending on your use-case. Here are some other projects to consider:
290292

291293
- [Raph Levien](https://github.com/raphlinus)'s [`pulldown-cmark`](https://github.com/google/pulldown-cmark). It's
@@ -295,20 +297,43 @@ depending on your use-case. Here are some other projects to consider:
295297
- Know of another library? Please open a PR to add it\!
296298

297299
As far as I know, Comrak is the only library to implement all of the [GitHub Flavored Markdown
298-
extensions](https://github.github.com/gfm) to the spec, but this tends to only be important if you want to reproduce
299-
GitHub's Markdown rendering exactly, e.g. in a GitHub client app.
300+
extensions](https://github.github.com/gfm) rigorously.
301+
302+
## Benchmarking
303+
304+
You'll need to [install hyperfine](https://github.com/sharkdp/hyperfine#installation), and CMake if you want to compare against `cmark-gfm`.
305+
306+
If you want to just run the benchmark for the `comrak` binary itself, run:
307+
308+
``` bash
309+
make bench-comrak
310+
```
311+
312+
This will build Comrak in release mode, and run benchmark on it. You will see the time measurements as reported by hyperfine in the console.
313+
314+
The `Makefile` also provides a way to run benchmarks for `comrak` current state (with your changes), `comrak` main branch, [`cmark-gfm`](https://github.com/github/cmark-gfm), [`pulldown-cmark`](https://github.com/raphlinus/pulldown-cmark) and [`markdown-it.rs`](https://github.com/rlidwka/markdown-it.rs). You'll need CMake, and ensure [submodules are prepared](https://stackoverflow.com/a/10168693/499609).
315+
316+
``` bash
317+
make bench-all
318+
```
319+
320+
This will build and run benchmarks across all, and report the time taken by each as well as relative time.
321+
322+
<!-- XXX: The following isn't really true at the moment, due to https://github.com/kivikakk/comrak/issues/339 -->
323+
324+
<!-- Apart from this, CI is also setup for running benchmarks when a pull request is first opened. It will add a comment with the results on the pull request in a tabular format comparing the 5 versions. After that you can manually trigger this CI by commenting `/run-bench` on the PR, this will update the existing comment with new results. Note benchmarks won't be automatically run on each push. -->
300325

301326
## Contributing
302327

303-
Contributions are highly encouraged; where possible I practice [Optimistic Merging](http://hintjens.com/blog:106) as
304-
described by Peter Hintjens. Please keep the [code of conduct](CODE_OF_CONDUCT.md) in mind when interacting with this
305-
project.
328+
Contributions are **highly encouraged**; if you'd like to assist, consider checking out the [`good first issue` label](https://github.com/kivikakk/comrak/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)\! I'm happy to help provide direction and guidance throughout, even if (especially if\!) you're new to Rust or open source.
329+
330+
Where possible I practice [Optimistic Merging](http://hintjens.com/blog:106) as described by Peter Hintjens. Please keep the [code of conduct](CODE_OF_CONDUCT.md) in mind too.
306331

307332
Thank you to Comrak's many contributors for PRs and issues opened\!
308333

309334
### Code Contributors
310335

311-
<a href="https://github.com/kivikakk/comrak/graphs/contributors"><img src="https://opencollective.com/comrak/contributors.svg?width=890&button=false" /></a>
336+
[![Small chart showing Comrak contributors.](https://opencollective.com/comrak/contributors.svg?width=890&button=false)](https://github.com/kivikakk/comrak/graphs/contributors)
312337

313338
### Financial Contributors
314339

0 commit comments

Comments
 (0)