commonmarker 0.23.1 → 0.23.5

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +56 -55
  3. data/bin/commonmarker +2 -7
  4. data/commonmarker.gemspec +27 -26
  5. data/ext/commonmarker/blocks.c +13 -2
  6. data/ext/commonmarker/cmark-gfm_version.h +2 -2
  7. data/ext/commonmarker/commonmark.c +14 -4
  8. data/ext/commonmarker/commonmarker.c +30 -44
  9. data/ext/commonmarker/ext_scanners.c +360 -640
  10. data/ext/commonmarker/footnotes.c +23 -0
  11. data/ext/commonmarker/footnotes.h +2 -0
  12. data/ext/commonmarker/html.c +40 -19
  13. data/ext/commonmarker/inlines.c +69 -11
  14. data/ext/commonmarker/node.h +7 -0
  15. data/ext/commonmarker/scanners.c +2438 -2450
  16. data/ext/commonmarker/table.c +98 -53
  17. data/lib/commonmarker/config.rb +1 -1
  18. data/lib/commonmarker/node/inspect.rb +8 -18
  19. data/lib/commonmarker/node.rb +6 -6
  20. data/lib/commonmarker/renderer/html_renderer.rb +37 -37
  21. data/lib/commonmarker/renderer.rb +5 -5
  22. data/lib/commonmarker/version.rb +1 -1
  23. data/lib/commonmarker.rb +9 -11
  24. metadata +6 -57
  25. data/test/benchmark.rb +0 -32
  26. data/test/fixtures/curly.md +0 -1
  27. data/test/fixtures/dingus.md +0 -10
  28. data/test/fixtures/strong.md +0 -1
  29. data/test/fixtures/table.md +0 -10
  30. data/test/test_attributes.rb +0 -24
  31. data/test/test_basics.rb +0 -35
  32. data/test/test_commands.rb +0 -72
  33. data/test/test_commonmark.rb +0 -36
  34. data/test/test_doc.rb +0 -130
  35. data/test/test_encoding.rb +0 -23
  36. data/test/test_extensions.rb +0 -116
  37. data/test/test_footnotes.rb +0 -48
  38. data/test/test_gc.rb +0 -47
  39. data/test/test_helper.rb +0 -71
  40. data/test/test_linebreaks.rb +0 -15
  41. data/test/test_maliciousness.rb +0 -262
  42. data/test/test_node.rb +0 -89
  43. data/test/test_options.rb +0 -37
  44. data/test/test_pathological_inputs.rb +0 -94
  45. data/test/test_plaintext.rb +0 -46
  46. data/test/test_renderer.rb +0 -47
  47. data/test/test_smartpunct.rb +0 -27
  48. data/test/test_spec.rb +0 -30
  49. data/test/test_tasklists.rb +0 -43
  50. data/test/test_xml.rb +0 -107
@@ -114,60 +114,94 @@ static cmark_strbuf *unescape_pipes(cmark_mem *mem, unsigned char *string, bufsi
114
114
  static table_row *row_from_string(cmark_syntax_extension *self,
115
115
  cmark_parser *parser, unsigned char *string,
116
116
  int len) {
117
+ // Parses a single table row. It has the following form:
118
+ // `delim? table_cell (delim table_cell)* delim? newline`
119
+ // Note that cells are allowed to be empty.
120
+ //
121
+ // From the GitHub-flavored Markdown specification:
122
+ //
123
+ // > Each row consists of cells containing arbitrary text, in which inlines
124
+ // > are parsed, separated by pipes (|). A leading and trailing pipe is also
125
+ // > recommended for clarity of reading, and if there’s otherwise parsing
126
+ // > ambiguity.
127
+
117
128
  table_row *row = NULL;
118
129
  bufsize_t cell_matched = 1, pipe_matched = 1, offset;
119
- int cell_end_offset;
130
+ int expect_more_cells = 1;
131
+ int row_end_offset = 0;
132
+ int int_overflow_abort = 0;
120
133
 
121
134
  row = (table_row *)parser->mem->calloc(1, sizeof(table_row));
122
135
  row->n_columns = 0;
123
136
  row->cells = NULL;
124
137
 
138
+ // Scan past the (optional) leading pipe.
125
139
  offset = scan_table_cell_end(string, len, 0);
126
140
 
127
141
  // Parse the cells of the row. Stop if we reach the end of the input, or if we
128
142
  // cannot detect any more cells.
129
- while (offset < len && (cell_matched || pipe_matched)) {
143
+ while (offset < len && expect_more_cells) {
130
144
  cell_matched = scan_table_cell(string, len, offset);
131
145
  pipe_matched = scan_table_cell_end(string, len, offset + cell_matched);
132
146
 
133
147
  if (cell_matched || pipe_matched) {
134
- cell_end_offset = offset + cell_matched - 1;
148
+ // We are guaranteed to have a cell, since (1) either we found some
149
+ // content and cell_matched, or (2) we found an empty cell followed by a
150
+ // pipe.
151
+ cmark_strbuf *cell_buf = unescape_pipes(parser->mem, string + offset,
152
+ cell_matched);
153
+ cmark_strbuf_trim(cell_buf);
154
+
155
+ node_cell *cell = (node_cell *)parser->mem->calloc(1, sizeof(*cell));
156
+ cell->buf = cell_buf;
157
+ cell->start_offset = offset;
158
+ cell->end_offset = offset + cell_matched - 1;
159
+
160
+ while (cell->start_offset > 0 && string[cell->start_offset - 1] != '|') {
161
+ --cell->start_offset;
162
+ ++cell->internal_offset;
163
+ }
164
+
165
+ // make sure we never wrap row->n_columns
166
+ // offset will != len and our exit will clean up as intended
167
+ if (row->n_columns == UINT16_MAX) {
168
+ int_overflow_abort = 1;
169
+ break;
170
+ }
171
+ row->n_columns += 1;
172
+ row->cells = cmark_llist_append(parser->mem, row->cells, cell);
173
+ }
135
174
 
136
- if (string[cell_end_offset] == '\n' || string[cell_end_offset] == '\r') {
137
- row->paragraph_offset = cell_end_offset;
175
+ offset += cell_matched + pipe_matched;
176
+
177
+ if (pipe_matched) {
178
+ expect_more_cells = 1;
179
+ } else {
180
+ // We've scanned the last cell. Check if we have reached the end of the row
181
+ row_end_offset = scan_table_row_end(string, len, offset);
182
+ offset += row_end_offset;
183
+
184
+ // If the end of the row is not the end of the input,
185
+ // the row is not a real row but potentially part of the paragraph
186
+ // preceding the table.
187
+ if (row_end_offset && offset != len) {
188
+ row->paragraph_offset = offset;
138
189
 
139
190
  cmark_llist_free_full(parser->mem, row->cells, (cmark_free_func)free_table_cell);
140
191
  row->cells = NULL;
141
192
  row->n_columns = 0;
142
- } else {
143
- cmark_strbuf *cell_buf = unescape_pipes(parser->mem, string + offset,
144
- cell_matched);
145
- cmark_strbuf_trim(cell_buf);
146
-
147
- node_cell *cell = (node_cell *)parser->mem->calloc(1, sizeof(*cell));
148
- cell->buf = cell_buf;
149
- cell->start_offset = offset;
150
- cell->end_offset = cell_end_offset;
151
-
152
- while (cell->start_offset > 0 && string[cell->start_offset - 1] != '|') {
153
- --cell->start_offset;
154
- ++cell->internal_offset;
155
- }
156
193
 
157
- row->n_columns += 1;
158
- row->cells = cmark_llist_append(parser->mem, row->cells, cell);
159
- }
160
- }
161
-
162
- offset += cell_matched + pipe_matched;
194
+ // Scan past the (optional) leading pipe.
195
+ offset += scan_table_cell_end(string, len, offset);
163
196
 
164
- if (!pipe_matched) {
165
- pipe_matched = scan_table_row_end(string, len, offset);
166
- offset += pipe_matched;
197
+ expect_more_cells = 1;
198
+ } else {
199
+ expect_more_cells = 0;
200
+ }
167
201
  }
168
202
  }
169
203
 
170
- if (offset != len || !row->n_columns) {
204
+ if (offset != len || row->n_columns == 0 || int_overflow_abort) {
171
205
  free_table_row(parser->mem, row);
172
206
  row = NULL;
173
207
  }
@@ -199,8 +233,6 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
199
233
  cmark_parser *parser,
200
234
  cmark_node *parent_container,
201
235
  unsigned char *input, int len) {
202
- bufsize_t matched =
203
- scan_table_start(input, len, cmark_parser_get_first_nonspace(parser));
204
236
  cmark_node *table_header;
205
237
  table_row *header_row = NULL;
206
238
  table_row *marker_row = NULL;
@@ -208,41 +240,48 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
208
240
  const char *parent_string;
209
241
  uint16_t i;
210
242
 
211
- if (!matched)
212
- return parent_container;
213
-
214
- parent_string = cmark_node_get_string_content(parent_container);
215
-
216
- cmark_arena_push();
217
-
218
- header_row = row_from_string(self, parser, (unsigned char *)parent_string,
219
- (int)strlen(parent_string));
220
-
221
- if (!header_row) {
222
- free_table_row(parser->mem, header_row);
223
- cmark_arena_pop();
243
+ if (!scan_table_start(input, len, cmark_parser_get_first_nonspace(parser))) {
224
244
  return parent_container;
225
245
  }
226
246
 
247
+ // Since scan_table_start was successful, we must have a marker row.
227
248
  marker_row = row_from_string(self, parser,
228
249
  input + cmark_parser_get_first_nonspace(parser),
229
250
  len - cmark_parser_get_first_nonspace(parser));
230
-
251
+ // assert may be optimized out, don't rely on it for security boundaries
252
+ if (!marker_row) {
253
+ return parent_container;
254
+ }
255
+
231
256
  assert(marker_row);
232
257
 
233
- if (header_row->n_columns != marker_row->n_columns) {
234
- free_table_row(parser->mem, header_row);
258
+ cmark_arena_push();
259
+
260
+ // Check for a matching header row. We call `row_from_string` with the entire
261
+ // (potentially long) parent container as input, but this should be safe since
262
+ // `row_from_string` bails out early if it does not find a row.
263
+ parent_string = cmark_node_get_string_content(parent_container);
264
+ header_row = row_from_string(self, parser, (unsigned char *)parent_string,
265
+ (int)strlen(parent_string));
266
+ if (!header_row || header_row->n_columns != marker_row->n_columns) {
235
267
  free_table_row(parser->mem, marker_row);
268
+ free_table_row(parser->mem, header_row);
236
269
  cmark_arena_pop();
237
270
  return parent_container;
238
271
  }
239
272
 
240
273
  if (cmark_arena_pop()) {
274
+ marker_row = row_from_string(
275
+ self, parser, input + cmark_parser_get_first_nonspace(parser),
276
+ len - cmark_parser_get_first_nonspace(parser));
241
277
  header_row = row_from_string(self, parser, (unsigned char *)parent_string,
242
278
  (int)strlen(parent_string));
243
- marker_row = row_from_string(self, parser,
244
- input + cmark_parser_get_first_nonspace(parser),
245
- len - cmark_parser_get_first_nonspace(parser));
279
+ // row_from_string can return NULL, add additional check to ensure n_columns match
280
+ if (!marker_row || !header_row || header_row->n_columns != marker_row->n_columns) {
281
+ free_table_row(parser->mem, marker_row);
282
+ free_table_row(parser->mem, header_row);
283
+ return parent_container;
284
+ }
246
285
  }
247
286
 
248
287
  if (!cmark_node_set_type(parent_container, CMARK_NODE_TABLE)) {
@@ -257,13 +296,13 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
257
296
  }
258
297
 
259
298
  cmark_node_set_syntax_extension(parent_container, self);
260
-
261
299
  parent_container->as.opaque = parser->mem->calloc(1, sizeof(node_table));
262
-
263
300
  set_n_table_columns(parent_container, header_row->n_columns);
264
301
 
302
+ // allocate alignments based on marker_row->n_columns
303
+ // since we populate the alignments array based on marker_row->cells
265
304
  uint8_t *alignments =
266
- (uint8_t *)parser->mem->calloc(header_row->n_columns, sizeof(uint8_t));
305
+ (uint8_t *)parser->mem->calloc(marker_row->n_columns, sizeof(uint8_t));
267
306
  cmark_llist *it = marker_row->cells;
268
307
  for (i = 0; it; it = it->next, ++i) {
269
308
  node_cell *node = (node_cell *)it->data;
@@ -332,6 +371,12 @@ static cmark_node *try_opening_table_row(cmark_syntax_extension *self,
332
371
  row = row_from_string(self, parser, input + cmark_parser_get_first_nonspace(parser),
333
372
  len - cmark_parser_get_first_nonspace(parser));
334
373
 
374
+ if (!row) {
375
+ // clean up the dangling node
376
+ cmark_node_free(table_row_block);
377
+ return NULL;
378
+ }
379
+
335
380
  {
336
381
  cmark_llist *tmp;
337
382
  int i, table_columns = get_n_table_columns(parent_container);
@@ -30,7 +30,7 @@ module CommonMarker
30
30
  TABLE_PREFER_STYLE_ATTRIBUTES: (1 << 15),
31
31
  FULL_INFO_STRING: (1 << 16),
32
32
  }.freeze,
33
- format: %i[html xml commonmark plaintext].freeze
33
+ format: [:html, :xml, :commonmark, :plaintext].freeze,
34
34
  }.freeze
35
35
 
36
36
  def self.process_options(option, type)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pp'
3
+ require "pp"
4
4
 
5
5
  module CommonMarker
6
6
  class Node
@@ -8,33 +8,23 @@ module CommonMarker
8
8
  PP_INDENT_SIZE = 2
9
9
 
10
10
  def inspect
11
- PP.pp(self, +'', Float::INFINITY)
11
+ PP.pp(self, +"", Float::INFINITY)
12
12
  end
13
13
 
14
14
  # @param printer [PrettyPrint] pp
15
15
  def pretty_print(printer)
16
- printer.group(PP_INDENT_SIZE, "#<#{self.class}(#{type}):", '>') do
16
+ printer.group(PP_INDENT_SIZE, "#<#{self.class}(#{type}):", ">") do
17
17
  printer.breakable
18
18
 
19
- attrs = %i[
20
- sourcepos
21
- string_content
22
- url
23
- title
24
- header_level
25
- list_type
26
- list_start
27
- list_tight
28
- fence_info
29
- ].map do |name|
19
+ attrs = [:sourcepos, :string_content, :url, :title, :header_level, :list_type, :list_start, :list_tight, :fence_info].map do |name|
30
20
  [name, __send__(name)]
31
21
  rescue NodeError
32
22
  nil
33
23
  end.compact
34
24
 
35
25
  printer.seplist(attrs) do |name, value|
36
- printer.text "#{name}="
37
- printer.pp value
26
+ printer.text("#{name}=")
27
+ printer.pp(value)
38
28
  end
39
29
 
40
30
  if first_child
@@ -46,8 +36,8 @@ module CommonMarker
46
36
  children << node
47
37
  node = node.next
48
38
  end
49
- printer.text 'children='
50
- printer.pp children
39
+ printer.text("children=")
40
+ printer.pp(children)
51
41
  end
52
42
  end
53
43
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'commonmarker/node/inspect'
3
+ require "commonmarker/node/inspect"
4
4
 
5
5
  module CommonMarker
6
6
  class Node
@@ -27,7 +27,7 @@ module CommonMarker
27
27
  # Returns a {String}.
28
28
  def to_html(options = :DEFAULT, extensions = [])
29
29
  opts = Config.process_options(options, :render)
30
- _render_html(opts, extensions).force_encoding('utf-8')
30
+ _render_html(opts, extensions).force_encoding("utf-8")
31
31
  end
32
32
 
33
33
  # Public: Convert the node to an XML string.
@@ -37,7 +37,7 @@ module CommonMarker
37
37
  # Returns a {String}.
38
38
  def to_xml(options = :DEFAULT)
39
39
  opts = Config.process_options(options, :render)
40
- _render_xml(opts).force_encoding('utf-8')
40
+ _render_xml(opts).force_encoding("utf-8")
41
41
  end
42
42
 
43
43
  # Public: Convert the node to a CommonMark string.
@@ -48,7 +48,7 @@ module CommonMarker
48
48
  # Returns a {String}.
49
49
  def to_commonmark(options = :DEFAULT, width = 120)
50
50
  opts = Config.process_options(options, :render)
51
- _render_commonmark(opts, width).force_encoding('utf-8')
51
+ _render_commonmark(opts, width).force_encoding("utf-8")
52
52
  end
53
53
 
54
54
  # Public: Convert the node to a plain text string.
@@ -59,7 +59,7 @@ module CommonMarker
59
59
  # Returns a {String}.
60
60
  def to_plaintext(options = :DEFAULT, width = 120)
61
61
  opts = Config.process_options(options, :render)
62
- _render_plaintext(opts, width).force_encoding('utf-8')
62
+ _render_plaintext(opts, width).force_encoding("utf-8")
63
63
  end
64
64
 
65
65
  # Public: Iterate over the children (if any) of the current pointer.
@@ -76,7 +76,7 @@ module CommonMarker
76
76
 
77
77
  # Deprecated: Please use `each` instead
78
78
  def each_child(&block)
79
- warn '[DEPRECATION] `each_child` is deprecated. Please use `each` instead.'
79
+ warn("[DEPRECATION] `each_child` is deprecated. Please use `each` instead.")
80
80
  each(&block)
81
81
  end
82
82
  end
@@ -9,8 +9,8 @@ module CommonMarker
9
9
 
10
10
  def header(node)
11
11
  block do
12
- out('<h', node.header_level, "#{sourcepos(node)}>", :children,
13
- '</h', node.header_level, '>')
12
+ out("<h", node.header_level, "#{sourcepos(node)}>", :children,
13
+ "</h", node.header_level, ">")
14
14
  end
15
15
  end
16
16
 
@@ -19,10 +19,10 @@ module CommonMarker
19
19
  out(:children)
20
20
  else
21
21
  block do
22
- container("<p#{sourcepos(node)}>", '</p>') do
22
+ container("<p#{sourcepos(node)}>", "</p>") do
23
23
  out(:children)
24
24
  if node.parent.type == :footnote_definition && node.next.nil?
25
- out(' ')
25
+ out(" ")
26
26
  out_footnote_backref
27
27
  end
28
28
  end
@@ -36,16 +36,16 @@ module CommonMarker
36
36
 
37
37
  block do
38
38
  if node.list_type == :bullet_list
39
- container("<ul#{sourcepos(node)}>\n", '</ul>') do
39
+ container("<ul#{sourcepos(node)}>\n", "</ul>") do
40
40
  out(:children)
41
41
  end
42
42
  else
43
43
  start = if node.list_start == 1
44
- "<ol#{sourcepos(node)}>\n"
45
- else
46
- "<ol start=\"#{node.list_start}\"#{sourcepos(node)}>\n"
47
- end
48
- container(start, '</ol>') do
44
+ "<ol#{sourcepos(node)}>\n"
45
+ else
46
+ "<ol start=\"#{node.list_start}\"#{sourcepos(node)}>\n"
47
+ end
48
+ container(start, "</ol>") do
49
49
  out(:children)
50
50
  end
51
51
  end
@@ -57,26 +57,26 @@ module CommonMarker
57
57
  def list_item(node)
58
58
  block do
59
59
  tasklist_data = tasklist(node)
60
- container("<li#{sourcepos(node)}#{tasklist_data}>#{' ' if tasklist?(node)}", '</li>') do
60
+ container("<li#{sourcepos(node)}#{tasklist_data}>#{" " if tasklist?(node)}", "</li>") do
61
61
  out(:children)
62
62
  end
63
63
  end
64
64
  end
65
65
 
66
66
  def tasklist(node)
67
- return '' unless tasklist?(node)
67
+ return "" unless tasklist?(node)
68
68
 
69
69
  state = if checked?(node)
70
- 'checked="" disabled=""'
71
- else
72
- 'disabled=""'
73
- end
70
+ 'checked="" disabled=""'
71
+ else
72
+ 'disabled=""'
73
+ end
74
74
  "><input type=\"checkbox\" #{state} /"
75
75
  end
76
76
 
77
77
  def blockquote(node)
78
78
  block do
79
- container("<blockquote#{sourcepos(node)}>\n", '</blockquote>') do
79
+ container("<blockquote#{sourcepos(node)}>\n", "</blockquote>") do
80
80
  out(:children)
81
81
  end
82
82
  end
@@ -93,17 +93,17 @@ module CommonMarker
93
93
  if option_enabled?(:GITHUB_PRE_LANG)
94
94
  out("<pre#{sourcepos(node)}")
95
95
  out(' lang="', node.fence_info.split(/\s+/)[0], '"') if node.fence_info && !node.fence_info.empty?
96
- out('><code>')
96
+ out("><code>")
97
97
  else
98
98
  out("<pre#{sourcepos(node)}><code")
99
99
  if node.fence_info && !node.fence_info.empty?
100
100
  out(' class="language-', node.fence_info.split(/\s+/)[0], '">')
101
101
  else
102
- out('>')
102
+ out(">")
103
103
  end
104
104
  end
105
105
  out(escape_html(node.string_content))
106
- out('</code></pre>')
106
+ out("</code></pre>")
107
107
  end
108
108
  end
109
109
 
@@ -112,7 +112,7 @@ module CommonMarker
112
112
  if option_enabled?(:UNSAFE)
113
113
  out(tagfilter(node.string_content))
114
114
  else
115
- out('<!-- raw HTML omitted -->')
115
+ out("<!-- raw HTML omitted -->")
116
116
  end
117
117
  end
118
118
  end
@@ -121,22 +121,22 @@ module CommonMarker
121
121
  if option_enabled?(:UNSAFE)
122
122
  out(tagfilter(node.string_content))
123
123
  else
124
- out('<!-- raw HTML omitted -->')
124
+ out("<!-- raw HTML omitted -->")
125
125
  end
126
126
  end
127
127
 
128
128
  def emph(_)
129
- out('<em>', :children, '</em>')
129
+ out("<em>", :children, "</em>")
130
130
  end
131
131
 
132
132
  def strong(_)
133
- out('<strong>', :children, '</strong>')
133
+ out("<strong>", :children, "</strong>")
134
134
  end
135
135
 
136
136
  def link(node)
137
- out('<a href="', node.url.nil? ? '' : escape_href(node.url), '"')
137
+ out('<a href="', node.url.nil? ? "" : escape_href(node.url), '"')
138
138
  out(' title="', escape_html(node.title), '"') if node.title && !node.title.empty?
139
- out('>', :children, '</a>')
139
+ out(">", :children, "</a>")
140
140
  end
141
141
 
142
142
  def image(node)
@@ -145,7 +145,7 @@ module CommonMarker
145
145
  out(' alt="', :children, '"')
146
146
  end
147
147
  out(' title="', escape_html(node.title), '"') if node.title && !node.title.empty?
148
- out(' />')
148
+ out(" />")
149
149
  end
150
150
 
151
151
  def text(node)
@@ -153,9 +153,9 @@ module CommonMarker
153
153
  end
154
154
 
155
155
  def code(node)
156
- out('<code>')
156
+ out("<code>")
157
157
  out(escape_html(node.string_content))
158
- out('</code>')
158
+ out("</code>")
159
159
  end
160
160
 
161
161
  def linebreak(_node)
@@ -166,7 +166,7 @@ module CommonMarker
166
166
  if option_enabled?(:HARDBREAKS)
167
167
  out("<br />\n")
168
168
  elsif option_enabled?(:NOBREAKS)
169
- out(' ')
169
+ out(" ")
170
170
  else
171
171
  out("\n")
172
172
  end
@@ -199,17 +199,17 @@ module CommonMarker
199
199
 
200
200
  def table_cell(node)
201
201
  align = case @alignments[@column_index]
202
- when :left then ' align="left"'
203
- when :right then ' align="right"'
204
- when :center then ' align="center"'
205
- else; ''
206
- end
202
+ when :left then ' align="left"'
203
+ when :right then ' align="right"'
204
+ when :center then ' align="center"'
205
+ else; ""
206
+ end
207
207
  out(@in_header ? "<th#{align}#{sourcepos(node)}>" : "<td#{align}#{sourcepos(node)}>", :children, @in_header ? "</th>\n" : "</td>\n")
208
208
  @column_index += 1
209
209
  end
210
210
 
211
211
  def strikethrough(_)
212
- out('<del>', :children, '</del>')
212
+ out("<del>", :children, "</del>")
213
213
  end
214
214
 
215
215
  def footnote_reference(node)
@@ -242,7 +242,7 @@ module CommonMarker
242
242
  end
243
243
 
244
244
  def tasklist?(node)
245
- node.type_string == 'tasklist'
245
+ node.type_string == "tasklist"
246
246
  end
247
247
 
248
248
  def checked?(node)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
- require 'stringio'
3
+ require "set"
4
+ require "stringio"
5
5
 
6
6
  module CommonMarker
7
7
  class Renderer
@@ -9,9 +9,9 @@ module CommonMarker
9
9
 
10
10
  def initialize(options: :DEFAULT, extensions: [])
11
11
  @opts = Config.process_options(options, :render)
12
- @stream = StringIO.new(+'')
12
+ @stream = StringIO.new(+"")
13
13
  @need_blocksep = false
14
- @warnings = Set.new []
14
+ @warnings = Set.new([])
15
15
  @in_tight = false
16
16
  @in_plain = false
17
17
  @tagfilter = extensions.include?(:tagfilter)
@@ -121,7 +121,7 @@ module CommonMarker
121
121
  end
122
122
 
123
123
  def sourcepos(node)
124
- return '' unless option_enabled?(:SOURCEPOS)
124
+ return "" unless option_enabled?(:SOURCEPOS)
125
125
 
126
126
  s = node.sourcepos
127
127
  " data-sourcepos=\"#{s[:start_line]}:#{s[:start_column]}-" \
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CommonMarker
4
- VERSION = '0.23.1'
4
+ VERSION = "0.23.5"
5
5
  end
data/lib/commonmarker.rb CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'commonmarker/commonmarker'
5
- require 'commonmarker/config'
6
- require 'commonmarker/node'
7
- require 'commonmarker/renderer'
8
- require 'commonmarker/renderer/html_renderer'
9
- require 'commonmarker/version'
4
+ require "commonmarker/commonmarker"
5
+ require "commonmarker/config"
6
+ require "commonmarker/node"
7
+ require "commonmarker/renderer"
8
+ require "commonmarker/renderer/html_renderer"
9
+ require "commonmarker/version"
10
10
 
11
11
  begin
12
- require 'awesome_print'
12
+ require "awesome_print"
13
13
  rescue LoadError; end # rubocop:disable Lint/SuppressedException
14
14
  module CommonMarker
15
15
  # Public: Parses a Markdown string into an HTML string.
@@ -23,9 +23,7 @@ module CommonMarker
23
23
  raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
24
24
 
25
25
  opts = Config.process_options(options, :render)
26
- text = text.encode('UTF-8')
27
- html = Node.markdown_to_html(text, opts, extensions)
28
- html.force_encoding('UTF-8')
26
+ Node.markdown_to_html(text.encode("UTF-8"), opts, extensions)
29
27
  end
30
28
 
31
29
  # Public: Parses a Markdown string into a `document` node.
@@ -39,7 +37,7 @@ module CommonMarker
39
37
  raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
40
38
 
41
39
  opts = Config.process_options(options, :parse)
42
- text = text.encode('UTF-8')
40
+ text = text.encode("UTF-8")
43
41
  Node.parse_document(text, text.bytesize, opts, extensions)
44
42
  end
45
43
  end