commonmarker 0.17.13 → 0.23.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of commonmarker might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/README.md +94 -18
- data/Rakefile +24 -5
- data/bin/commonmarker +107 -47
- data/commonmarker.gemspec +18 -15
- data/ext/commonmarker/autolink.c +10 -6
- data/ext/commonmarker/blocks.c +102 -31
- data/ext/commonmarker/buffer.c +0 -1
- data/ext/commonmarker/chunk.h +0 -1
- data/ext/commonmarker/cmark-gfm-core-extensions.h +29 -0
- data/ext/commonmarker/cmark-gfm-extension_api.h +19 -2
- data/ext/commonmarker/cmark-gfm.h +19 -5
- data/ext/commonmarker/cmark-gfm_version.h +2 -2
- data/ext/commonmarker/commonmark.c +33 -12
- data/ext/commonmarker/commonmarker.c +209 -100
- data/ext/commonmarker/core-extensions.c +2 -0
- data/ext/commonmarker/ext_scanners.c +622 -684
- data/ext/commonmarker/ext_scanners.h +2 -0
- data/ext/commonmarker/extconf.rb +3 -1
- data/ext/commonmarker/footnotes.c +23 -0
- data/ext/commonmarker/footnotes.h +2 -0
- data/ext/commonmarker/houdini_href_e.c +1 -1
- data/ext/commonmarker/html.c +46 -25
- data/ext/commonmarker/inlines.c +127 -30
- data/ext/commonmarker/iterator.h +0 -1
- data/ext/commonmarker/map.h +0 -1
- data/ext/commonmarker/node.c +17 -3
- data/ext/commonmarker/node.h +9 -0
- data/ext/commonmarker/parser.h +2 -1
- data/ext/commonmarker/plaintext.c +22 -0
- data/ext/commonmarker/render.c +18 -15
- data/ext/commonmarker/render.h +0 -1
- data/ext/commonmarker/scanners.c +779 -953
- data/ext/commonmarker/scanners.h +0 -2
- data/ext/commonmarker/strikethrough.c +4 -1
- data/ext/commonmarker/syntax_extension.c +10 -0
- data/ext/commonmarker/syntax_extension.h +2 -0
- data/ext/commonmarker/table.c +178 -31
- data/ext/commonmarker/tasklist.c +156 -0
- data/ext/commonmarker/tasklist.h +8 -0
- data/ext/commonmarker/xml.c +9 -2
- data/lib/commonmarker/config.rb +41 -38
- data/lib/commonmarker/errors.rb +12 -0
- data/lib/commonmarker/node/inspect.rb +15 -17
- data/lib/commonmarker/node.rb +14 -2
- data/lib/commonmarker/renderer/html_renderer.rb +45 -36
- data/lib/commonmarker/renderer.rb +16 -10
- data/lib/commonmarker/version.rb +3 -1
- data/lib/commonmarker.rb +8 -7
- data/test/benchmark.rb +26 -21
- data/test/fixtures/strong.md +1 -0
- data/test/fixtures/table.md +10 -0
- data/test/test_attributes.rb +5 -3
- data/test/test_basics.rb +19 -0
- data/test/test_commands.rb +72 -0
- data/test/test_commonmark.rb +15 -13
- data/test/test_doc.rb +31 -29
- data/test/test_encoding.rb +9 -5
- data/test/test_extensions.rb +66 -73
- data/test/test_footnotes.rb +47 -12
- data/test/test_gc.rb +6 -2
- data/test/test_helper.rb +25 -15
- data/test/test_linebreaks.rb +2 -0
- data/test/test_maliciousness.rb +189 -190
- data/test/test_node.rb +12 -12
- data/test/test_options.rb +17 -15
- data/test/test_pathological_inputs.rb +14 -12
- data/test/test_plaintext.rb +23 -21
- data/test/test_renderer.rb +29 -10
- data/test/test_smartpunct.rb +7 -2
- data/test/test_spec.rb +7 -4
- data/test/test_tasklists.rb +43 -0
- data/test/test_xml.rb +107 -0
- metadata +74 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bc6d71b6e85fb61abc438252b07369d3264982cf8fb327d96e5e8333bb23841e
|
4
|
+
data.tar.gz: 1911965561ddf20104db09c44c4e5d25f65a277a28b825bc0c03bb172779a623
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59737cb433c3f4f3d53e06d3466f1f3dcd8a40e201e8b0f26be4d553f45667137e05d980100304e720d0e8fda178da3eaa9e421608cf4e53c6d159ff9261ae3e
|
7
|
+
data.tar.gz: c3088c3219da29bdb0356f46a5b7a7f2881410c825e101f7ced3964760bfcfcb5cef57e7f3ebf5bd9f686b974ad80887fc93899e616afb211dc0e648d6352cd2
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# CommonMarker
|
2
2
|
|
3
|
-
|
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)
|
4
4
|
|
5
5
|
Ruby wrapper for [libcmark-gfm](https://github.com/github/cmark),
|
6
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.
|
@@ -112,10 +112,8 @@ class MyHtmlRenderer < CommonMarker::HtmlRenderer
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
# this renderer prints directly to STDOUT, instead
|
116
|
-
# of returning a string
|
117
115
|
myrenderer = MyHtmlRenderer.new
|
118
|
-
|
116
|
+
puts myrenderer.render(doc)
|
119
117
|
|
120
118
|
# Print any warnings to STDERR
|
121
119
|
renderer.warnings.each do |w|
|
@@ -132,24 +130,31 @@ CommonMarker accepts the same options that CMark does, as symbols. Note that the
|
|
132
130
|
| Name | Description
|
133
131
|
| ----------------------------- | -----------
|
134
132
|
| `:DEFAULT` | The default parsing system.
|
135
|
-
| `:
|
136
|
-
| `:
|
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`.
|
137
136
|
| `:SMART` | Use smart punctuation (curly quotes, etc.).
|
137
|
+
| `:LIBERAL_HTML_TAG` | Support liberal parsing of inline HTML tags.
|
138
|
+
| `:FOOTNOTES` | Parse footnotes.
|
138
139
|
| `:STRIKETHROUGH_DOUBLE_TILDE` | Parse strikethroughs by double tildes (compatibility with [redcarpet](https://github.com/vmg/redcarpet))
|
139
|
-
| `:VALIDATE_UTF8` | Replace illegal sequences with the replacement character `U+FFFD`.
|
140
140
|
|
141
141
|
### Render options
|
142
142
|
|
143
|
-
| Name | Description
|
144
|
-
| ------------------ | -----------
|
145
|
-
| `:DEFAULT` | The default rendering system.
|
146
|
-
| `:
|
147
|
-
| `:HARDBREAKS` | Treat `\n` as hardbreaks (by adding `<br/>`).
|
148
|
-
| `:
|
149
|
-
| `:
|
150
|
-
| `:
|
151
|
-
| `:
|
152
|
-
| `:
|
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. |
|
153
158
|
|
154
159
|
### Passing options
|
155
160
|
|
@@ -175,9 +180,80 @@ Both `render_html` and `render_doc` take an optional third argument defining the
|
|
175
180
|
The available extensions are:
|
176
181
|
|
177
182
|
* `:table` - This provides support for tables.
|
183
|
+
* `:tasklist` - This provides support for task list items.
|
178
184
|
* `:strikethrough` - This provides support for strikethroughs.
|
179
185
|
* `:autolink` - This provides support for automatically converting URLs to anchor tags.
|
180
|
-
* `:tagfilter` - This
|
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
|
189
|
+
|
190
|
+
Like CMark, CommonMarker can generate output in several formats: HTML, XML, plaintext, and commonmark are currently supported.
|
191
|
+
|
192
|
+
### HTML
|
193
|
+
|
194
|
+
The default output format, HTML, will be generated when calling `to_html` or using `--to=html` on the command line.
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
doc = CommonMarker.render_doc('*Hello* world!', :DEFAULT)
|
198
|
+
puts(doc.to_html)
|
199
|
+
|
200
|
+
<p><em>Hello</em> world!</p>
|
201
|
+
```
|
202
|
+
|
203
|
+
### XML
|
204
|
+
|
205
|
+
XML will be generated when calling `to_xml` or using `--to=xml` on the command line.
|
206
|
+
|
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
|
+
```
|
222
|
+
|
223
|
+
### Plaintext
|
224
|
+
|
225
|
+
Plaintext will be generated when calling `to_plaintext` or using `--to=plaintext` on the command line.
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
doc = CommonMarker.render_doc('*Hello* world!', :DEFAULT)
|
229
|
+
puts(doc.to_plaintext)
|
230
|
+
|
231
|
+
Hello world!
|
232
|
+
```
|
233
|
+
|
234
|
+
### Commonmark
|
235
|
+
|
236
|
+
Commonmark will be generated when calling `to_commonmark` or using `--to=commonmark` on the command line.
|
237
|
+
|
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
|
245
|
+
|
246
|
+
doc = CommonMarker.render_doc(text, :DEFAULT)
|
247
|
+
puts(doc.to_commonmark)
|
248
|
+
|
249
|
+
1. I am a numeric list.
|
250
|
+
2. I continue the list.
|
251
|
+
|
252
|
+
<!-- end list -->
|
253
|
+
|
254
|
+
- Suddenly, an unordered list\!
|
255
|
+
- What fun\!
|
256
|
+
```
|
181
257
|
|
182
258
|
## Developing locally
|
183
259
|
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'date'
|
2
4
|
require 'rake/clean'
|
3
5
|
require 'rake/extensiontask'
|
@@ -6,7 +8,7 @@ require 'digest/md5'
|
|
6
8
|
host_os = RbConfig::CONFIG['host_os']
|
7
9
|
require 'devkit' if host_os == 'mingw32'
|
8
10
|
|
9
|
-
task :
|
11
|
+
task default: [:test]
|
10
12
|
|
11
13
|
# Gem Spec
|
12
14
|
gem_spec = Gem::Specification.load('commonmarker.gemspec')
|
@@ -33,14 +35,18 @@ end
|
|
33
35
|
task 'test:unit' => :compile
|
34
36
|
|
35
37
|
desc 'Run unit and conformance tests'
|
36
|
-
task :
|
38
|
+
task test: %w[test:unit]
|
39
|
+
|
40
|
+
require 'rubocop/rake_task'
|
41
|
+
|
42
|
+
RuboCop::RakeTask.new(:rubocop)
|
37
43
|
|
38
44
|
desc 'Run benchmarks'
|
39
45
|
task :benchmark do
|
40
46
|
if ENV['FETCH_PROGIT']
|
41
47
|
`rm -rf test/progit`
|
42
48
|
`git clone https://github.com/progit/progit.git test/progit`
|
43
|
-
langs = %w
|
49
|
+
langs = %w[ar az be ca cs de en eo es es-ni fa fi fr hi hu id it ja ko mk nl no-nb pl pt-br ro ru sr th tr uk vi zh zh-tw]
|
44
50
|
langs.each do |lang|
|
45
51
|
`cat test/progit/#{lang}/*/*.markdown >> test/benchinput.md`
|
46
52
|
end
|
@@ -70,13 +76,26 @@ RDoc::Task.new do |rd|
|
|
70
76
|
rd.options << '--fileboxes'
|
71
77
|
end
|
72
78
|
|
79
|
+
desc 'Generate the documentation and run a web server'
|
80
|
+
task serve: [:rdoc] do
|
81
|
+
require 'webrick'
|
82
|
+
|
83
|
+
puts 'Navigate to http://localhost:3000 to see the docs'
|
84
|
+
|
85
|
+
server = WEBrick::HTTPServer.new Port: 3000
|
86
|
+
server.mount '/', WEBrick::HTTPServlet::FileHandler, 'docs'
|
87
|
+
trap('INT') { server.stop }
|
88
|
+
server.start
|
89
|
+
end
|
90
|
+
|
73
91
|
desc 'Generate and publish docs to gh-pages'
|
74
|
-
task :
|
92
|
+
task publish: [:rdoc] do
|
93
|
+
require 'tmpdir'
|
75
94
|
require 'shellwords'
|
76
95
|
|
77
96
|
Dir.mktmpdir do |tmp|
|
78
97
|
system "mv docs/* #{tmp}"
|
79
|
-
system 'git checkout gh-pages'
|
98
|
+
system 'git checkout origin/gh-pages'
|
80
99
|
system 'rm -rf *'
|
81
100
|
system "mv #{tmp}/* ."
|
82
101
|
message = Shellwords.escape("Site updated at #{Time.now.utc}")
|
data/bin/commonmarker
CHANGED
@@ -1,58 +1,118 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# Convert one or more CommonMark files to HTML and write to standard output.
|
4
|
-
# If no FILE argument is provided, text will be read from STDIN.
|
5
|
-
# With --html-renderer, use the HtmlRenderer renderer rather than the native C
|
6
|
-
# renderer.
|
7
|
-
# With --extension=EXTENSION, EXTENSION will be used for parsing, and HTML
|
8
|
-
# output unless --html-renderer is specified.
|
9
|
-
if ARGV.include?('--help') or ARGV.include?('-h')
|
10
|
-
File.read(__FILE__).split("\n").grep(/^# /).each do |line|
|
11
|
-
puts line[2..-1]
|
12
|
-
end
|
13
|
-
exit 0
|
14
|
-
end
|
2
|
+
# frozen_string_literal: true
|
15
3
|
|
16
|
-
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
17
7
|
require 'commonmarker'
|
18
8
|
|
19
|
-
|
20
|
-
|
21
|
-
exit 0
|
22
|
-
end
|
9
|
+
root = File.expand_path('..', __dir__)
|
10
|
+
$LOAD_PATH.unshift File.expand_path('lib', root)
|
23
11
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
extensions = CommonMarker.extensions
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
renderer =
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
12
|
+
def parse_options
|
13
|
+
options = Struct.new(:active_extensions, :active_parse_options, :active_render_options, :output_format, :renderer)
|
14
|
+
.new([], [:DEFAULT], [:DEFAULT], :html)
|
15
|
+
extensions = CommonMarker.extensions
|
16
|
+
parse_options = CommonMarker::Config::OPTS.fetch(:parse)
|
17
|
+
render_options = CommonMarker::Config::OPTS.fetch(:render)
|
18
|
+
format_options = CommonMarker::Config::OPTS.fetch(:format)
|
19
|
+
|
20
|
+
option_parser = OptionParser.new do |opts|
|
21
|
+
opts.banner = 'Usage: commonmarker [--html-renderer] [--extension=EXTENSION]'
|
22
|
+
opts.separator ' [--to=FORMAT]'
|
23
|
+
opts.separator ' [--parse-option=OPTION]'
|
24
|
+
opts.separator ' [--render-option=OPTION]'
|
25
|
+
opts.separator ' [FILE..]'
|
26
|
+
opts.separator ''
|
27
|
+
opts.separator 'Convert one or more CommonMark files to HTML and write to standard output.'
|
28
|
+
opts.separator 'If no FILE argument is provided, text will be read from STDIN.'
|
29
|
+
opts.separator ''
|
30
|
+
|
31
|
+
opts.on('--extension=EXTENSION', Array, 'Use EXTENSION for parsing and HTML output (unless --html-renderer is specified)') do |values|
|
32
|
+
values.each do |value|
|
33
|
+
if extensions.include?(value)
|
34
|
+
options.active_extensions << value.to_sym
|
35
|
+
else
|
36
|
+
abort("extension '#{value}' not found")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on('-h', '--help', 'Prints this help') do
|
42
|
+
puts opts
|
43
|
+
puts
|
44
|
+
puts "Available formats: #{format_options.join(', ')}"
|
45
|
+
puts "Available extentions: #{extensions.join(', ')}"
|
46
|
+
puts "Available parse options: #{parse_options.keys.join(', ')}"
|
47
|
+
puts "Available render options: #{render_options.keys.join(', ')}"
|
48
|
+
puts
|
49
|
+
puts 'See the README for more information on these.'
|
50
|
+
exit
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on('-tFORMAT', '--to=FORMAT', String, 'Specify output FORMAT') do |value|
|
54
|
+
value = value.to_sym
|
55
|
+
if format_options.include?(value)
|
56
|
+
options.output_format = value
|
57
|
+
else
|
58
|
+
abort("format '#{value}' not found")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
opts.on('--html-renderer', 'Use the HtmlRenderer renderer rather than the native C renderer (only valid when format is html)') do
|
63
|
+
options.renderer = true
|
64
|
+
end
|
65
|
+
|
66
|
+
opts.on('--parse-option=OPTION', Array, 'OPTION passed during parsing') do |values|
|
67
|
+
values.each do |value|
|
68
|
+
if parse_options.key?(value.to_sym)
|
69
|
+
options.active_parse_options << value.to_sym
|
70
|
+
else
|
71
|
+
abort("parse-option '#{value}' not found")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
opts.on('--render-option=OPTION', Array, 'OPTION passed during rendering') do |values|
|
77
|
+
values.each do |value|
|
78
|
+
if render_options.key?(value.to_sym)
|
79
|
+
options.active_render_options << value.to_sym
|
80
|
+
else
|
81
|
+
abort("render-option '#{value}' not found")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
opts.on('-v', '--version', 'Version information') do
|
87
|
+
puts "commonmarker #{CommonMarker::VERSION}"
|
88
|
+
exit
|
44
89
|
end
|
45
|
-
true
|
46
|
-
else
|
47
|
-
false
|
48
90
|
end
|
91
|
+
|
92
|
+
option_parser.parse!
|
93
|
+
|
94
|
+
options
|
49
95
|
end
|
50
96
|
|
51
|
-
|
97
|
+
options = parse_options
|
98
|
+
|
99
|
+
abort("format '#{options.output_format}' does not support using the HtmlRenderer renderer") if
|
100
|
+
options.renderer && options.output_format != :html
|
52
101
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
102
|
+
doc = CommonMarker.render_doc(ARGF.read, options.active_parse_options, options.active_extensions)
|
103
|
+
|
104
|
+
case options.output_format
|
105
|
+
when :html
|
106
|
+
if options.renderer
|
107
|
+
renderer = CommonMarker::HtmlRenderer.new(options: options.active_render_options, extensions: options.active_extensions)
|
108
|
+
$stdout.write(renderer.render(doc))
|
109
|
+
else
|
110
|
+
$stdout.write(doc.to_html(options.active_render_options, options.active_extensions))
|
111
|
+
end
|
112
|
+
when :xml
|
113
|
+
$stdout.write(doc.to_xml(options.active_render_options))
|
114
|
+
when :commonmark
|
115
|
+
$stdout.write(doc.to_commonmark(options.active_render_options))
|
116
|
+
when :plaintext
|
117
|
+
$stdout.write(doc.to_plaintext(options.active_render_options))
|
58
118
|
end
|
data/commonmarker.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'commonmarker/version'
|
5
6
|
|
@@ -8,29 +9,31 @@ Gem::Specification.new do |s|
|
|
8
9
|
s.version = CommonMarker::VERSION
|
9
10
|
s.summary = 'CommonMark parser and renderer. Written in C, wrapped in Ruby.'
|
10
11
|
s.description = 'A fast, safe, extensible parser for CommonMark. This wraps the official libcmark library.'
|
11
|
-
s.authors
|
12
|
-
s.homepage = '
|
12
|
+
s.authors = ['Garen Torikian', 'Ashe Connor']
|
13
|
+
s.homepage = 'https://github.com/gjtorikian/commonmarker'
|
13
14
|
s.license = 'MIT'
|
14
|
-
s.required_ruby_version = '>= 2.0.0'
|
15
15
|
|
16
|
-
s.files = %w
|
16
|
+
s.files = %w[LICENSE.txt README.md Rakefile commonmarker.gemspec bin/commonmarker]
|
17
17
|
s.files += Dir.glob('lib/**/*.rb')
|
18
18
|
s.files += Dir.glob('ext/commonmarker/*.*')
|
19
|
-
s.test_files = Dir.glob('test/**/*')
|
19
|
+
s.test_files = Dir.glob('test/**/*').reject { |f| f == 'test/benchinput.md' || f.start_with?('test/progit/') }
|
20
20
|
s.extensions = ['ext/commonmarker/extconf.rb']
|
21
21
|
|
22
|
-
s.test_files = s.files.grep(%r{^test/})
|
23
22
|
s.executables = ['commonmarker']
|
24
|
-
s.require_paths = %w
|
23
|
+
s.require_paths = %w[lib ext]
|
24
|
+
s.required_ruby_version = ['>= 2.6', '< 4.0']
|
25
25
|
|
26
|
-
s.
|
26
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
27
27
|
|
28
|
-
s.
|
28
|
+
s.rdoc_options += ['-x', 'ext/commonmarker/cmark/.*']
|
29
29
|
|
30
|
+
s.add_development_dependency 'awesome_print'
|
31
|
+
s.add_development_dependency 'json', '~> 2.3'
|
30
32
|
s.add_development_dependency 'minitest', '~> 5.6'
|
33
|
+
s.add_development_dependency 'minitest-focus', '~> 1.1'
|
34
|
+
s.add_development_dependency 'rake'
|
31
35
|
s.add_development_dependency 'rake-compiler', '~> 0.9'
|
32
|
-
s.add_development_dependency '
|
33
|
-
s.add_development_dependency '
|
34
|
-
s.add_development_dependency '
|
35
|
-
s.add_development_dependency 'rdoc', '~> 5.1'
|
36
|
+
s.add_development_dependency 'rdoc', '~> 6.2'
|
37
|
+
s.add_development_dependency 'rubocop'
|
38
|
+
s.add_development_dependency 'rubocop-standard'
|
36
39
|
end
|
data/ext/commonmarker/autolink.c
CHANGED
@@ -269,7 +269,11 @@ static cmark_node *match(cmark_syntax_extension *ext, cmark_parser *parser,
|
|
269
269
|
// inline was finished in inlines.c.
|
270
270
|
}
|
271
271
|
|
272
|
-
static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset) {
|
272
|
+
static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset, int depth) {
|
273
|
+
// postprocess_text can recurse very deeply if there is a very long line of
|
274
|
+
// '@' only. Stop at a reasonable depth to ensure it cannot crash.
|
275
|
+
if (depth > 1000) return;
|
276
|
+
|
273
277
|
size_t link_end;
|
274
278
|
uint8_t *data = text->as.literal.data,
|
275
279
|
*at;
|
@@ -307,7 +311,7 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset)
|
|
307
311
|
}
|
308
312
|
|
309
313
|
if (rewind == 0 || ns > 0) {
|
310
|
-
postprocess_text(parser, text, max_rewind + 1 + offset);
|
314
|
+
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
|
311
315
|
return;
|
312
316
|
}
|
313
317
|
|
@@ -327,14 +331,14 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset)
|
|
327
331
|
|
328
332
|
if (link_end < 2 || nb != 1 || np == 0 ||
|
329
333
|
(!cmark_isalpha(data[link_end - 1]) && data[link_end - 1] != '.')) {
|
330
|
-
postprocess_text(parser, text, max_rewind + 1 + offset);
|
334
|
+
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
|
331
335
|
return;
|
332
336
|
}
|
333
337
|
|
334
338
|
link_end = autolink_delim(data, link_end);
|
335
339
|
|
336
340
|
if (link_end == 0) {
|
337
|
-
postprocess_text(parser, text, max_rewind + 1 + offset);
|
341
|
+
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
|
338
342
|
return;
|
339
343
|
}
|
340
344
|
|
@@ -369,7 +373,7 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset)
|
|
369
373
|
text->as.literal.len = offset + max_rewind - rewind;
|
370
374
|
text->as.literal.data[text->as.literal.len] = 0;
|
371
375
|
|
372
|
-
postprocess_text(parser, post, 0);
|
376
|
+
postprocess_text(parser, post, 0, depth + 1);
|
373
377
|
}
|
374
378
|
|
375
379
|
static cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser, cmark_node *root) {
|
@@ -396,7 +400,7 @@ static cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser
|
|
396
400
|
}
|
397
401
|
|
398
402
|
if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_TEXT) {
|
399
|
-
postprocess_text(parser, node, 0);
|
403
|
+
postprocess_text(parser, node, 0, /*depth*/0);
|
400
404
|
}
|
401
405
|
}
|
402
406
|
|