commonmarker 0.23.10 → 2.8.2

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 +253 -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 +1310 -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 +15 -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,80 @@ 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
+ - `alert_type`
89
+
90
+ #### Example: Walking the AST
56
91
 
57
92
  You can use `walk` or `each` to iterate over nodes:
58
93
 
59
94
  - `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.
95
+ - `each` will iterate on a node's direct children, but no further.
61
96
 
62
- ``` ruby
97
+ ```ruby
63
98
  require 'commonmarker'
64
99
 
65
- # parse the files specified on the command line
66
- doc = CommonMarker.render_doc("# The site\n\n [GitHub](https://www.github.com)")
100
+ # parse some string
101
+ doc = Commonmarker.parse("# The site\n\n [GitHub](https://www.github.com)")
67
102
 
68
103
  # Walk tree and print out URLs for links
69
104
  doc.walk do |node|
@@ -71,17 +106,7 @@ doc.walk do |node|
71
106
  printf("URL = %s\n", node.url)
72
107
  end
73
108
  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
109
+ # => URL = https://www.github.com
85
110
 
86
111
  # Transform links to regular text
87
112
  doc.walk do |node|
@@ -90,169 +115,210 @@ doc.walk do |node|
90
115
  node.delete
91
116
  end
92
117
  end
118
+ # => <h1><a href=\"#the-site\"></a>The site</h1>\n<p>GitHub</p>\n
93
119
  ```
94
120
 
95
- ### Creating a custom renderer
121
+ #### Example: Converting a document back into raw CommonMark
96
122
 
97
- You can also derive a class from CommonMarker's `HtmlRenderer` class. This produces slower output, but is far more customizable. For example:
123
+ You can use `to_commonmark` on a node to render it as raw text:
98
124
 
99
- ``` ruby
100
- class MyHtmlRenderer < CommonMarker::HtmlRenderer
101
- def initialize
102
- super
103
- @headerid = 1
104
- end
125
+ ```ruby
126
+ require 'commonmarker'
105
127
 
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
128
+ # parse some string
129
+ doc = Commonmarker.parse("# The site\n\n [GitHub](https://www.github.com)")
130
+
131
+ # Transform links to regular text
132
+ doc.walk do |node|
133
+ if node.type == :link
134
+ node.insert_before(node.first_child)
135
+ node.delete
112
136
  end
113
137
  end
114
138
 
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
139
+ doc.to_commonmark
140
+ # => # The site\n\nGitHub\n
122
141
  ```
123
142
 
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.
143
+ ## Options and plugins
127
144
 
128
- ### Parse options
145
+ ### Options
129
146
 
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))
147
+ Commonmarker accepts the same parse, render, and extensions options that comrak does, as a hash dictionary with symbol keys:
140
148
 
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])
149
+ ```ruby
150
+ Commonmarker.to_html('"Hi *there*"', options:{
151
+ parse: { smart: true },
152
+ render: { hardbreaks: false}
153
+ })
172
154
  ```
173
155
 
174
- For more information on these options, see [the CMark documentation](https://git.io/v7nh1).
175
-
176
- ## Extensions
156
+ 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
157
 
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
158
+ ### Parse options
189
159
 
190
- Like CMark, CommonMarker can generate output in several formats: HTML, XML, plaintext, and commonmark are currently supported.
160
+ | Name | Description | Default |
161
+ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
162
+ | `smart` | Punctuation (quotes, full-stops and hyphens) are converted into 'smart' punctuation. | `false` |
163
+ | `default_info_string` | The default info string for fenced code blocks. | `""` |
164
+ | `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` |
165
+ | `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` |
166
+ | `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` |
167
+ | `ignore_setext` | Ignores setext-style headings. | `false` |
168
+ | `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
169
 
192
- ### HTML
170
+ ### Render options
193
171
 
194
- The default output format, HTML, will be generated when calling `to_html` or using `--to=html` on the command line.
172
+ | Name | Description | Default |
173
+ | -------------------- | ------------------------------------------------------------------------------------------------------ | ------- |
174
+ | `hardbreaks` | [Soft line breaks](http://spec.commonmark.org/0.27/#soft-line-breaks) translate into hard line breaks. | `true` |
175
+ | `github_pre_lang` | GitHub-style `<pre lang="xyz">` is used for fenced code blocks with info tags. | `true` |
176
+ | `full_info_string` | Gives info string data after a space in a `data-meta` attribute on code blocks. | `false` |
177
+ | `width` | The wrap column when outputting CommonMark. | `80` |
178
+ | `unsafe` | Allow rendering of raw HTML and potentially dangerous links. | `false` |
179
+ | `escape` | Escape raw HTML instead of clobbering it. | `false` |
180
+ | `sourcepos` | Include source position attribute in HTML and XML output. | `false` |
181
+ | `escaped_char_spans` | Wrap escaped characters in span tags. | `true` |
182
+ | `ignore_empty_links` | Ignores empty links, leaving the Markdown text in place. | `false` |
183
+ | `gfm_quirks` | Outputs HTML with GFM-style quirks; namely, not nesting `<strong>` inlines. | `false` |
184
+ | `prefer_fenced` | Always output fenced code blocks, even where an indented one could be used. | `false` |
185
+ | `tasklist_classes` | Add CSS classes to the HTML output of the tasklist extension | `false` |
186
+ | `compact_html` | Suppress newlines in pretty-printed HTML output. | `false` |
187
+
188
+ As well, there are several extensions which you can toggle in the same manner:
195
189
 
196
190
  ```ruby
197
- doc = CommonMarker.render_doc('*Hello* world!', :DEFAULT)
198
- puts(doc.to_html)
199
-
200
- <p><em>Hello</em> world!</p>
191
+ Commonmarker.to_html('"Hi *there*"', options: {
192
+ extension: { footnotes: true, description_lists: true },
193
+ render: { hardbreaks: false }
194
+ })
201
195
  ```
202
196
 
203
- ### XML
197
+ ### Extension options
198
+
199
+ | Name | Description | Default |
200
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------- |
201
+ | `strikethrough` | Enables the [strikethrough extension](https://github.github.com/gfm/#strikethrough-extension-) from the GFM spec. | `true` |
202
+ | `tagfilter` | Enables the [tagfilter extension](https://github.github.com/gfm/#disallowed-raw-html-extension-) from the GFM spec. | `true` |
203
+ | `table` | Enables the [table extension](https://github.github.com/gfm/#tables-extension-) from the GFM spec. | `true` |
204
+ | `autolink` | Enables the [autolink extension](https://github.github.com/gfm/#autolinks-extension-) from the GFM spec. | `true` |
205
+ | `tasklist` | Enables the [task list extension](https://github.github.com/gfm/#task-list-items-extension-) from the GFM spec. | `true` |
206
+ | `superscript` | Enables the superscript Comrak extension. | `false` |
207
+ | `header_ids` | Enables the header IDs Comrak extension. from the GFM spec. | `""` |
208
+ | `header_id_prefix_in_href` | Also add the prefix to generated `href` attributes pointing to headers. | `false` |
209
+ | `footnotes` | Enables the footnotes extension per `cmark-gfm`. | `false` |
210
+ | `inline_footnotes` | Enables the inline footnotes extension. | `false` |
211
+ | `description_lists` | Enables the description lists extension. | `false` |
212
+ | `front_matter_delimiter` | Enables the front matter extension. | `""` |
213
+ | `multiline_block_quotes` | Enables the multiline block quotes extension. | `false` |
214
+ | `math_dollars`, `math_code` | Enables the math extension. | `false` |
215
+ | `shortcodes` | Enables the shortcodes extension. | `true` |
216
+ | `wikilinks_title_before_pipe` | Enables the wikilinks extension, placing the title before the dividing pipe. | `false` |
217
+ | `wikilinks_title_after_pipe` | Enables the wikilinks extension, placing the title after the dividing pipe. | `false` |
218
+ | `underline` | Enables the underline extension. | `false` |
219
+ | `spoiler` | Enables the spoiler extension. | `false` |
220
+ | `greentext` | Enables the greentext extension. | `false` |
221
+ | `subtext` | Enables the subtext extension. | `false` |
222
+ | `subscript` | Enables the subscript extension. | `false` |
223
+ | `alerts` | Enables the alerts extension. | `false` |
224
+ | `cjk_friendly_emphasis` | Enables the [CJK friendly emphasis](https://github.com/tats-u/markdown-cjk-friendly) extension. | `false` |
225
+ | `highlight` | Enables highlighting via `==` | `false` |
226
+ | `insert` | Enables the insert extension, rendering `++text++` as `<ins>text</ins>`. | `false` |
227
+ | `block_directive` | Enables the block directive extension. | `false` |
228
+
229
+ For more information on these options, see [the comrak documentation](https://github.com/kivikakk/comrak#usage).
230
+
231
+ ### Plugins
232
+
233
+ In addition to the possibilities provided by generic CommonMark rendering, Commonmarker also supports plugins as a means of
234
+ providing further niceties.
235
+
236
+ #### Syntax Highlighter Plugin
237
+
238
+ 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.
239
+
240
+ 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:
241
+
242
+ - `"base16-ocean.dark"`
243
+ - `"base16-eighties.dark"`
244
+ - `"base16-mocha.dark"`
245
+ - `"base16-ocean.light"`
246
+ - `"InspiredGitHub"`
247
+ - `"Solarized (dark)"`
248
+ - `"Solarized (light)"`
249
+
250
+ ````ruby
251
+ code = <<~CODE
252
+ ```ruby
253
+ def hello
254
+ puts "hello"
255
+ end
256
+ ```
257
+ CODE
258
+
259
+ # pass in a theme name from a pre-existing set
260
+ puts Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "InspiredGitHub" } })
261
+
262
+ # <pre style="background-color:#ffffff;" lang="ruby"><code>
263
+ # <span style="font-weight:bold;color:#a71d5d;">def </span><span style="font-weight:bold;color:#795da3;">hello
264
+ # </span><span style="color:#62a35c;">puts </span><span style="color:#183691;">&quot;hello&quot;
265
+ # </span><span style="font-weight:bold;color:#a71d5d;">end
266
+ # </span>
267
+ # </code></pre>
268
+ ````
269
+
270
+ To disable this plugin, set the value to `nil`:
271
+
272
+ ````ruby
273
+ code = <<~CODE
274
+ ```ruby
275
+ def hello
276
+ puts "hello"
277
+ end
278
+ ```
279
+ CODE
204
280
 
205
- XML will be generated when calling `to_xml` or using `--to=xml` on the command line.
281
+ Commonmarker.to_html(code, plugins: { syntax_highlighter: nil })
206
282
 
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
- ```
283
+ # <pre lang="ruby"><code>def hello
284
+ # puts &quot;hello&quot;
285
+ # end
286
+ # </code></pre>
287
+ ````
222
288
 
223
- ### Plaintext
289
+ To output CSS classes instead of `style` attributes, set the `theme` key to `""`:
224
290
 
225
- Plaintext will be generated when calling `to_plaintext` or using `--to=plaintext` on the command line.
291
+ ````ruby
292
+ code = <<~CODE
293
+ ```ruby
294
+ def hello
295
+ puts "hello"
296
+ end
297
+ CODE
226
298
 
227
- ```ruby
228
- doc = CommonMarker.render_doc('*Hello* world!', :DEFAULT)
229
- puts(doc.to_plaintext)
299
+ Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "" } })
230
300
 
231
- Hello world!
232
- ```
301
+ # <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>
302
+ # <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>
303
+ # <span class="keyword control ruby">end</span>\n</span></code></pre>
304
+ ````
233
305
 
234
- ### Commonmark
306
+ To use a custom theme, you can provide a `path` to a directory containing `.tmtheme` files to load:
235
307
 
236
- Commonmark will be generated when calling `to_commonmark` or using `--to=commonmark` on the command line.
308
+ ```ruby
309
+ Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "Monokai", path: "./themes" } })
310
+ ```
237
311
 
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
312
+ ## Output formats
245
313
 
246
- doc = CommonMarker.render_doc(text, :DEFAULT)
247
- puts(doc.to_commonmark)
314
+ Commonmarker can currently only generate output in one format: HTML.
248
315
 
249
- 1. I am a numeric list.
250
- 2. I continue the list.
316
+ ### HTML
251
317
 
252
- <!-- end list -->
318
+ ```ruby
319
+ puts Commonmarker.to_html('*Hello* world!')
253
320
 
254
- - Suddenly, an unordered list\!
255
- - What fun\!
321
+ # <p><em>Hello</em> world!</p>
256
322
  ```
257
323
 
258
324
  ## Developing locally
@@ -264,25 +330,36 @@ script/bootstrap
264
330
  bundle exec rake compile
265
331
  ```
266
332
 
267
- If there were no errors, you're done! Otherwise, make sure to follow the CMark dependency instructions.
333
+ If there were no errors, you're done! Otherwise, make sure to follow the comrak dependency instructions.
268
334
 
269
335
  ## Benchmarks
270
336
 
271
- Some rough benchmarks:
272
-
273
337
  ```
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)
338
+ bundle exec rake benchmark
339
+ input size = 11064832 bytes
340
+
341
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
342
+ Warming up --------------------------------------
343
+ Markly.render_html 1.000 i/100ms
344
+ Markly::Node#to_html 1.000 i/100ms
345
+ Commonmarker.to_html 1.000 i/100ms
346
+ Commonmarker::Node.to_html
347
+ 1.000 i/100ms
348
+ Kramdown::Document#to_html
349
+ 1.000 i/100ms
350
+ Calculating -------------------------------------
351
+ Markly.render_html 15.606 (±25.6%) i/s - 71.000 in 5.047132s
352
+ Markly::Node#to_html 15.692 (±25.5%) i/s - 72.000 in 5.095810s
353
+ Commonmarker.to_html 4.482 (± 0.0%) i/s - 23.000 in 5.137680s
354
+ Commonmarker::Node.to_html
355
+ 5.092 (±19.6%) i/s - 25.000 in 5.072220s
356
+ Kramdown::Document#to_html
357
+ 0.379 (± 0.0%) i/s - 2.000 in 5.277770s
358
+
359
+ Comparison:
360
+ Markly::Node#to_html: 15.7 i/s
361
+ Markly.render_html: 15.6 i/s - same-ish: difference falls within error
362
+ Commonmarker::Node.to_html: 5.1 i/s - 3.08x slower
363
+ Commonmarker.to_html: 4.5 i/s - 3.50x slower
364
+ Kramdown::Document#to_html: 0.4 i/s - 41.40x slower
288
365
  ```
@@ -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")