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.

Files changed (74) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +94 -18
  3. data/Rakefile +24 -5
  4. data/bin/commonmarker +107 -47
  5. data/commonmarker.gemspec +18 -15
  6. data/ext/commonmarker/autolink.c +10 -6
  7. data/ext/commonmarker/blocks.c +102 -31
  8. data/ext/commonmarker/buffer.c +0 -1
  9. data/ext/commonmarker/chunk.h +0 -1
  10. data/ext/commonmarker/cmark-gfm-core-extensions.h +29 -0
  11. data/ext/commonmarker/cmark-gfm-extension_api.h +19 -2
  12. data/ext/commonmarker/cmark-gfm.h +19 -5
  13. data/ext/commonmarker/cmark-gfm_version.h +2 -2
  14. data/ext/commonmarker/commonmark.c +33 -12
  15. data/ext/commonmarker/commonmarker.c +209 -100
  16. data/ext/commonmarker/core-extensions.c +2 -0
  17. data/ext/commonmarker/ext_scanners.c +622 -684
  18. data/ext/commonmarker/ext_scanners.h +2 -0
  19. data/ext/commonmarker/extconf.rb +3 -1
  20. data/ext/commonmarker/footnotes.c +23 -0
  21. data/ext/commonmarker/footnotes.h +2 -0
  22. data/ext/commonmarker/houdini_href_e.c +1 -1
  23. data/ext/commonmarker/html.c +46 -25
  24. data/ext/commonmarker/inlines.c +127 -30
  25. data/ext/commonmarker/iterator.h +0 -1
  26. data/ext/commonmarker/map.h +0 -1
  27. data/ext/commonmarker/node.c +17 -3
  28. data/ext/commonmarker/node.h +9 -0
  29. data/ext/commonmarker/parser.h +2 -1
  30. data/ext/commonmarker/plaintext.c +22 -0
  31. data/ext/commonmarker/render.c +18 -15
  32. data/ext/commonmarker/render.h +0 -1
  33. data/ext/commonmarker/scanners.c +779 -953
  34. data/ext/commonmarker/scanners.h +0 -2
  35. data/ext/commonmarker/strikethrough.c +4 -1
  36. data/ext/commonmarker/syntax_extension.c +10 -0
  37. data/ext/commonmarker/syntax_extension.h +2 -0
  38. data/ext/commonmarker/table.c +178 -31
  39. data/ext/commonmarker/tasklist.c +156 -0
  40. data/ext/commonmarker/tasklist.h +8 -0
  41. data/ext/commonmarker/xml.c +9 -2
  42. data/lib/commonmarker/config.rb +41 -38
  43. data/lib/commonmarker/errors.rb +12 -0
  44. data/lib/commonmarker/node/inspect.rb +15 -17
  45. data/lib/commonmarker/node.rb +14 -2
  46. data/lib/commonmarker/renderer/html_renderer.rb +45 -36
  47. data/lib/commonmarker/renderer.rb +16 -10
  48. data/lib/commonmarker/version.rb +3 -1
  49. data/lib/commonmarker.rb +8 -7
  50. data/test/benchmark.rb +26 -21
  51. data/test/fixtures/strong.md +1 -0
  52. data/test/fixtures/table.md +10 -0
  53. data/test/test_attributes.rb +5 -3
  54. data/test/test_basics.rb +19 -0
  55. data/test/test_commands.rb +72 -0
  56. data/test/test_commonmark.rb +15 -13
  57. data/test/test_doc.rb +31 -29
  58. data/test/test_encoding.rb +9 -5
  59. data/test/test_extensions.rb +66 -73
  60. data/test/test_footnotes.rb +47 -12
  61. data/test/test_gc.rb +6 -2
  62. data/test/test_helper.rb +25 -15
  63. data/test/test_linebreaks.rb +2 -0
  64. data/test/test_maliciousness.rb +189 -190
  65. data/test/test_node.rb +12 -12
  66. data/test/test_options.rb +17 -15
  67. data/test/test_pathological_inputs.rb +14 -12
  68. data/test/test_plaintext.rb +23 -21
  69. data/test/test_renderer.rb +29 -10
  70. data/test/test_smartpunct.rb +7 -2
  71. data/test/test_spec.rb +7 -4
  72. data/test/test_tasklists.rb +43 -0
  73. data/test/test_xml.rb +107 -0
  74. metadata +74 -30
@@ -1,49 +1,52 @@
1
- require 'ruby-enum'
1
+ # frozen_string_literal: true
2
+
2
3
  module CommonMarker
3
4
  # For Ruby::Enum, these must be classes, not modules
4
5
  module Config
5
- class Parse
6
- include Ruby::Enum
7
-
8
- define :DEFAULT, 0
9
- define :VALIDATE_UTF8, (1 << 9)
10
- define :SMART, (1 << 10)
11
- define :LIBERAL_HTML_TAG, (1 << 12)
12
- define :FOOTNOTES, (1 << 13)
13
- define :STRIKETHROUGH_DOUBLE_TILDE, (1 << 14)
14
- end
15
-
16
- class Render
17
- include Ruby::Enum
18
-
19
- define :DEFAULT, 0
20
- define :SOURCEPOS, (1 << 1)
21
- define :HARDBREAKS, (1 << 2)
22
- define :SAFE, (1 << 3)
23
- define :NOBREAKS, (1 << 4)
24
- define :GITHUB_PRE_LANG, (1 << 11)
25
- define :TABLE_PREFER_STYLE_ATTRIBUTES, (1 << 15)
26
- define :FULL_INFO_STRING, (1 << 16)
27
- end
6
+ # See https://github.com/github/cmark-gfm/blob/master/src/cmark-gfm.h#L673
7
+ OPTS = {
8
+ parse: {
9
+ DEFAULT: 0,
10
+ SOURCEPOS: (1 << 1),
11
+ UNSAFE: (1 << 17),
12
+ VALIDATE_UTF8: (1 << 9),
13
+ SMART: (1 << 10),
14
+ LIBERAL_HTML_TAG: (1 << 12),
15
+ FOOTNOTES: (1 << 13),
16
+ STRIKETHROUGH_DOUBLE_TILDE: (1 << 14)
17
+ }.freeze,
18
+ render: {
19
+ DEFAULT: 0,
20
+ SOURCEPOS: (1 << 1),
21
+ HARDBREAKS: (1 << 2),
22
+ UNSAFE: (1 << 17),
23
+ NOBREAKS: (1 << 4),
24
+ VALIDATE_UTF8: (1 << 9),
25
+ SMART: (1 << 10),
26
+ GITHUB_PRE_LANG: (1 << 11),
27
+ LIBERAL_HTML_TAG: (1 << 12),
28
+ FOOTNOTES: (1 << 13),
29
+ STRIKETHROUGH_DOUBLE_TILDE: (1 << 14),
30
+ TABLE_PREFER_STYLE_ATTRIBUTES: (1 << 15),
31
+ FULL_INFO_STRING: (1 << 16)
32
+ }.freeze,
33
+ format: %i[html xml commonmark plaintext].freeze
34
+ }.freeze
28
35
 
29
36
  def self.process_options(option, type)
30
- type = Config.const_get(type.capitalize)
31
- if option.is_a?(Symbol)
32
- check_option(option, type)
33
- type.to_h[option]
34
- elsif option.is_a?(Array)
35
- option = [nil] if option.empty?
37
+ case option
38
+ when Symbol
39
+ OPTS.fetch(type).fetch(option)
40
+ when Array
41
+ raise TypeError if option.none?
42
+
36
43
  # neckbearding around. the map will both check the opts and then bitwise-OR it
37
- option.map { |o| check_option(o, type); type.to_h[o] }.inject(0, :|)
44
+ OPTS.fetch(type).fetch_values(*option).inject(0, :|)
38
45
  else
39
- raise TypeError, 'option type must be a valid symbol or array of symbols'
40
- end
41
- end
42
-
43
- def self.check_option(option, type)
44
- unless type.keys.include?(option)
45
- raise TypeError, "option ':#{option}' does not exist for #{type}"
46
+ raise TypeError, "option type must be a valid symbol or array of symbols within the #{name}::OPTS[:#{type}] context"
46
47
  end
48
+ rescue KeyError => e
49
+ raise TypeError, "option ':#{e.key}' does not exist for #{name}::OPTS[:#{type}]"
47
50
  end
48
51
  end
49
52
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'commonmarker/node/inspect'
4
+
5
+ module CommonMarker
6
+ class RenderError < StandardError
7
+ PREAMBLE = 'There was an error rendering'
8
+ def initialize(error)
9
+ super("#{PREAMBLE}: #{error.class} #{error.message}")
10
+ end
11
+ end
12
+ end
@@ -8,13 +8,13 @@ module CommonMarker
8
8
  PP_INDENT_SIZE = 2
9
9
 
10
10
  def inspect
11
- PP.pp(self, String.new, Float::INFINITY)
11
+ PP.pp(self, +'', Float::INFINITY)
12
12
  end
13
13
 
14
- # @param [PrettyPrint] pp
15
- def pretty_print(pp)
16
- pp.group(PP_INDENT_SIZE, "#<#{self.class}(#{type}):", '>') do
17
- pp.breakable
14
+ # @param printer [PrettyPrint] pp
15
+ def pretty_print(printer)
16
+ printer.group(PP_INDENT_SIZE, "#<#{self.class}(#{type}):", '>') do
17
+ printer.breakable
18
18
 
19
19
  attrs = %i[
20
20
  sourcepos
@@ -27,29 +27,27 @@ module CommonMarker
27
27
  list_tight
28
28
  fence_info
29
29
  ].map do |name|
30
- begin
31
- [name, __send__(name)]
32
- rescue NodeError
33
- nil
34
- end
30
+ [name, __send__(name)]
31
+ rescue NodeError
32
+ nil
35
33
  end.compact
36
34
 
37
- pp.seplist(attrs) do |name, value|
38
- pp.text "#{name}="
39
- pp.pp value
35
+ printer.seplist(attrs) do |name, value|
36
+ printer.text "#{name}="
37
+ printer.pp value
40
38
  end
41
39
 
42
40
  if first_child
43
- pp.breakable
44
- pp.group(PP_INDENT_SIZE) do
41
+ printer.breakable
42
+ printer.group(PP_INDENT_SIZE) do
45
43
  children = []
46
44
  node = first_child
47
45
  while node
48
46
  children << node
49
47
  node = node.next
50
48
  end
51
- pp.text 'children='
52
- pp.pp children
49
+ printer.text 'children='
50
+ printer.pp children
53
51
  end
54
52
  end
55
53
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'commonmarker/node/inspect'
2
4
 
3
5
  module CommonMarker
@@ -9,7 +11,7 @@ module CommonMarker
9
11
  #
10
12
  # blk - A {Proc} representing the action to take for each child
11
13
  def walk(&block)
12
- return enum_for(:walk) unless block_given?
14
+ return enum_for(:walk) unless block
13
15
 
14
16
  yield self
15
17
  each do |child|
@@ -28,6 +30,16 @@ module CommonMarker
28
30
  _render_html(opts, extensions).force_encoding('utf-8')
29
31
  end
30
32
 
33
+ # Public: Convert the node to an XML string.
34
+ #
35
+ # options - A {Symbol} or {Array of Symbol}s indicating the render options
36
+ #
37
+ # Returns a {String}.
38
+ def to_xml(options = :DEFAULT)
39
+ opts = Config.process_options(options, :render)
40
+ _render_xml(opts).force_encoding('utf-8')
41
+ end
42
+
31
43
  # Public: Convert the node to a CommonMark string.
32
44
  #
33
45
  # options - A {Symbol} or {Array of Symbol}s indicating the render options
@@ -51,7 +63,7 @@ module CommonMarker
51
63
  end
52
64
 
53
65
  # Public: Iterate over the children (if any) of the current pointer.
54
- def each(&block)
66
+ def each
55
67
  return enum_for(:each) unless block_given?
56
68
 
57
69
  child = first_child
@@ -1,14 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CommonMarker
2
4
  class HtmlRenderer < Renderer
3
- def render(node)
4
- super(node)
5
- end
6
-
7
5
  def document(_)
8
6
  super
9
- if @written_footnote_ix
10
- out("</ol>\n</section>\n")
11
- end
7
+ out("</ol>\n</section>\n") if @written_footnote_ix
12
8
  end
13
9
 
14
10
  def header(node)
@@ -26,7 +22,7 @@ module CommonMarker
26
22
  container("<p#{sourcepos(node)}>", '</p>') do
27
23
  out(:children)
28
24
  if node.parent.type == :footnote_definition && node.next.nil?
29
- out(" ")
25
+ out(' ')
30
26
  out_footnote_backref
31
27
  end
32
28
  end
@@ -60,12 +56,24 @@ module CommonMarker
60
56
 
61
57
  def list_item(node)
62
58
  block do
63
- container("<li#{sourcepos(node)}>", '</li>') do
59
+ tasklist_data = tasklist(node)
60
+ container("<li#{sourcepos(node)}#{tasklist_data}>#{' ' if tasklist?(node)}", '</li>') do
64
61
  out(:children)
65
62
  end
66
63
  end
67
64
  end
68
65
 
66
+ def tasklist(node)
67
+ return '' unless tasklist?(node)
68
+
69
+ state = if checked?(node)
70
+ 'checked="" disabled=""'
71
+ else
72
+ 'disabled=""'
73
+ end
74
+ "><input type=\"checkbox\" #{state} /"
75
+ end
76
+
69
77
  def blockquote(node)
70
78
  block do
71
79
  container("<blockquote#{sourcepos(node)}>\n", '</blockquote>') do
@@ -84,9 +92,7 @@ module CommonMarker
84
92
  block do
85
93
  if option_enabled?(:GITHUB_PRE_LANG)
86
94
  out("<pre#{sourcepos(node)}")
87
- if node.fence_info && !node.fence_info.empty?
88
- out(' lang="', node.fence_info.split(/\s+/)[0], '"')
89
- end
95
+ out(' lang="', node.fence_info.split(/\s+/)[0], '"') if node.fence_info && !node.fence_info.empty?
90
96
  out('><code>')
91
97
  else
92
98
  out("<pre#{sourcepos(node)}><code")
@@ -103,19 +109,19 @@ module CommonMarker
103
109
 
104
110
  def html(node)
105
111
  block do
106
- if option_enabled?(:SAFE)
107
- out('<!-- raw HTML omitted -->')
108
- else
112
+ if option_enabled?(:UNSAFE)
109
113
  out(tagfilter(node.string_content))
114
+ else
115
+ out('<!-- raw HTML omitted -->')
110
116
  end
111
117
  end
112
118
  end
113
119
 
114
120
  def inline_html(node)
115
- if option_enabled?(:SAFE)
116
- out('<!-- raw HTML omitted -->')
117
- else
121
+ if option_enabled?(:UNSAFE)
118
122
  out(tagfilter(node.string_content))
123
+ else
124
+ out('<!-- raw HTML omitted -->')
119
125
  end
120
126
  end
121
127
 
@@ -129,9 +135,7 @@ module CommonMarker
129
135
 
130
136
  def link(node)
131
137
  out('<a href="', node.url.nil? ? '' : escape_href(node.url), '"')
132
- if node.title && !node.title.empty?
133
- out(' title="', escape_html(node.title), '"')
134
- end
138
+ out(' title="', escape_html(node.title), '"') if node.title && !node.title.empty?
135
139
  out('>', :children, '</a>')
136
140
  end
137
141
 
@@ -140,9 +144,7 @@ module CommonMarker
140
144
  plain do
141
145
  out(' alt="', :children, '"')
142
146
  end
143
- if node.title && !node.title.empty?
144
- out(' title="', escape_html(node.title), '"')
145
- end
147
+ out(' title="', escape_html(node.title), '"') if node.title && !node.title.empty?
146
148
  out(' />')
147
149
  end
148
150
 
@@ -156,7 +158,7 @@ module CommonMarker
156
158
  out('</code>')
157
159
  end
158
160
 
159
- def linebreak(node)
161
+ def linebreak(_node)
160
162
  out("<br />\n")
161
163
  end
162
164
 
@@ -197,9 +199,9 @@ module CommonMarker
197
199
 
198
200
  def table_cell(node)
199
201
  align = case @alignments[@column_index]
200
- when :left; ' align="left"'
201
- when :right; ' align="right"'
202
- when :center; ' align="center"'
202
+ when :left then ' align="left"'
203
+ when :right then ' align="right"'
204
+ when :center then ' align="center"'
203
205
  else; ''
204
206
  end
205
207
  out(@in_header ? "<th#{align}#{sourcepos(node)}>" : "<td#{align}#{sourcepos(node)}>", :children, @in_header ? "</th>\n" : "</td>\n")
@@ -215,29 +217,36 @@ module CommonMarker
215
217
  end
216
218
 
217
219
  def footnote_definition(_)
218
- if !@footnote_ix
220
+ unless @footnote_ix
219
221
  out("<section class=\"footnotes\">\n<ol>\n")
220
222
  @footnote_ix = 0
221
223
  end
222
224
 
223
225
  @footnote_ix += 1
224
- out("<li id=\"fn#@footnote_ix\">\n", :children)
225
- if out_footnote_backref
226
- out("\n")
227
- end
226
+ out("<li id=\"fn#{@footnote_ix}\">\n", :children)
227
+ out("\n") if out_footnote_backref
228
228
  out("</li>\n")
229
- #</ol>
230
- #</section>
229
+ # </ol>
230
+ # </section>
231
231
  end
232
232
 
233
233
  private
234
234
 
235
235
  def out_footnote_backref
236
236
  return false if @written_footnote_ix == @footnote_ix
237
+
237
238
  @written_footnote_ix = @footnote_ix
238
239
 
239
- out("<a href=\"#fnref#@footnote_ix\" class=\"footnote-backref\">↩</a>")
240
+ out("<a href=\"#fnref#{@footnote_ix}\" class=\"footnote-backref\">↩</a>")
240
241
  true
241
242
  end
243
+
244
+ def tasklist?(node)
245
+ node.type_string == 'tasklist'
246
+ end
247
+
248
+ def checked?(node)
249
+ node.tasklist_item_checked?
250
+ end
242
251
  end
243
252
  end
@@ -1,12 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'set'
2
4
  require 'stringio'
3
5
 
4
6
  module CommonMarker
5
7
  class Renderer
6
8
  attr_accessor :in_tight, :warnings, :in_plain
9
+
7
10
  def initialize(options: :DEFAULT, extensions: [])
8
11
  @opts = Config.process_options(options, :render)
9
- @stream = StringIO.new("".force_encoding("utf-8"))
12
+ @stream = StringIO.new(+'')
10
13
  @need_blocksep = false
11
14
  @warnings = Set.new []
12
15
  @in_tight = false
@@ -16,11 +19,12 @@ module CommonMarker
16
19
 
17
20
  def out(*args)
18
21
  args.each do |arg|
19
- if arg == :children
22
+ case arg
23
+ when :children
20
24
  @node.each { |child| out(child) }
21
- elsif arg.is_a?(Array)
25
+ when Array
22
26
  arg.each { |x| render(x) }
23
- elsif arg.is_a?(Node)
27
+ when Node
24
28
  render(arg)
25
29
  else
26
30
  @stream.write(arg)
@@ -32,7 +36,7 @@ module CommonMarker
32
36
  @node = node
33
37
  if node.type == :document
34
38
  document(node)
35
- return @stream.string
39
+ @stream.string
36
40
  elsif @in_plain && node.type != :text && node.type != :softbreak
37
41
  node.each { |child| render(child) }
38
42
  else
@@ -53,11 +57,11 @@ module CommonMarker
53
57
  code_block(node)
54
58
  end
55
59
 
56
- def reference_def(_node)
57
- end
60
+ def reference_def(_node); end
58
61
 
59
62
  def cr
60
63
  return if @stream.string.empty? || @stream.string[-1] == "\n"
64
+
61
65
  out("\n")
62
66
  end
63
67
 
@@ -109,21 +113,23 @@ module CommonMarker
109
113
  )
110
114
  (?=\s|>|/>)
111
115
  }xi,
112
- '&lt;\1')
116
+ '&lt;\1'
117
+ )
113
118
  else
114
119
  str
115
120
  end
116
121
  end
117
122
 
118
123
  def sourcepos(node)
119
- return "" unless option_enabled?(:SOURCEPOS)
124
+ return '' unless option_enabled?(:SOURCEPOS)
125
+
120
126
  s = node.sourcepos
121
127
  " data-sourcepos=\"#{s[:start_line]}:#{s[:start_column]}-" \
122
128
  "#{s[:end_line]}:#{s[:end_column]}\""
123
129
  end
124
130
 
125
131
  def option_enabled?(opt)
126
- (@opts & CommonMarker::Config::Render.value(opt)) != 0
132
+ (@opts & CommonMarker::Config::OPTS.dig(:render, opt)) != 0
127
133
  end
128
134
  end
129
135
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CommonMarker
2
- VERSION = '0.17.13'.freeze
4
+ VERSION = '0.23.4'
3
5
  end
data/lib/commonmarker.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  require 'commonmarker/commonmarker'
3
5
  require 'commonmarker/config'
4
6
  require 'commonmarker/node'
@@ -8,8 +10,7 @@ require 'commonmarker/version'
8
10
 
9
11
  begin
10
12
  require 'awesome_print'
11
- rescue LoadError; end
12
-
13
+ rescue LoadError; end # rubocop:disable Lint/SuppressedException
13
14
  module CommonMarker
14
15
  # Public: Parses a Markdown string into an HTML string.
15
16
  #
@@ -19,11 +20,10 @@ module CommonMarker
19
20
  #
20
21
  # Returns a {String} of converted HTML.
21
22
  def self.render_html(text, options = :DEFAULT, extensions = [])
22
- fail TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
23
+ raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
24
+
23
25
  opts = Config.process_options(options, :render)
24
- text = text.encode('UTF-8')
25
- html = Node.markdown_to_html(text, opts, extensions)
26
- html.force_encoding('UTF-8')
26
+ Node.markdown_to_html(text.encode('UTF-8'), opts, extensions)
27
27
  end
28
28
 
29
29
  # Public: Parses a Markdown string into a `document` node.
@@ -34,7 +34,8 @@ module CommonMarker
34
34
  #
35
35
  # Returns the `document` node.
36
36
  def self.render_doc(text, options = :DEFAULT, extensions = [])
37
- fail TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
37
+ raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
38
+
38
39
  opts = Config.process_options(options, :parse)
39
40
  text = text.encode('UTF-8')
40
41
  Node.parse_document(text, text.bytesize, opts, extensions)
data/test/benchmark.rb CHANGED
@@ -1,34 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'benchmark/ips'
1
4
  require 'commonmarker'
2
- require 'github/markdown'
3
5
  require 'redcarpet'
4
6
  require 'kramdown'
5
7
  require 'benchmark'
6
8
 
7
- def dobench(name, &blk)
8
- puts name
9
- puts Benchmark.measure(&blk)
10
- end
9
+ benchinput = File.read('test/benchinput.md').freeze
11
10
 
12
- benchinput = File.open('test/benchinput.md', 'r').read()
11
+ printf("input size = %<bytes>d bytes\n\n", { bytes: benchinput.bytesize })
13
12
 
14
- printf("input size = %d bytes\n\n", benchinput.bytesize)
13
+ Benchmark.ips do |x|
14
+ x.report('redcarpet') do
15
+ Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: false, tables: false).render(benchinput)
16
+ end
15
17
 
16
- dobench('redcarpet') do
17
- Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: false, tables: false).render(benchinput)
18
- end
18
+ x.report('commonmarker with to_html') do
19
+ CommonMarker.render_html(benchinput)
20
+ end
19
21
 
20
- dobench('github-markdown') do
21
- GitHub::Markdown.render(benchinput)
22
- end
22
+ x.report('commonmarker with to_xml') do
23
+ CommonMarker.render_html(benchinput)
24
+ end
23
25
 
24
- dobench('commonmarker with to_html') do
25
- CommonMarker.render_html(benchinput)
26
- end
26
+ x.report('commonmarker with ruby HtmlRenderer') do
27
+ CommonMarker::HtmlRenderer.new.render(CommonMarker.render_doc(benchinput))
28
+ end
27
29
 
28
- dobench('commonmarker with ruby HtmlRenderer') do
29
- CommonMarker::HtmlRenderer.new.render(CommonMarker.render_doc(benchinput))
30
- end
30
+ x.report('commonmarker with render_doc.to_html') do
31
+ CommonMarker.render_doc(benchinput, :DEFAULT, [:autolink]).to_html(:DEFAULT, [:autolink])
32
+ end
33
+
34
+ x.report('kramdown') do
35
+ Kramdown::Document.new(benchinput).to_html(benchinput)
36
+ end
31
37
 
32
- dobench('kramdown') do
33
- Kramdown::Document.new(benchinput).to_html(benchinput)
38
+ x.compare!
34
39
  end
@@ -0,0 +1 @@
1
+ I am **strong**
@@ -0,0 +1,10 @@
1
+ One extension:
2
+
3
+ | a | b |
4
+ | --- | --- |
5
+ | c | d |
6
+ | **x** | |
7
+
8
+ Another extension:
9
+
10
+ ~~hi~~
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class TestAttributes < Minitest::Test
4
6
  def setup
5
- contents = File.read(File.join(FIXTURES_DIR, 'dingus.md'))
7
+ contents = fixtures_file('dingus.md')
6
8
  @doc = CommonMarker.render_doc(contents.strip)
7
9
  end
8
10
 
@@ -13,9 +15,9 @@ class TestAttributes < Minitest::Test
13
15
  sourcepos << node.sourcepos
14
16
  end
15
17
 
16
- sourcepos.delete_if { |h| h.values.all? { |v| v == 0 } }
18
+ sourcepos.delete_if { |h| h.values.all?(&:zero?) }
17
19
 
18
- result = [{:start_line=>1, :start_column=>1, :end_line=>10, :end_column=>12}, {:start_line=>1, :start_column=>1, :end_line=>1, :end_column=>17}, {:start_line=>1, :start_column=>4, :end_line=>1, :end_column=>17}, {:start_line=>3, :start_column=>1, :end_line=>5, :end_column=>36}, {:start_line=>3, :start_column=>1, :end_line=>3, :end_column=>55}, {:start_line=>4, :start_column=>1, :end_line=>4, :end_column=>53}, {:start_line=>4, :start_column=>2, :end_line=>4, :end_column=>14}, {:start_line=>4, :start_column=>54, :end_line=>4, :end_column=>58}, {:start_line=>5, :start_column=>1, :end_line=>5, :end_column=>36}, {:start_line=>7, :start_column=>1, :end_line=>10, :end_column=>12}, {:start_line=>7, :start_column=>1, :end_line=>7, :end_column=>11}, {:start_line=>7, :start_column=>4, :end_line=>7, :end_column=>11}, {:start_line=>7, :start_column=>4, :end_line=>7, :end_column=>11}, {:start_line=>8, :start_column=>1, :end_line=>10, :end_column=>12}, {:start_line=>8, :start_column=>4, :end_line=>8, :end_column=>11}, {:start_line=>8, :start_column=>4, :end_line=>8, :end_column=>11}, {:start_line=>9, :start_column=>4, :end_line=>10, :end_column=>12}, {:start_line=>9, :start_column=>4, :end_line=>9, :end_column=>12}, {:start_line=>9, :start_column=>6, :end_line=>9, :end_column=>12}, {:start_line=>9, :start_column=>6, :end_line=>9, :end_column=>12}, {:start_line=>10, :start_column=>4, :end_line=>10, :end_column=>12}, {:start_line=>10, :start_column=>6, :end_line=>10, :end_column=>12}, {:start_line=>10, :start_column=>6, :end_line=>10, :end_column=>12}]
20
+ result = [{ start_line: 1, start_column: 1, end_line: 10, end_column: 12 }, { start_line: 1, start_column: 1, end_line: 1, end_column: 17 }, { start_line: 1, start_column: 4, end_line: 1, end_column: 17 }, { start_line: 3, start_column: 1, end_line: 5, end_column: 36 }, { start_line: 3, start_column: 1, end_line: 3, end_column: 55 }, { start_line: 4, start_column: 1, end_line: 4, end_column: 53 }, { start_line: 4, start_column: 2, end_line: 4, end_column: 14 }, { start_line: 4, start_column: 54, end_line: 4, end_column: 58 }, { start_line: 5, start_column: 1, end_line: 5, end_column: 36 }, { start_line: 7, start_column: 1, end_line: 10, end_column: 12 }, { start_line: 7, start_column: 1, end_line: 7, end_column: 11 }, { start_line: 7, start_column: 4, end_line: 7, end_column: 11 }, { start_line: 7, start_column: 4, end_line: 7, end_column: 11 }, { start_line: 8, start_column: 1, end_line: 10, end_column: 12 }, { start_line: 8, start_column: 4, end_line: 8, end_column: 11 }, { start_line: 8, start_column: 4, end_line: 8, end_column: 11 }, { start_line: 9, start_column: 4, end_line: 10, end_column: 12 }, { start_line: 9, start_column: 4, end_line: 9, end_column: 12 }, { start_line: 9, start_column: 6, end_line: 9, end_column: 12 }, { start_line: 9, start_column: 6, end_line: 9, end_column: 12 }, { start_line: 10, start_column: 4, end_line: 10, end_column: 12 }, { start_line: 10, start_column: 6, end_line: 10, end_column: 12 }, { start_line: 10, start_column: 6, end_line: 10, end_column: 12 }]
19
21
 
20
22
  assert_equal result, sourcepos
21
23
  end
data/test/test_basics.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class TestBasics < Minitest::Test
@@ -13,4 +15,21 @@ class TestBasics < Minitest::Test
13
15
  html = CommonMarker.render_html('Hi *there*')
14
16
  assert_equal "<p>Hi <em>there</em></p>\n", html
15
17
  end
18
+
19
+ # basic test that just checks if every option is accepted & no errors are thrown
20
+ def test_accept_every_option
21
+ text = "Hello **world** -- how are _you_ today? I'm ~~fine~~, ~yourself~?"
22
+ parse_opt = %i[SOURCEPOS UNSAFE VALIDATE_UTF8 SMART LIBERAL_HTML_TAG FOOTNOTES STRIKETHROUGH_DOUBLE_TILDE]
23
+ render_opt = parse_opt + %i[HARDBREAKS NOBREAKS GITHUB_PRE_LANG TABLE_PREFER_STYLE_ATTRIBUTES FULL_INFO_STRING]
24
+
25
+ extensions = %i[table tasklist strikethrough autolink tagfilter]
26
+
27
+ assert_equal "<p>Hello <strong>world</strong> – how are <em>you</em> today? I’m <del>fine</del>, ~yourself~?</p>\n", CommonMarker.render_doc(text, parse_opt, extensions).to_html
28
+
29
+ # NOTE: how tho the doc returned has sourcepos info, by default the renderer
30
+ # won't emit it. for that we need to pass in the render opt
31
+ assert_equal "<p data-sourcepos=\"1:1-1:65\">Hello <strong>world</strong> – how are <em>you</em> today? I’m <del>fine</del>, ~yourself~?</p>\n", CommonMarker.render_doc(text, parse_opt, extensions).to_html(render_opt, extensions)
32
+
33
+ assert_equal "<p data-sourcepos=\"1:1-1:65\">Hello <strong>world</strong> – how are <em>you</em> today? I’m <del>fine</del>, ~yourself~?</p>\n", CommonMarker.render_html(text, parse_opt, extensions)
34
+ end
16
35
  end