commonmarker 0.23.10 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1164 -0
  3. data/Cargo.toml +12 -0
  4. data/README.md +252 -176
  5. data/ext/commonmarker/Cargo.toml +21 -0
  6. data/ext/commonmarker/build.rs +9 -0
  7. data/ext/commonmarker/extconf.rb +3 -6
  8. data/ext/commonmarker/src/lib.rs +168 -0
  9. data/ext/commonmarker/src/node.rs +1263 -0
  10. data/ext/commonmarker/src/options.rs +241 -0
  11. data/ext/commonmarker/src/plugins/syntax_highlighting.rs +171 -0
  12. data/ext/commonmarker/src/plugins.rs +6 -0
  13. data/ext/commonmarker/src/utils.rs +5 -0
  14. data/lib/commonmarker/config.rb +103 -40
  15. data/lib/commonmarker/constants.rb +7 -0
  16. data/lib/commonmarker/extension.rb +14 -0
  17. data/lib/commonmarker/node/ast.rb +8 -0
  18. data/lib/commonmarker/node/inspect.rb +14 -4
  19. data/lib/commonmarker/node.rb +29 -47
  20. data/lib/commonmarker/renderer.rb +1 -127
  21. data/lib/commonmarker/utils.rb +22 -0
  22. data/lib/commonmarker/version.rb +2 -2
  23. data/lib/commonmarker.rb +27 -25
  24. metadata +38 -187
  25. data/Rakefile +0 -109
  26. data/bin/commonmarker +0 -118
  27. data/commonmarker.gemspec +0 -38
  28. data/ext/commonmarker/arena.c +0 -104
  29. data/ext/commonmarker/autolink.c +0 -508
  30. data/ext/commonmarker/autolink.h +0 -8
  31. data/ext/commonmarker/blocks.c +0 -1622
  32. data/ext/commonmarker/buffer.c +0 -278
  33. data/ext/commonmarker/buffer.h +0 -116
  34. data/ext/commonmarker/case_fold_switch.inc +0 -4327
  35. data/ext/commonmarker/chunk.h +0 -135
  36. data/ext/commonmarker/cmark-gfm-core-extensions.h +0 -54
  37. data/ext/commonmarker/cmark-gfm-extension_api.h +0 -737
  38. data/ext/commonmarker/cmark-gfm-extensions_export.h +0 -42
  39. data/ext/commonmarker/cmark-gfm.h +0 -833
  40. data/ext/commonmarker/cmark-gfm_export.h +0 -42
  41. data/ext/commonmarker/cmark-gfm_version.h +0 -7
  42. data/ext/commonmarker/cmark.c +0 -55
  43. data/ext/commonmarker/cmark_ctype.c +0 -44
  44. data/ext/commonmarker/cmark_ctype.h +0 -33
  45. data/ext/commonmarker/commonmark.c +0 -514
  46. data/ext/commonmarker/commonmarker.c +0 -1308
  47. data/ext/commonmarker/commonmarker.h +0 -16
  48. data/ext/commonmarker/config.h +0 -76
  49. data/ext/commonmarker/core-extensions.c +0 -27
  50. data/ext/commonmarker/entities.inc +0 -2138
  51. data/ext/commonmarker/ext_scanners.c +0 -879
  52. data/ext/commonmarker/ext_scanners.h +0 -24
  53. data/ext/commonmarker/footnotes.c +0 -63
  54. data/ext/commonmarker/footnotes.h +0 -27
  55. data/ext/commonmarker/houdini.h +0 -57
  56. data/ext/commonmarker/houdini_href_e.c +0 -100
  57. data/ext/commonmarker/houdini_html_e.c +0 -66
  58. data/ext/commonmarker/houdini_html_u.c +0 -149
  59. data/ext/commonmarker/html.c +0 -502
  60. data/ext/commonmarker/html.h +0 -27
  61. data/ext/commonmarker/inlines.c +0 -1788
  62. data/ext/commonmarker/inlines.h +0 -29
  63. data/ext/commonmarker/iterator.c +0 -159
  64. data/ext/commonmarker/iterator.h +0 -26
  65. data/ext/commonmarker/latex.c +0 -468
  66. data/ext/commonmarker/linked_list.c +0 -37
  67. data/ext/commonmarker/man.c +0 -274
  68. data/ext/commonmarker/map.c +0 -129
  69. data/ext/commonmarker/map.h +0 -44
  70. data/ext/commonmarker/node.c +0 -1045
  71. data/ext/commonmarker/node.h +0 -167
  72. data/ext/commonmarker/parser.h +0 -59
  73. data/ext/commonmarker/plaintext.c +0 -218
  74. data/ext/commonmarker/plugin.c +0 -36
  75. data/ext/commonmarker/plugin.h +0 -34
  76. data/ext/commonmarker/references.c +0 -43
  77. data/ext/commonmarker/references.h +0 -26
  78. data/ext/commonmarker/registry.c +0 -63
  79. data/ext/commonmarker/registry.h +0 -24
  80. data/ext/commonmarker/render.c +0 -213
  81. data/ext/commonmarker/render.h +0 -62
  82. data/ext/commonmarker/scanners.c +0 -14056
  83. data/ext/commonmarker/scanners.h +0 -70
  84. data/ext/commonmarker/scanners.re +0 -341
  85. data/ext/commonmarker/strikethrough.c +0 -167
  86. data/ext/commonmarker/strikethrough.h +0 -9
  87. data/ext/commonmarker/syntax_extension.c +0 -149
  88. data/ext/commonmarker/syntax_extension.h +0 -34
  89. data/ext/commonmarker/table.c +0 -917
  90. data/ext/commonmarker/table.h +0 -12
  91. data/ext/commonmarker/tagfilter.c +0 -60
  92. data/ext/commonmarker/tagfilter.h +0 -8
  93. data/ext/commonmarker/tasklist.c +0 -156
  94. data/ext/commonmarker/tasklist.h +0 -8
  95. data/ext/commonmarker/utf8.c +0 -317
  96. data/ext/commonmarker/utf8.h +0 -35
  97. data/ext/commonmarker/xml.c +0 -182
  98. data/lib/commonmarker/renderer/html_renderer.rb +0 -256
data/Cargo.toml ADDED
@@ -0,0 +1,12 @@
1
+ # This Cargo.toml is here to let externals tools (IDEs, etc.) know that this is
2
+ # a Rust project. Your extensions dependencies should be added to the Cargo.toml
3
+ # in the ext/ directory.
4
+
5
+ [workspace]
6
+ members = ["ext/commonmarker"]
7
+ resolver = "2"
8
+
9
+ [profile.release]
10
+ codegen-units = 1
11
+ lto = true
12
+ strip = true
data/README.md CHANGED
@@ -1,11 +1,13 @@
1
- # CommonMarker
1
+ # Commonmarker
2
2
 
3
- ![Build Status](https://github.com/gjtorikian/commonmarker/workflows/CI/badge.svg) [![Gem Version](https://badge.fury.io/rb/commonmarker.svg)](http://badge.fury.io/rb/commonmarker)
3
+ Ruby wrapper for Rust's [comrak](https://github.com/kivikakk/comrak) crate.
4
4
 
5
- Ruby wrapper for [libcmark-gfm](https://github.com/github/cmark),
6
- GitHub's fork of the reference parser for CommonMark. It passes all of the C tests, and is therefore spec-complete. It also includes extensions to the CommonMark spec as documented in the [GitHub Flavored Markdown spec](http://github.github.com/gfm/), such as support for tables, strikethroughs, and autolinking.
5
+ 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](http://github.github.com/gfm/), such as support for tables, strikethroughs, and autolinking.
7
6
 
8
- For more information on available extensions, see [the documentation below](#extensions).
7
+ > [!NOTE]
8
+ > By default, the following extensions are enabled for end user convenience: `strikethrough`, `tagfilter`, `table`, `autolink`, `tasklist` (all from the [GFM spec](http://github.github.com/gfm/)), and `shortcodes`. The `syntax_highlighter` plugin is also enabled by default, using the `"base16-ocean.dark"` theme.
9
+ >
10
+ > For more information on the available options and extensions, see [the documentation below](#options-and-plugins).
9
11
 
10
12
  ## Installation
11
13
 
@@ -23,47 +25,79 @@ Or install it yourself as:
23
25
 
24
26
  ## Usage
25
27
 
28
+ This gem expects to receive UTF-8 strings. Ensure your strings are the right encoding before passing them into `Commonmarker`.
29
+
26
30
  ### Converting to HTML
27
31
 
28
- Call `render_html` on a string to convert it to HTML:
32
+ Call `to_html` on a string to convert it to HTML:
29
33
 
30
- ``` ruby
34
+ ```ruby
31
35
  require 'commonmarker'
32
- CommonMarker.render_html('Hi *there*', :DEFAULT)
33
- # <p>Hi <em>there</em></p>\n
36
+ Commonmarker.to_html('"Hi *there*"', options: {
37
+ parse: { smart: true }
38
+ })
39
+ # => <p>“Hi <em>there</em>”</p>\n
34
40
  ```
35
41
 
36
- The second argument is optional--[see below](#options) for more information.
42
+ (The second argument is optional--[see below](#options-and-plugins) for more information.)
37
43
 
38
44
  ### Generating a document
39
45
 
40
- You can also parse a string to receive a `Document` node. You can then print that node to HTML, iterate over the children, and other fun node stuff. For example:
46
+ You can also parse a string to receive a `:document` node. You can then print that node to HTML, iterate over the children, and do other fun node stuff. For example:
41
47
 
42
- ``` ruby
48
+ ```ruby
43
49
  require 'commonmarker'
44
50
 
45
- doc = CommonMarker.render_doc('*Hello* world', :DEFAULT)
46
- puts(doc.to_html) # <p>Hi <em>there</em></p>\n
51
+ doc = Commonmarker.parse("*Hello* world", options: {
52
+ parse: { smart: true }
53
+ })
54
+ puts(doc.to_html) # => <p><em>Hello</em> world</p>\n
47
55
 
48
56
  doc.walk do |node|
49
- puts node.type # [:document, :paragraph, :text, :emph, :text]
57
+ puts node.type # => [:document, :paragraph, :emph, :text, :text]
50
58
  end
51
59
  ```
52
60
 
53
- The second argument is optional--[see below](#options) for more information.
61
+ (The second argument is optional--[see below](#options-and-plugins) for more information.)
62
+
63
+ When it comes to modifying the document, you can perform the following operations:
54
64
 
55
- #### Example: walking the AST
65
+ - `insert_before`
66
+ - `insert_after`
67
+ - `prepend_child`
68
+ - `append_child`
69
+ - `delete`
70
+
71
+ You can also get the source position of a node by calling `source_position`:
72
+
73
+ ```ruby
74
+ doc = Commonmarker.parse("*Hello* world")
75
+ puts doc.first_child.first_child.source_position
76
+ # => {:start_line=>1, :start_column=>1, :end_line=>1, :end_column=>7}
77
+ ```
78
+
79
+ You can also modify the following attributes:
80
+
81
+ - `url`
82
+ - `title`
83
+ - `header_level`
84
+ - `list_type`
85
+ - `list_start`
86
+ - `list_tight`
87
+ - `fence_info`
88
+
89
+ #### Example: Walking the AST
56
90
 
57
91
  You can use `walk` or `each` to iterate over nodes:
58
92
 
59
93
  - `walk` will iterate on a node and recursively iterate on a node's children.
60
- - `each` will iterate on a node and its children, but no further.
94
+ - `each` will iterate on a node's direct children, but no further.
61
95
 
62
- ``` ruby
96
+ ```ruby
63
97
  require 'commonmarker'
64
98
 
65
- # parse the files specified on the command line
66
- doc = CommonMarker.render_doc("# The site\n\n [GitHub](https://www.github.com)")
99
+ # parse some string
100
+ doc = Commonmarker.parse("# The site\n\n [GitHub](https://www.github.com)")
67
101
 
68
102
  # Walk tree and print out URLs for links
69
103
  doc.walk do |node|
@@ -71,17 +105,7 @@ doc.walk do |node|
71
105
  printf("URL = %s\n", node.url)
72
106
  end
73
107
  end
74
-
75
- # Capitalize all regular text in headers
76
- doc.walk do |node|
77
- if node.type == :header
78
- node.each do |subnode|
79
- if subnode.type == :text
80
- subnode.string_content = subnode.string_content.upcase
81
- end
82
- end
83
- end
84
- end
108
+ # => URL = https://www.github.com
85
109
 
86
110
  # Transform links to regular text
87
111
  doc.walk do |node|
@@ -90,169 +114,210 @@ doc.walk do |node|
90
114
  node.delete
91
115
  end
92
116
  end
117
+ # => <h1><a href=\"#the-site\"></a>The site</h1>\n<p>GitHub</p>\n
93
118
  ```
94
119
 
95
- ### Creating a custom renderer
120
+ #### Example: Converting a document back into raw CommonMark
96
121
 
97
- You can also derive a class from CommonMarker's `HtmlRenderer` class. This produces slower output, but is far more customizable. For example:
122
+ You can use `to_commonmark` on a node to render it as raw text:
98
123
 
99
- ``` ruby
100
- class MyHtmlRenderer < CommonMarker::HtmlRenderer
101
- def initialize
102
- super
103
- @headerid = 1
104
- end
124
+ ```ruby
125
+ require 'commonmarker'
105
126
 
106
- def header(node)
107
- block do
108
- out("<h", node.header_level, " id=\"", @headerid, "\">",
109
- :children, "</h", node.header_level, ">")
110
- @headerid += 1
111
- end
127
+ # parse some string
128
+ doc = Commonmarker.parse("# The site\n\n [GitHub](https://www.github.com)")
129
+
130
+ # Transform links to regular text
131
+ doc.walk do |node|
132
+ if node.type == :link
133
+ node.insert_before(node.first_child)
134
+ node.delete
112
135
  end
113
136
  end
114
137
 
115
- myrenderer = MyHtmlRenderer.new
116
- puts myrenderer.render(doc)
117
-
118
- # Print any warnings to STDERR
119
- renderer.warnings.each do |w|
120
- STDERR.write("#{w}\n")
121
- end
138
+ doc.to_commonmark
139
+ # => # The site\n\nGitHub\n
122
140
  ```
123
141
 
124
- ## Options
125
-
126
- CommonMarker accepts the same options that CMark does, as symbols. Note that there is a distinction in CMark for "parse" options and "render" options, which are represented in the tables below.
142
+ ## Options and plugins
127
143
 
128
- ### Parse options
144
+ ### Options
129
145
 
130
- | Name | Description
131
- | ----------------------------- | -----------
132
- | `:DEFAULT` | The default parsing system.
133
- | `:SOURCEPOS` | Include source position in nodes
134
- | `:UNSAFE` | Allow raw/custom HTML and unsafe links.
135
- | `:VALIDATE_UTF8` | Replace illegal sequences with the replacement character `U+FFFD`.
136
- | `:SMART` | Use smart punctuation (curly quotes, etc.).
137
- | `:LIBERAL_HTML_TAG` | Support liberal parsing of inline HTML tags.
138
- | `:FOOTNOTES` | Parse footnotes.
139
- | `:STRIKETHROUGH_DOUBLE_TILDE` | Parse strikethroughs by double tildes (compatibility with [redcarpet](https://github.com/vmg/redcarpet))
146
+ Commonmarker accepts the same parse, render, and extensions options that comrak does, as a hash dictionary with symbol keys:
140
147
 
141
- ### Render options
142
-
143
- | Name | Description |
144
- | ------------------ | ----------- |
145
- | `:DEFAULT` | The default rendering system. |
146
- | `:SOURCEPOS` | Include source position in rendered HTML. |
147
- | `:HARDBREAKS` | Treat `\n` as hardbreaks (by adding `<br/>`). |
148
- | `:UNSAFE` | Allow raw/custom HTML and unsafe links. |
149
- | `:NOBREAKS` | Translate `\n` in the source to a single whitespace. |
150
- | `:VALIDATE_UTF8` | Replace illegal sequences with the replacement character `U+FFFD`. |
151
- | `:SMART` | Use smart punctuation (curly quotes, etc.). |
152
- | `:GITHUB_PRE_LANG` | Use GitHub-style `<pre lang>` for fenced code blocks. |
153
- | `:LIBERAL_HTML_TAG` | Support liberal parsing of inline HTML tags. |
154
- | `:FOOTNOTES` | Render footnotes. |
155
- | `:STRIKETHROUGH_DOUBLE_TILDE` | Parse strikethroughs by double tildes (compatibility with [redcarpet](https://github.com/vmg/redcarpet)) |
156
- | `:TABLE_PREFER_STYLE_ATTRIBUTES` | Use `style` insted of `align` for table cells. |
157
- | `:FULL_INFO_STRING` | Include full info strings of code blocks in separate attribute. |
158
-
159
- ### Passing options
160
-
161
- To apply a single option, pass it in as a symbol argument:
162
-
163
- ``` ruby
164
- CommonMarker.render_doc("\"Hello,\" said the spider.", :SMART)
165
- # <p>“Hello,” said the spider.</p>\n
166
- ```
167
-
168
- To have multiple options applied, pass in an array of symbols:
169
-
170
- ``` ruby
171
- CommonMarker.render_html("\"'Shelob' is my name.\"", [:HARDBREAKS, :SOURCEPOS])
148
+ ```ruby
149
+ Commonmarker.to_html('"Hi *there*"', options:{
150
+ parse: { smart: true },
151
+ render: { hardbreaks: false}
152
+ })
172
153
  ```
173
154
 
174
- For more information on these options, see [the CMark documentation](https://git.io/v7nh1).
175
-
176
- ## Extensions
155
+ Note that there is a distinction in comrak for "parse" options and "render" options, which are represented in the tables below. As well, if you wish to disable any-non boolean option, pass in `nil`.
177
156
 
178
- Both `render_html` and `render_doc` take an optional third argument defining the extensions you want enabled as your CommonMark document is being processed. The documentation for these extensions are [defined in this spec](https://github.github.com/gfm/), and the rationale is provided [in this blog post](https://githubengineering.com/a-formal-spec-for-github-markdown/).
179
-
180
- The available extensions are:
181
-
182
- * `:table` - This provides support for tables.
183
- * `:tasklist` - This provides support for task list items.
184
- * `:strikethrough` - This provides support for strikethroughs.
185
- * `:autolink` - This provides support for automatically converting URLs to anchor tags.
186
- * `:tagfilter` - This escapes [several "unsafe" HTML tags](https://github.github.com/gfm/#disallowed-raw-html-extension-), causing them to not have any effect.
187
-
188
- ## Output formats
157
+ ### Parse options
189
158
 
190
- Like CMark, CommonMarker can generate output in several formats: HTML, XML, plaintext, and commonmark are currently supported.
159
+ | Name | Description | Default |
160
+ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
161
+ | `smart` | Punctuation (quotes, full-stops and hyphens) are converted into 'smart' punctuation. | `false` |
162
+ | `default_info_string` | The default info string for fenced code blocks. | `""` |
163
+ | `relaxed_tasklist_matching` | Enables relaxing of the tasklist extension matching, allowing any non-space to be used for the "checked" state instead of only `x` and `X`. | `false` |
164
+ | `relaxed_autolinks` | Enable relaxing of the autolink extension parsing, allowing links to be recognized when in brackets, as well as permitting any url scheme. | `false` |
165
+ | `leave_footnote_definitions` | Allow footnote definitions to remain in their original positions instead of being moved to the document's end (only affects AST) | `false` |
166
+ | `ignore_setext` | Ignores setext-style headings. | `false` |
167
+ | `sourcepos_chars` | Use character-based column tracking in source positions instead of byte-based. Relevant for multi-byte UTF-8 documents with `sourcepos`. | `false` |
191
168
 
192
- ### HTML
169
+ ### Render options
193
170
 
194
- The default output format, HTML, will be generated when calling `to_html` or using `--to=html` on the command line.
171
+ | Name | Description | Default |
172
+ | -------------------- | ------------------------------------------------------------------------------------------------------ | ------- |
173
+ | `hardbreaks` | [Soft line breaks](http://spec.commonmark.org/0.27/#soft-line-breaks) translate into hard line breaks. | `true` |
174
+ | `github_pre_lang` | GitHub-style `<pre lang="xyz">` is used for fenced code blocks with info tags. | `true` |
175
+ | `full_info_string` | Gives info string data after a space in a `data-meta` attribute on code blocks. | `false` |
176
+ | `width` | The wrap column when outputting CommonMark. | `80` |
177
+ | `unsafe` | Allow rendering of raw HTML and potentially dangerous links. | `false` |
178
+ | `escape` | Escape raw HTML instead of clobbering it. | `false` |
179
+ | `sourcepos` | Include source position attribute in HTML and XML output. | `false` |
180
+ | `escaped_char_spans` | Wrap escaped characters in span tags. | `true` |
181
+ | `ignore_empty_links` | Ignores empty links, leaving the Markdown text in place. | `false` |
182
+ | `gfm_quirks` | Outputs HTML with GFM-style quirks; namely, not nesting `<strong>` inlines. | `false` |
183
+ | `prefer_fenced` | Always output fenced code blocks, even where an indented one could be used. | `false` |
184
+ | `tasklist_classes` | Add CSS classes to the HTML output of the tasklist extension | `false` |
185
+ | `compact_html` | Suppress newlines in pretty-printed HTML output. | `false` |
186
+
187
+ As well, there are several extensions which you can toggle in the same manner:
195
188
 
196
189
  ```ruby
197
- doc = CommonMarker.render_doc('*Hello* world!', :DEFAULT)
198
- puts(doc.to_html)
199
-
200
- <p><em>Hello</em> world!</p>
190
+ Commonmarker.to_html('"Hi *there*"', options: {
191
+ extension: { footnotes: true, description_lists: true },
192
+ render: { hardbreaks: false }
193
+ })
201
194
  ```
202
195
 
203
- ### XML
196
+ ### Extension options
197
+
198
+ | Name | Description | Default |
199
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------- |
200
+ | `strikethrough` | Enables the [strikethrough extension](https://github.github.com/gfm/#strikethrough-extension-) from the GFM spec. | `true` |
201
+ | `tagfilter` | Enables the [tagfilter extension](https://github.github.com/gfm/#disallowed-raw-html-extension-) from the GFM spec. | `true` |
202
+ | `table` | Enables the [table extension](https://github.github.com/gfm/#tables-extension-) from the GFM spec. | `true` |
203
+ | `autolink` | Enables the [autolink extension](https://github.github.com/gfm/#autolinks-extension-) from the GFM spec. | `true` |
204
+ | `tasklist` | Enables the [task list extension](https://github.github.com/gfm/#task-list-items-extension-) from the GFM spec. | `true` |
205
+ | `superscript` | Enables the superscript Comrak extension. | `false` |
206
+ | `header_ids` | Enables the header IDs Comrak extension. from the GFM spec. | `""` |
207
+ | `header_id_prefix_in_href` | Also add the prefix to generated `href` attributes pointing to headers. | `false` |
208
+ | `footnotes` | Enables the footnotes extension per `cmark-gfm`. | `false` |
209
+ | `inline_footnotes` | Enables the inline footnotes extension. | `false` |
210
+ | `description_lists` | Enables the description lists extension. | `false` |
211
+ | `front_matter_delimiter` | Enables the front matter extension. | `""` |
212
+ | `multiline_block_quotes` | Enables the multiline block quotes extension. | `false` |
213
+ | `math_dollars`, `math_code` | Enables the math extension. | `false` |
214
+ | `shortcodes` | Enables the shortcodes extension. | `true` |
215
+ | `wikilinks_title_before_pipe` | Enables the wikilinks extension, placing the title before the dividing pipe. | `false` |
216
+ | `wikilinks_title_after_pipe` | Enables the wikilinks extension, placing the title after the dividing pipe. | `false` |
217
+ | `underline` | Enables the underline extension. | `false` |
218
+ | `spoiler` | Enables the spoiler extension. | `false` |
219
+ | `greentext` | Enables the greentext extension. | `false` |
220
+ | `subtext` | Enables the subtext extension. | `false` |
221
+ | `subscript` | Enables the subscript extension. | `false` |
222
+ | `alerts` | Enables the alerts extension. | `false` |
223
+ | `cjk_friendly_emphasis` | Enables the [CJK friendly emphasis](https://github.com/tats-u/markdown-cjk-friendly) extension. | `false` |
224
+ | `highlight` | Enables highlighting via `==` | `false` |
225
+ | `insert` | Enables the insert extension, rendering `++text++` as `<ins>text</ins>`. | `false` |
226
+ | `block_directive` | Enables the block directive extension. | `false` |
227
+
228
+ For more information on these options, see [the comrak documentation](https://github.com/kivikakk/comrak#usage).
229
+
230
+ ### Plugins
231
+
232
+ In addition to the possibilities provided by generic CommonMark rendering, Commonmarker also supports plugins as a means of
233
+ providing further niceties.
234
+
235
+ #### Syntax Highlighter Plugin
236
+
237
+ The syntax highlighter plugin is **enabled by default**, using the `"base16-ocean.dark"` theme. It applies syntax highlighting to fenced code blocks that specify a language.
238
+
239
+ The library comes with [a set of pre-existing themes](https://docs.rs/syntect/5.0.0/syntect/highlighting/struct.ThemeSet.html#implementations) for highlighting code:
240
+
241
+ - `"base16-ocean.dark"`
242
+ - `"base16-eighties.dark"`
243
+ - `"base16-mocha.dark"`
244
+ - `"base16-ocean.light"`
245
+ - `"InspiredGitHub"`
246
+ - `"Solarized (dark)"`
247
+ - `"Solarized (light)"`
248
+
249
+ ````ruby
250
+ code = <<~CODE
251
+ ```ruby
252
+ def hello
253
+ puts "hello"
254
+ end
255
+ ```
256
+ CODE
257
+
258
+ # pass in a theme name from a pre-existing set
259
+ puts Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "InspiredGitHub" } })
260
+
261
+ # <pre style="background-color:#ffffff;" lang="ruby"><code>
262
+ # <span style="font-weight:bold;color:#a71d5d;">def </span><span style="font-weight:bold;color:#795da3;">hello
263
+ # </span><span style="color:#62a35c;">puts </span><span style="color:#183691;">&quot;hello&quot;
264
+ # </span><span style="font-weight:bold;color:#a71d5d;">end
265
+ # </span>
266
+ # </code></pre>
267
+ ````
268
+
269
+ To disable this plugin, set the value to `nil`:
270
+
271
+ ````ruby
272
+ code = <<~CODE
273
+ ```ruby
274
+ def hello
275
+ puts "hello"
276
+ end
277
+ ```
278
+ CODE
204
279
 
205
- XML will be generated when calling `to_xml` or using `--to=xml` on the command line.
280
+ Commonmarker.to_html(code, plugins: { syntax_highlighter: nil })
206
281
 
207
- ```ruby
208
- doc = CommonMarker.render_doc('*Hello* world!', :DEFAULT)
209
- puts(doc.to_xml)
210
-
211
- <?xml version="1.0" encoding="UTF-8"?>
212
- <!DOCTYPE document SYSTEM "CommonMark.dtd">
213
- <document xmlns="http://commonmark.org/xml/1.0">
214
- <paragraph>
215
- <emph>
216
- <text xml:space="preserve">Hello</text>
217
- </emph>
218
- <text xml:space="preserve"> world!</text>
219
- </paragraph>
220
- </document>
221
- ```
282
+ # <pre lang="ruby"><code>def hello
283
+ # puts &quot;hello&quot;
284
+ # end
285
+ # </code></pre>
286
+ ````
222
287
 
223
- ### Plaintext
288
+ To output CSS classes instead of `style` attributes, set the `theme` key to `""`:
224
289
 
225
- Plaintext will be generated when calling `to_plaintext` or using `--to=plaintext` on the command line.
290
+ ````ruby
291
+ code = <<~CODE
292
+ ```ruby
293
+ def hello
294
+ puts "hello"
295
+ end
296
+ CODE
226
297
 
227
- ```ruby
228
- doc = CommonMarker.render_doc('*Hello* world!', :DEFAULT)
229
- puts(doc.to_plaintext)
298
+ Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "" } })
230
299
 
231
- Hello world!
232
- ```
300
+ # <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>
301
+ # <span class="support function builtin ruby">puts</span> <span class="string quoted double ruby"><span class="punctuation definition string begin ruby">&quot;</span>hello<span class="punctuation definition string end ruby">&quot;</span></span>
302
+ # <span class="keyword control ruby">end</span>\n</span></code></pre>
303
+ ````
233
304
 
234
- ### Commonmark
305
+ To use a custom theme, you can provide a `path` to a directory containing `.tmtheme` files to load:
235
306
 
236
- Commonmark will be generated when calling `to_commonmark` or using `--to=commonmark` on the command line.
307
+ ```ruby
308
+ Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "Monokai", path: "./themes" } })
309
+ ```
237
310
 
238
- ``` ruby
239
- text = <<-TEXT
240
- 1. I am a numeric list.
241
- 2. I continue the list.
242
- * Suddenly, an unordered list!
243
- * What fun!
244
- TEXT
311
+ ## Output formats
245
312
 
246
- doc = CommonMarker.render_doc(text, :DEFAULT)
247
- puts(doc.to_commonmark)
313
+ Commonmarker can currently only generate output in one format: HTML.
248
314
 
249
- 1. I am a numeric list.
250
- 2. I continue the list.
315
+ ### HTML
251
316
 
252
- <!-- end list -->
317
+ ```ruby
318
+ puts Commonmarker.to_html('*Hello* world!')
253
319
 
254
- - Suddenly, an unordered list\!
255
- - What fun\!
320
+ # <p><em>Hello</em> world!</p>
256
321
  ```
257
322
 
258
323
  ## Developing locally
@@ -264,25 +329,36 @@ script/bootstrap
264
329
  bundle exec rake compile
265
330
  ```
266
331
 
267
- If there were no errors, you're done! Otherwise, make sure to follow the CMark dependency instructions.
332
+ If there were no errors, you're done! Otherwise, make sure to follow the comrak dependency instructions.
268
333
 
269
334
  ## Benchmarks
270
335
 
271
- Some rough benchmarks:
272
-
273
336
  ```
274
- $ bundle exec rake benchmark
275
-
276
- input size = 11063727 bytes
277
-
278
- redcarpet
279
- 0.070000 0.020000 0.090000 ( 0.079641)
280
- github-markdown
281
- 0.070000 0.010000 0.080000 ( 0.083535)
282
- commonmarker with to_html
283
- 0.100000 0.010000 0.110000 ( 0.111947)
284
- commonmarker with ruby HtmlRenderer
285
- 1.830000 0.030000 1.860000 ( 1.866203)
286
- kramdown
287
- 4.610000 0.070000 4.680000 ( 4.678398)
337
+ bundle exec rake benchmark
338
+ input size = 11064832 bytes
339
+
340
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
341
+ Warming up --------------------------------------
342
+ Markly.render_html 1.000 i/100ms
343
+ Markly::Node#to_html 1.000 i/100ms
344
+ Commonmarker.to_html 1.000 i/100ms
345
+ Commonmarker::Node.to_html
346
+ 1.000 i/100ms
347
+ Kramdown::Document#to_html
348
+ 1.000 i/100ms
349
+ Calculating -------------------------------------
350
+ Markly.render_html 15.606 (±25.6%) i/s - 71.000 in 5.047132s
351
+ Markly::Node#to_html 15.692 (±25.5%) i/s - 72.000 in 5.095810s
352
+ Commonmarker.to_html 4.482 (± 0.0%) i/s - 23.000 in 5.137680s
353
+ Commonmarker::Node.to_html
354
+ 5.092 (±19.6%) i/s - 25.000 in 5.072220s
355
+ Kramdown::Document#to_html
356
+ 0.379 (± 0.0%) i/s - 2.000 in 5.277770s
357
+
358
+ Comparison:
359
+ Markly::Node#to_html: 15.7 i/s
360
+ Markly.render_html: 15.6 i/s - same-ish: difference falls within error
361
+ Commonmarker::Node.to_html: 5.1 i/s - 3.08x slower
362
+ Commonmarker.to_html: 4.5 i/s - 3.50x slower
363
+ Kramdown::Document#to_html: 0.4 i/s - 41.40x slower
288
364
  ```
@@ -0,0 +1,21 @@
1
+ [package]
2
+ name = "commonmarker"
3
+ version = "1.0.0"
4
+ edition = "2021"
5
+ rust-version = "1.75.0"
6
+ publish = false
7
+
8
+ [dependencies]
9
+ magnus = { version = "0.8", features = ["rb-sys"] }
10
+ rb-sys = { version = "*", default-features = false, features = [
11
+ "stable-api-compiled-fallback",
12
+ ] }
13
+ comrak = { version = "0.52", features = ["shortcodes"] }
14
+ syntect = { version = "5.3", features = ["plist-load"] }
15
+ typed-arena = "2.0"
16
+ rctree = "0.6"
17
+ rb-allocator = "0.9"
18
+
19
+ [lib]
20
+ name = "commonmarker"
21
+ crate-type = ["cdylib"]
@@ -0,0 +1,9 @@
1
+ fn main() {
2
+ // Ruby statically bundles Oniguruma in its Windows library (libx64-ucrt-ruby*.a),
3
+ // which collides with onig_sys pulled in by comrak's syntect dependency.
4
+ // Allow the linker to resolve duplicates by picking the first definition.
5
+ let target = std::env::var("TARGET").unwrap_or_default();
6
+ if target.contains("windows-gnu") {
7
+ println!("cargo:rustc-link-arg=-Wl,--allow-multiple-definition");
8
+ }
9
+ }
@@ -1,7 +1,4 @@
1
- # frozen_string_literal: true
1
+ require "mkmf"
2
+ require "rb_sys/mkmf"
2
3
 
3
- require 'mkmf'
4
-
5
- $CFLAGS << ' -std=c99'
6
-
7
- create_makefile('commonmarker/commonmarker')
4
+ create_rust_makefile("commonmarker/commonmarker")