Ruby wrapper for Rust's comrak crate.
It passes all of the CommonMark test suite, and is therefore spec-complete. It also includes extensions to the CommonMark spec as documented in the GitHub Flavored Markdown spec, such as support for tables, strikethroughs, and autolinking.
For more information on available extensions, see the documentation below.
Add this line to your application's Gemfile:
gem 'commonmarker'
And then execute:
$ bundle
Or install it yourself as:
$ gem install commonmarker
Call to_html
on a string to convert it to HTML:
require 'commonmarker'
Commonmarker.to_html('"Hi *there*"', options: {
parse: { smart: true }
})
# <p>βHi <em>there</em>β</p>\n
The second argument is optional--see below for more information.
Commonmarker accepts the same parse, render, and extensions options that comrak does, as a hash dictionary with symbol keys:
Commonmarker.to_html('"Hi *there*"', options:{
parse: { smart: true },
render: { hardbreaks: false}
})
Note that there is a distinction in comrak for "parse" options and "render" options, which are represented in the tables below.
Name | Description | Default |
---|---|---|
smart |
Punctuation (quotes, full-stops and hyphens) are converted into 'smart' punctuation. | false |
default_info_string |
The default info string for fenced code blocks. | "" |
Name | Description | Default |
---|---|---|
hardbreaks |
Soft line breaks translate into hard line breaks. | true |
github_pre_lang |
GitHub-style <pre lang="xyz"> is used for fenced code blocks with info tags. |
true |
width |
The wrap column when outputting CommonMark. | 80 |
unsafe |
Allow rendering of raw HTML and potentially dangerous links. | false |
escape |
Escape raw HTML instead of clobbering it. | false |
sourcepos |
Include source position attribute in HTML and XML output. | false |
As well, there are several extensions which you can toggle in the same manner:
Commonmarker.to_html('"Hi *there*"', options: {
extension: { footnotes: true, description_lists: true },
render: { hardbreaks: false}
})
Name | Description | Default |
---|---|---|
strikethrough |
Enables the strikethrough extension from the GFM spec. | true |
tagfilter |
Enables the tagfilter extension from the GFM spec. | true |
table |
Enables the table extension from the GFM spec. | true |
autolink |
Enables the autolink extension from the GFM spec. | true |
tasklist |
Enables the task list extension from the GFM spec. | true |
superscript |
Enables the superscript Comrak extension. | false |
header_ids |
Enables the header IDs Comrak extension. from the GFM spec. | "" |
footnotes |
Enables the footnotes extension per cmark-gfm . |
false |
description_lists |
Enables the description lists extension. | false |
front_matter_delimiter |
Enables the front matter extension. | "" |
shortcodes |
Enables the shortcodes extension. | true |
For more information on these options, see the comrak documentation.
In addition to the possibilities provided by generic CommonMark rendering, Commonmarker also supports plugins as a means of providing further niceties.
The library comes with a set of pre-existing themes for highlighting code:
"base16-ocean.dark"
"base16-eighties.dark"
"base16-mocha.dark"
"base16-ocean.light"
"InspiredGitHub"
"Solarized (dark)"
"Solarized (light)"
code = <<~CODE
```ruby
def hello
puts "hello"
end
```
CODE
# pass in a theme name from a pre-existing set
puts Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "InspiredGitHub" } })
# <pre style="background-color:#ffffff;" lang="ruby"><code>
# <span style="font-weight:bold;color:#a71d5d;">def </span><span style="font-weight:bold;color:#795da3;">hello
# </span><span style="color:#62a35c;">puts </span><span style="color:#183691;">"hello"
# </span><span style="font-weight:bold;color:#a71d5d;">end
# </span>
# </code></pre>
By default, the plugin uses the "base16-ocean.dark"
theme to syntax highlight code.
To disable this plugin, set the value to nil
:
code = <<~CODE
```ruby
def hello
puts "hello"
end
```
CODE
Commonmarker.to_html(code, plugins: { syntax_highlighter: nil })
# <pre lang="ruby"><code>def hello
# puts "hello"
# end
# </code></pre>
To output CSS classes instead of style
attributes, set the theme
key to ""
:
code = <<~CODE
```ruby
def hello
puts "hello"
end
CODE
Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "" } })
# <pre class="syntax-highlighting"><code><span class="source ruby"><span class="meta function ruby"><span class="keyword control def ruby">def</span></span><span class="meta function ruby"> # <span class="entity name function ruby">hello</span></span>
# <span class="support function builtin ruby">puts</span> <span class="string quoted double ruby"><span class="punctuation definition string begin ruby">"</span>hello<span class="punctuation definition string end ruby">"</span></span>
# <span class="keyword control ruby">end</span>\n</span></code></pre>
To use a custom theme, you can provide a path
to a directory containing .tmtheme
files to load:
Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "Monokai", path: "./themes" } })
Commonmarker can currently only generate output in one format: HTML.
puts Commonmarker.to_html('*Hello* world!')
# <p><em>Hello</em> world!</p>
After cloning the repo:
script/bootstrap
bundle exec rake compile
If there were no errors, you're done! Otherwise, make sure to follow the comrak dependency instructions.
Some rough benchmarks:
$ bundle exec rake benchmark
input size = 11064832 bytes
Warming up --------------------------------------
redcarpet 2.000 i/100ms
commonmarker with to_html
1.000 i/100ms
kramdown 1.000 i/100ms
Calculating -------------------------------------
redcarpet 22.317 (Β± 4.5%) i/s - 112.000 in 5.036374s
commonmarker with to_html
5.815 (Β± 0.0%) i/s - 30.000 in 5.168869s
kramdown 0.327 (Β± 0.0%) i/s - 2.000 in 6.121486s
Comparison:
redcarpet: 22.3 i/s
commonmarker with to_html: 5.8 i/s - 3.84x (Β± 0.00) slower
kramdown: 0.3 i/s - 68.30x (Β± 0.00) slower