commonmarker 2.10.0-arm-linux-gnu

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 35327c693dd53702f646b2cce40ee187a4c901340bc370f8e54285acc5a78526
4
+ data.tar.gz: f6913b5d0ff1907b1431dc1333b2a4af393d1ba9dcfe1b2fb13de0307e12570d
5
+ SHA512:
6
+ metadata.gz: 4e14faf517356b5d4ad8d81d7d50676a34da3b0a21be3fef6ef9f5d2cd9afedeeafa9ecb8b35c8bf276eb006fdf4ec5380ec2f6707fb9b9eeef31bc56673eb87
7
+ data.tar.gz: 1d16283507055f8036c093e5db3408854f5b074ee8e15d79b4f0f17ade0e8874294f133a50aaefb1f514f3d9eb731e41bc9e66dcbeeeebd523961d1803be1df5
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Garen J. Torikian
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,385 @@
1
+ # Commonmarker
2
+
3
+ Ruby wrapper for Rust's [comrak](https://github.com/kivikakk/comrak) crate.
4
+
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.
6
+
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).
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ gem 'commonmarker'
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install commonmarker
25
+
26
+ ## Usage
27
+
28
+ This gem expects to receive UTF-8 strings. Ensure your strings are the right encoding before passing them into `Commonmarker`.
29
+
30
+ ### Converting to HTML
31
+
32
+ Call `to_html` on a string to convert it to HTML:
33
+
34
+ ```ruby
35
+ require 'commonmarker'
36
+ Commonmarker.to_html('"Hi *there*"', options: {
37
+ parse: { smart: true }
38
+ })
39
+ # => <p>“Hi <em>there</em>”</p>\n
40
+ ```
41
+
42
+ (The second argument is optional--[see below](#options-and-plugins) for more information.)
43
+
44
+ ### Generating a document
45
+
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:
47
+
48
+ ```ruby
49
+ require 'commonmarker'
50
+
51
+ doc = Commonmarker.parse("*Hello* world", options: {
52
+ parse: { smart: true }
53
+ })
54
+ puts(doc.to_html) # => <p><em>Hello</em> world</p>\n
55
+
56
+ doc.walk do |node|
57
+ puts node.type # => [:document, :paragraph, :emph, :text, :text]
58
+ end
59
+ ```
60
+
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:
64
+
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
91
+
92
+ You can use `walk` or `each` to iterate over nodes:
93
+
94
+ - `walk` will iterate on a node and recursively iterate on a node's children.
95
+ - `each` will iterate on a node's direct children, but no further.
96
+
97
+ ```ruby
98
+ require 'commonmarker'
99
+
100
+ # parse some string
101
+ doc = Commonmarker.parse("# The site\n\n [GitHub](https://www.github.com)")
102
+
103
+ # Walk tree and print out URLs for links
104
+ doc.walk do |node|
105
+ if node.type == :link
106
+ printf("URL = %s\n", node.url)
107
+ end
108
+ end
109
+ # => URL = https://www.github.com
110
+
111
+ # Transform links to regular text
112
+ doc.walk do |node|
113
+ if node.type == :link
114
+ node.insert_before(node.first_child)
115
+ node.delete
116
+ end
117
+ end
118
+ # => <h1><a href=\"#the-site\"></a>The site</h1>\n<p>GitHub</p>\n
119
+ ```
120
+
121
+ #### Example: Converting a document back into raw CommonMark
122
+
123
+ You can use `to_commonmark` on a node to render it as raw text:
124
+
125
+ ```ruby
126
+ require 'commonmarker'
127
+
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
136
+ end
137
+ end
138
+
139
+ doc.to_commonmark
140
+ # => # The site\n\nGitHub\n
141
+ ```
142
+
143
+ ### Reading and writing node content
144
+
145
+ `string_content` reads and writes the text of nodes whose content is plain text (like `:text`, `:code`, and `:code_block`).
146
+
147
+ `literal` reads and writes the raw string a node carries, for every node type that has one (like `:text`, `:code`, `:code_block`, `:html_block`, `:html_inline`, `:raw`, `:math`, and `:frontmatter`).
148
+
149
+ The two exist separately because they mean different things. Rewriting `string_content` only ever swaps text for text. Rewriting `literal` on an `:html_block`, `:html_inline`, or `:raw` node writes markup that is emitted unescaped:
150
+
151
+ ```ruby
152
+ doc = Commonmarker.parse("A <b>bold</b> claim")
153
+
154
+ doc.walk do |node|
155
+ node.literal = "<i>" if node.type == :html_inline && node.literal == "<b>"
156
+ end
157
+ ```
158
+
159
+ Note that a `:frontmatter` node's literal includes its delimiters and trailing newlines, so anything you assign must include them too.
160
+
161
+ ## Options and plugins
162
+
163
+ ### Options
164
+
165
+ Commonmarker accepts the same parse, render, and extensions options that comrak does, as a hash dictionary with symbol keys:
166
+
167
+ ```ruby
168
+ Commonmarker.to_html('"Hi *there*"', options:{
169
+ parse: { smart: true },
170
+ render: { hardbreaks: false}
171
+ })
172
+ ```
173
+
174
+ 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`.
175
+
176
+ ### Parse options
177
+
178
+ | Name | Description | Default |
179
+ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
180
+ | `smart` | Punctuation (quotes, full-stops and hyphens) are converted into 'smart' punctuation. | `false` |
181
+ | `default_info_string` | The default info string for fenced code blocks. | `""` |
182
+ | `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` |
183
+ | `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` |
184
+ | `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` |
185
+ | `ignore_setext` | Ignores setext-style headings. | `false` |
186
+ | `sourcepos_chars` | Use character-based column tracking in source positions instead of byte-based. Relevant for multi-byte UTF-8 documents with `sourcepos`. | `false` |
187
+
188
+ ### Render options
189
+
190
+ | Name | Description | Default |
191
+ | -------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------ |
192
+ | `hardbreaks` | [Soft line breaks](http://spec.commonmark.org/0.27/#soft-line-breaks) translate into hard line breaks. | `true` |
193
+ | `github_pre_lang` | GitHub-style `<pre lang="xyz">` is used for fenced code blocks with info tags. | `true` |
194
+ | `full_info_string` | Gives info string data after a space in a `data-meta` attribute on code blocks. | `false` |
195
+ | `width` | The wrap column when outputting CommonMark. | `80` |
196
+ | `unsafe` | Allow rendering of raw HTML and potentially dangerous links. | `false` |
197
+ | `escape` | Escape raw HTML instead of clobbering it. | `false` |
198
+ | `sourcepos` | Include source position attribute in HTML and XML output. | `false` |
199
+ | `escaped_char_spans` | Wrap escaped characters in span tags. | `true` |
200
+ | `ignore_empty_links` | Ignores empty links, leaving the Markdown text in place. | `false` |
201
+ | `gfm_quirks` | Outputs HTML with GFM-style quirks; namely, not nesting `<strong>` inlines. | `false` |
202
+ | `prefer_fenced` | Always output fenced code blocks, even where an indented one could be used. | `false` |
203
+ | `tasklist_classes` | Add CSS classes to the HTML output of the tasklist extension | `false` |
204
+ | `compact_html` | Suppress newlines in pretty-printed HTML output. | `false` |
205
+ | `alert_style` | The style of alert output: `"specific"` (`<div class="markdown-alert">`) or `"semantic"` (`<aside class="admonition">`). | `"specific"` |
206
+
207
+ As well, there are several extensions which you can toggle in the same manner:
208
+
209
+ ```ruby
210
+ Commonmarker.to_html('"Hi *there*"', options: {
211
+ extension: { footnotes: true, description_lists: true },
212
+ render: { hardbreaks: false }
213
+ })
214
+ ```
215
+
216
+ ### Extension options
217
+
218
+ | Name | Description | Default |
219
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------- |
220
+ | `strikethrough` | Enables the [strikethrough extension](https://github.github.com/gfm/#strikethrough-extension-) from the GFM spec. | `true` |
221
+ | `tagfilter` | Enables the [tagfilter extension](https://github.github.com/gfm/#disallowed-raw-html-extension-) from the GFM spec. | `true` |
222
+ | `table` | Enables the [table extension](https://github.github.com/gfm/#tables-extension-) from the GFM spec. | `true` |
223
+ | `autolink` | Enables the [autolink extension](https://github.github.com/gfm/#autolinks-extension-) from the GFM spec. | `true` |
224
+ | `tasklist` | Enables the [task list extension](https://github.github.com/gfm/#task-list-items-extension-) from the GFM spec. | `true` |
225
+ | `superscript` | Enables the superscript Comrak extension. | `false` |
226
+ | `header_ids` | Enables the header IDs Comrak extension. from the GFM spec. | `""` |
227
+ | `header_id_prefix_in_href` | Also add the prefix to generated `href` attributes pointing to headers. | `false` |
228
+ | `footnotes` | Enables the footnotes extension per `cmark-gfm`. | `false` |
229
+ | `inline_footnotes` | Enables the inline footnotes extension. | `false` |
230
+ | `description_lists` | Enables the description lists extension. | `false` |
231
+ | `front_matter_delimiter` | Enables the front matter extension. | `""` |
232
+ | `multiline_block_quotes` | Enables the multiline block quotes extension. | `false` |
233
+ | `math_dollars`, `math_code` | Enables the math extension. | `false` |
234
+ | `math_latex` | Enables the math extension with LaTeX-style delimiters (`\(inline\)`, `\[display\]`). | `false` |
235
+ | `shortcodes` | Enables the shortcodes extension. | `true` |
236
+ | `wikilinks_title_before_pipe` | Enables the wikilinks extension, placing the title before the dividing pipe. | `false` |
237
+ | `wikilinks_title_after_pipe` | Enables the wikilinks extension, placing the title after the dividing pipe. | `false` |
238
+ | `underline` | Enables the underline extension. | `false` |
239
+ | `spoiler` | Enables the spoiler extension. | `false` |
240
+ | `greentext` | Enables the greentext extension. | `false` |
241
+ | `subtext` | Enables the subtext extension. | `false` |
242
+ | `subscript` | Enables the subscript extension. | `false` |
243
+ | `alerts` | Enables the alerts extension. | `false` |
244
+ | `cjk_friendly_emphasis` | Enables the [CJK friendly emphasis](https://github.com/tats-u/markdown-cjk-friendly) extension. | `false` |
245
+ | `highlight` | Enables highlighting via `==` | `false` |
246
+ | `insert` | Enables the insert extension, rendering `++text++` as `<ins>text</ins>`. | `false` |
247
+ | `block_directive` | Enables the block directive extension. | `false` |
248
+
249
+ For more information on these options, see [the comrak documentation](https://github.com/kivikakk/comrak#usage).
250
+
251
+ ### Plugins
252
+
253
+ In addition to the possibilities provided by generic CommonMark rendering, Commonmarker also supports plugins as a means of
254
+ providing further niceties.
255
+
256
+ #### Syntax Highlighter Plugin
257
+
258
+ 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.
259
+
260
+ 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:
261
+
262
+ - `"base16-ocean.dark"`
263
+ - `"base16-eighties.dark"`
264
+ - `"base16-mocha.dark"`
265
+ - `"base16-ocean.light"`
266
+ - `"InspiredGitHub"`
267
+ - `"Solarized (dark)"`
268
+ - `"Solarized (light)"`
269
+
270
+ ````ruby
271
+ code = <<~CODE
272
+ ```ruby
273
+ def hello
274
+ puts "hello"
275
+ end
276
+ ```
277
+ CODE
278
+
279
+ # pass in a theme name from a pre-existing set
280
+ puts Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "InspiredGitHub" } })
281
+
282
+ # <pre style="background-color:#ffffff;" lang="ruby"><code>
283
+ # <span style="font-weight:bold;color:#a71d5d;">def </span><span style="font-weight:bold;color:#795da3;">hello
284
+ # </span><span style="color:#62a35c;">puts </span><span style="color:#183691;">&quot;hello&quot;
285
+ # </span><span style="font-weight:bold;color:#a71d5d;">end
286
+ # </span>
287
+ # </code></pre>
288
+ ````
289
+
290
+ To disable this plugin, set the value to `nil`:
291
+
292
+ ````ruby
293
+ code = <<~CODE
294
+ ```ruby
295
+ def hello
296
+ puts "hello"
297
+ end
298
+ ```
299
+ CODE
300
+
301
+ Commonmarker.to_html(code, plugins: { syntax_highlighter: nil })
302
+
303
+ # <pre lang="ruby"><code>def hello
304
+ # puts &quot;hello&quot;
305
+ # end
306
+ # </code></pre>
307
+ ````
308
+
309
+ To output CSS classes instead of `style` attributes, set the `theme` key to `""`:
310
+
311
+ ````ruby
312
+ code = <<~CODE
313
+ ```ruby
314
+ def hello
315
+ puts "hello"
316
+ end
317
+ CODE
318
+
319
+ Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "" } })
320
+
321
+ # <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>
322
+ # <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>
323
+ # <span class="keyword control ruby">end</span>\n</span></code></pre>
324
+ ````
325
+
326
+ To use a custom theme, you can provide a `path` to a directory containing `.tmtheme` files to load:
327
+
328
+ ```ruby
329
+ Commonmarker.to_html(code, plugins: { syntax_highlighter: { theme: "Monokai", path: "./themes" } })
330
+ ```
331
+
332
+ ## Output formats
333
+
334
+ Commonmarker can currently only generate output in one format: HTML.
335
+
336
+ ### HTML
337
+
338
+ ```ruby
339
+ puts Commonmarker.to_html('*Hello* world!')
340
+
341
+ # <p><em>Hello</em> world!</p>
342
+ ```
343
+
344
+ ## Developing locally
345
+
346
+ After cloning the repo:
347
+
348
+ ```
349
+ script/bootstrap
350
+ bundle exec rake compile
351
+ ```
352
+
353
+ If there were no errors, you're done! Otherwise, make sure to follow the comrak dependency instructions.
354
+
355
+ ## Benchmarks
356
+
357
+ ```
358
+ ❯ bundle exec rake benchmark
359
+ input size = 11064832 bytes
360
+
361
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
362
+ Warming up --------------------------------------
363
+ Markly.render_html 1.000 i/100ms
364
+ Markly::Node#to_html 1.000 i/100ms
365
+ Commonmarker.to_html 1.000 i/100ms
366
+ Commonmarker::Node.to_html
367
+ 1.000 i/100ms
368
+ Kramdown::Document#to_html
369
+ 1.000 i/100ms
370
+ Calculating -------------------------------------
371
+ Markly.render_html 15.606 (±25.6%) i/s - 71.000 in 5.047132s
372
+ Markly::Node#to_html 15.692 (±25.5%) i/s - 72.000 in 5.095810s
373
+ Commonmarker.to_html 4.482 (± 0.0%) i/s - 23.000 in 5.137680s
374
+ Commonmarker::Node.to_html
375
+ 5.092 (±19.6%) i/s - 25.000 in 5.072220s
376
+ Kramdown::Document#to_html
377
+ 0.379 (± 0.0%) i/s - 2.000 in 5.277770s
378
+
379
+ Comparison:
380
+ Markly::Node#to_html: 15.7 i/s
381
+ Markly.render_html: 15.6 i/s - same-ish: difference falls within error
382
+ Commonmarker::Node.to_html: 5.1 i/s - 3.08x slower
383
+ Commonmarker.to_html: 4.5 i/s - 3.50x slower
384
+ Kramdown::Document#to_html: 0.4 i/s - 41.40x slower
385
+ ```
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Commonmarker
4
+ module Config
5
+ # For details, see
6
+ # https://github.com/kivikakk/comrak/blob/162ef9354deb2c9b4a4e05be495aa372ba5bb696/src/main.rs#L201
7
+ OPTIONS = {
8
+ parse: {
9
+ smart: false,
10
+ default_info_string: "",
11
+ relaxed_tasklist_matching: false,
12
+ relaxed_autolinks: false,
13
+ leave_footnote_definitions: false,
14
+ ignore_setext: false,
15
+ sourcepos_chars: false,
16
+ }.freeze,
17
+ render: {
18
+ hardbreaks: true,
19
+ github_pre_lang: true,
20
+ full_info_string: false,
21
+ width: 80,
22
+ unsafe: false,
23
+ escape: false,
24
+ sourcepos: false,
25
+ escaped_char_spans: true,
26
+ ignore_empty_links: false,
27
+ gfm_quirks: false,
28
+ prefer_fenced: false,
29
+ tasklist_classes: false,
30
+ compact_html: false,
31
+ alert_style: "specific",
32
+ }.freeze,
33
+ extension: {
34
+ strikethrough: true,
35
+ tagfilter: true,
36
+ table: true,
37
+ autolink: true,
38
+ tasklist: true,
39
+ superscript: false,
40
+ header_ids: "",
41
+ header_id_prefix_in_href: false,
42
+ footnotes: false,
43
+ inline_footnotes: false,
44
+ description_lists: false,
45
+ front_matter_delimiter: "",
46
+ multiline_block_quotes: false,
47
+ math_dollars: false,
48
+ math_code: false,
49
+ math_latex: false,
50
+ shortcodes: true,
51
+ wikilinks_title_before_pipe: false,
52
+ wikilinks_title_after_pipe: false,
53
+ underline: false,
54
+ spoiler: false,
55
+ greentext: false,
56
+ subscript: false,
57
+ subtext: false,
58
+ alerts: false,
59
+ cjk_friendly_emphasis: false,
60
+ highlight: false,
61
+ insert: false,
62
+ block_directive: false,
63
+ }.freeze,
64
+ format: [:html].freeze,
65
+ }.freeze
66
+
67
+ PLUGINS = {
68
+ syntax_highlighter: {
69
+ theme: "base16-ocean.dark",
70
+ path: "",
71
+ }.freeze,
72
+ }.freeze
73
+
74
+ class << self
75
+ include Commonmarker::Utils
76
+
77
+ def process_options(options)
78
+ {
79
+ parse: process_parse_options(options[:parse].dup),
80
+ render: process_render_options(options[:render].dup),
81
+ extension: process_extension_options(options[:extension].dup),
82
+ }
83
+ end
84
+
85
+ def process_plugins(plugins)
86
+ {
87
+ syntax_highlighter: process_syntax_highlighter_plugin(plugins&.fetch(:syntax_highlighter, nil)),
88
+ }
89
+ end
90
+ end
91
+
92
+ [:parse, :render, :extension].each do |type|
93
+ define_singleton_method :"process_#{type}_options" do |options|
94
+ Commonmarker::Config::OPTIONS[type].each_with_object({}) do |(key, value), hash|
95
+ if options.nil? || !options.key?(key) # option not provided, use the default
96
+ hash[key] = value
97
+ next
98
+ end
99
+
100
+ if options[key].nil? # # option explicitly not included, remove it
101
+ options.delete(key)
102
+ next
103
+ end
104
+
105
+ hash[key] = fetch_kv(options, key, value, type)
106
+ end
107
+ end
108
+ end
109
+
110
+ define_singleton_method :process_syntax_highlighter_plugin do |options|
111
+ return if options.nil? # plugin explicitly nil, remove it
112
+
113
+ raise TypeError, "Expected a Hash for syntax_highlighter plugin, got #{options.class}" unless options.is_a?(Hash)
114
+ raise TypeError, "Expected a Hash for syntax_highlighter plugin, got nothing" if options.empty?
115
+
116
+ Commonmarker::Config::PLUGINS[:syntax_highlighter].merge(options)
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Commonmarker
4
+ module Constants
5
+ BOOLS = [true, false].freeze
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ # native precompiled gems package shared libraries in <gem_dir>/lib/commonmarker/<ruby_version>
5
+ # load the precompiled extension file
6
+ ruby_version = /\d+\.\d+/.match(RUBY_VERSION)
7
+ require_relative "#{ruby_version}/commonmarker"
8
+ rescue LoadError
9
+ # fall back to the extension compiled upon installation.
10
+ # use "require" instead of "require_relative" because non-native gems will place C extension files
11
+ # in Gem::BasicSpecification#extension_dir after compilation (during normal installation), which
12
+ # is in $LOAD_PATH but not necessarily relative to this file (see nokogiri#2300)
13
+ require "commonmarker/commonmarker"
14
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Commonmarker
4
+ class Node
5
+ class Ast
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pp"
4
+
5
+ module Commonmarker
6
+ class Node
7
+ module Inspect
8
+ PP_INDENT_SIZE = 2
9
+
10
+ def inspect
11
+ PP.pp(self, +"", Float::INFINITY)
12
+ end
13
+
14
+ # @param printer [PrettyPrint] pp
15
+ def pretty_print(printer)
16
+ printer.group(PP_INDENT_SIZE, "#<#{self.class}(#{type}):", ">") do
17
+ printer.breakable
18
+
19
+ attrs = [
20
+ :source_position,
21
+ :string_content,
22
+ :url,
23
+ :title,
24
+ :header_level,
25
+ :list_type,
26
+ :list_start,
27
+ :list_tight,
28
+ :fence_info,
29
+ :alert_type,
30
+ ].filter_map do |name|
31
+ [name, __send__(name)] if respond_to?(name)
32
+ end
33
+
34
+ printer.seplist(attrs) do |name, value|
35
+ printer.text("#{name}=")
36
+ printer.pp(value)
37
+ end
38
+
39
+ if first_child
40
+ printer.breakable
41
+ printer.group(PP_INDENT_SIZE) do
42
+ children = []
43
+ node = first_child
44
+ while node
45
+ children << node
46
+ node = node.next_sibling
47
+ end
48
+ printer.text("children=")
49
+ printer.pp(children)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "commonmarker/node/ast"
4
+ require "commonmarker/node/inspect"
5
+
6
+ module Commonmarker
7
+ class Node
8
+ include Enumerable
9
+ include Inspect
10
+
11
+ # Public: Whether this node responds to the given method.
12
+ #
13
+ # name - A {Symbol} or {String} naming the method.
14
+ # include_all - A {Boolean} indicating whether to consider private methods.
15
+ #
16
+ # Returns a {Boolean}.
17
+ def respond_to?(name, include_all = false)
18
+ return false if node_supports?(name.to_sym) == false
19
+
20
+ super
21
+ end
22
+
23
+ # Public: An iterator that "walks the tree," descending into children recursively.
24
+ #
25
+ # blk - A {Proc} representing the action to take for each child
26
+ def walk(&block)
27
+ return enum_for(:walk) unless block
28
+
29
+ yield self
30
+ each do |child|
31
+ child.walk(&block)
32
+ end
33
+ end
34
+
35
+ # Public: Iterate over the children (if any) of the current pointer.
36
+ def each
37
+ return enum_for(:each) unless block_given?
38
+
39
+ child = first_child
40
+ while child
41
+ next_child = child.next_sibling
42
+ yield child
43
+ child = next_child
44
+ end
45
+ end
46
+
47
+ # Public: Converts a node to an HTML string.
48
+ #
49
+ # options - A {Hash} of render, parse, and extension options to transform the text.
50
+ # plugins - A {Hash} of additional plugins.
51
+ #
52
+ # Returns a {String} of HTML.
53
+ def to_html(options: Commonmarker::Config::OPTIONS, plugins: Commonmarker::Config::PLUGINS)
54
+ raise TypeError, "options must be a Hash; got a #{options.class}!" unless options.is_a?(Hash)
55
+
56
+ opts = Config.process_options(options)
57
+ plugins = Config.process_plugins(plugins)
58
+
59
+ node_to_html(render: opts[:render], parse: opts[:parse], extension: opts[:extension], plugins: plugins).force_encoding("utf-8")
60
+ end
61
+
62
+ # Public: Convert the node to a CommonMark string.
63
+ #
64
+ # options - A {Symbol} or {Array of Symbol}s indicating the render options
65
+ # plugins - A {Hash} of additional plugins.
66
+ #
67
+ # Returns a {String}.
68
+ def to_commonmark(options: Commonmarker::Config::OPTIONS, plugins: Commonmarker::Config::PLUGINS)
69
+ raise TypeError, "options must be a Hash; got a #{options.class}!" unless options.is_a?(Hash)
70
+
71
+ opts = Config.process_options(options)
72
+ plugins = Config.process_plugins(plugins)
73
+
74
+ node_to_commonmark(render: opts[:render], parse: opts[:parse], extension: opts[:extension], plugins: plugins).force_encoding("utf-8")
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+ require "stringio"
5
+
6
+ module Commonmarker
7
+ class Renderer
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "commonmarker/constants"
4
+
5
+ module Commonmarker
6
+ module Utils
7
+ include Commonmarker::Constants
8
+
9
+ def fetch_kv(options, key, value, type)
10
+ value_klass = value.class
11
+
12
+ if Constants::BOOLS.include?(value) && BOOLS.include?(options[key])
13
+ options[key]
14
+ elsif options[key].is_a?(value_klass)
15
+ options[key]
16
+ else
17
+ expected_type = Constants::BOOLS.include?(value) ? "Boolean" : value_klass.to_s
18
+ raise TypeError, "#{type} option `:#{key}` must be #{expected_type}; got #{options[key].class}"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Commonmarker
4
+ VERSION = "2.10.0"
5
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "commonmarker/extension"
4
+
5
+ require "commonmarker/utils"
6
+ require "commonmarker/node"
7
+ require "commonmarker/config"
8
+ require "commonmarker/renderer"
9
+ require "commonmarker/version"
10
+
11
+ module Commonmarker
12
+ class << self
13
+ # Public: Parses a CommonMark string into an HTML string.
14
+ #
15
+ # text - A {String} of text
16
+ # options - A {Hash} of render, parse, and extension options to transform the text.
17
+ #
18
+ # Returns the `parser` node.
19
+ def parse(text, options: Commonmarker::Config::OPTIONS)
20
+ raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
21
+ raise TypeError, "text must be UTF-8 encoded; got #{text.encoding}!" unless text.encoding.name == "UTF-8"
22
+ raise TypeError, "options must be a Hash; got a #{options.class}!" unless options.is_a?(Hash)
23
+
24
+ opts = Config.process_options(options)
25
+
26
+ commonmark_parse(text, parse: opts.fetch(:parse, {}), render: opts.fetch(:render, {}), extension: opts.fetch(:extension, {}))
27
+ end
28
+
29
+ # Public: Parses a CommonMark string into an HTML string.
30
+ #
31
+ # text - A {String} of text
32
+ # options - A {Hash} of render, parse, and extension options to transform the text.
33
+ # plugins - A {Hash} of additional plugins.
34
+ #
35
+ # Returns a {String} of converted HTML.
36
+ def to_html(text, options: Commonmarker::Config::OPTIONS, plugins: Commonmarker::Config::PLUGINS)
37
+ raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
38
+ raise TypeError, "text must be UTF-8 encoded; got #{text.encoding}!" unless text.encoding.name == "UTF-8"
39
+ raise TypeError, "options must be a Hash; got a #{options.class}!" unless options.is_a?(Hash)
40
+
41
+ opts = Config.process_options(options)
42
+ plugins = Config.process_plugins(plugins)
43
+
44
+ commonmark_to_html(text, parse: opts.fetch(:parse, {}), render: opts.fetch(:render, {}), extension: opts.fetch(:extension, {}), plugins: plugins)
45
+ end
46
+ end
47
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: commonmarker
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.10.0
5
+ platform: arm-linux-gnu
6
+ authors:
7
+ - Garen Torikian
8
+ - Ashe Connor
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2026-08-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A fast, safe, extensible parser for CommonMark. This wraps the comrak
14
+ Rust crate.
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - LICENSE.txt
20
+ - README.md
21
+ - lib/commonmarker.rb
22
+ - lib/commonmarker/3.2/commonmarker.so
23
+ - lib/commonmarker/3.3/commonmarker.so
24
+ - lib/commonmarker/3.4/commonmarker.so
25
+ - lib/commonmarker/4.0/commonmarker.so
26
+ - lib/commonmarker/config.rb
27
+ - lib/commonmarker/constants.rb
28
+ - lib/commonmarker/extension.rb
29
+ - lib/commonmarker/node.rb
30
+ - lib/commonmarker/node/ast.rb
31
+ - lib/commonmarker/node/inspect.rb
32
+ - lib/commonmarker/renderer.rb
33
+ - lib/commonmarker/utils.rb
34
+ - lib/commonmarker/version.rb
35
+ homepage: https://github.com/gjtorikian/commonmarker
36
+ licenses:
37
+ - MIT
38
+ metadata:
39
+ allowed_push_host: https://rubygems.org
40
+ funding_uri: https://github.com/sponsors/gjtorikian/
41
+ source_code_uri: https://github.com/gjtorikian/commonmarker
42
+ rubygems_mfa_required: 'true'
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '3.2'
51
+ - - "<"
52
+ - !ruby/object:Gem::Version
53
+ version: 4.1.dev
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '3.4'
59
+ requirements: []
60
+ rubygems_version: 3.6.9
61
+ specification_version: 4
62
+ summary: CommonMark parser and renderer. Written in Rust, wrapped in Ruby.
63
+ test_files: []