qiita_marker 0.23.6.2 → 0.23.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/qiita_marker/arena.c +9 -8
- data/ext/qiita_marker/autolink.c +209 -159
- data/ext/qiita_marker/blocks.c +25 -1
- data/ext/qiita_marker/cmark-gfm-core-extensions.h +11 -11
- data/ext/qiita_marker/cmark-gfm-extension_api.h +1 -0
- data/ext/qiita_marker/cmark-gfm.h +18 -2
- data/ext/qiita_marker/cmark-gfm_version.h +2 -2
- data/ext/qiita_marker/cmark.c +3 -3
- data/ext/qiita_marker/commonmark.c +18 -33
- data/ext/qiita_marker/html.c +22 -6
- data/ext/qiita_marker/inlines.c +130 -58
- data/ext/qiita_marker/latex.c +6 -4
- data/ext/qiita_marker/man.c +7 -11
- data/ext/qiita_marker/map.c +11 -4
- data/ext/qiita_marker/map.h +5 -2
- data/ext/qiita_marker/node.c +75 -10
- data/ext/qiita_marker/node.h +42 -1
- data/ext/qiita_marker/parser.h +1 -0
- data/ext/qiita_marker/plaintext.c +12 -29
- data/ext/qiita_marker/qiita_marker.c +1 -0
- data/ext/qiita_marker/references.c +1 -0
- data/ext/qiita_marker/render.c +15 -7
- data/ext/qiita_marker/scanners.c +13917 -10369
- data/ext/qiita_marker/scanners.h +8 -0
- data/ext/qiita_marker/strikethrough.c +1 -1
- data/ext/qiita_marker/table.c +59 -35
- data/ext/qiita_marker/xml.c +2 -1
- data/lib/qiita_marker/config.rb +14 -12
- data/lib/qiita_marker/renderer/html_renderer.rb +15 -4
- data/lib/qiita_marker/renderer.rb +1 -1
- data/lib/qiita_marker/version.rb +1 -1
- data/lib/qiita_marker.rb +26 -24
- data/qiita_marker.gemspec +1 -1
- metadata +4 -4
data/ext/qiita_marker/scanners.h
CHANGED
@@ -15,6 +15,10 @@ bufsize_t _scan_autolink_uri(const unsigned char *p);
|
|
15
15
|
bufsize_t _scan_autolink_email(const unsigned char *p);
|
16
16
|
bufsize_t _scan_html_tag(const unsigned char *p);
|
17
17
|
bufsize_t _scan_liberal_html_tag(const unsigned char *p);
|
18
|
+
bufsize_t _scan_html_comment(const unsigned char *p);
|
19
|
+
bufsize_t _scan_html_pi(const unsigned char *p);
|
20
|
+
bufsize_t _scan_html_declaration(const unsigned char *p);
|
21
|
+
bufsize_t _scan_html_cdata(const unsigned char *p);
|
18
22
|
bufsize_t _scan_html_block_start(const unsigned char *p);
|
19
23
|
bufsize_t _scan_html_block_start_7(const unsigned char *p);
|
20
24
|
bufsize_t _scan_html_block_end_1(const unsigned char *p);
|
@@ -37,6 +41,10 @@ bufsize_t _scan_footnote_definition(const unsigned char *p);
|
|
37
41
|
#define scan_autolink_email(c, n) _scan_at(&_scan_autolink_email, c, n)
|
38
42
|
#define scan_html_tag(c, n) _scan_at(&_scan_html_tag, c, n)
|
39
43
|
#define scan_liberal_html_tag(c, n) _scan_at(&_scan_liberal_html_tag, c, n)
|
44
|
+
#define scan_html_comment(c, n) _scan_at(&_scan_html_comment, c, n)
|
45
|
+
#define scan_html_pi(c, n) _scan_at(&_scan_html_pi, c, n)
|
46
|
+
#define scan_html_declaration(c, n) _scan_at(&_scan_html_declaration, c, n)
|
47
|
+
#define scan_html_cdata(c, n) _scan_at(&_scan_html_cdata, c, n)
|
40
48
|
#define scan_html_block_start(c, n) _scan_at(&_scan_html_block_start, c, n)
|
41
49
|
#define scan_html_block_start_7(c, n) _scan_at(&_scan_html_block_start_7, c, n)
|
42
50
|
#define scan_html_block_end_1(c, n) _scan_at(&_scan_html_block_end_1, c, n)
|
@@ -67,6 +67,7 @@ static delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser,
|
|
67
67
|
strikethrough->end_column = closer->inl_text->start_column + closer->inl_text->as.literal.len - 1;
|
68
68
|
cmark_node_free(closer->inl_text);
|
69
69
|
|
70
|
+
done:
|
70
71
|
delim = closer;
|
71
72
|
while (delim != NULL && delim != opener) {
|
72
73
|
tmp_delim = delim->previous;
|
@@ -76,7 +77,6 @@ static delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser,
|
|
76
77
|
|
77
78
|
cmark_inline_parser_remove_delimiter(inline_parser, opener);
|
78
79
|
|
79
|
-
done:
|
80
80
|
return res;
|
81
81
|
}
|
82
82
|
|
data/ext/qiita_marker/table.c
CHANGED
@@ -11,13 +11,21 @@
|
|
11
11
|
#include "table.h"
|
12
12
|
#include "cmark-gfm-core-extensions.h"
|
13
13
|
|
14
|
+
// Custom node flag, initialized in `create_table_extension`.
|
15
|
+
static cmark_node_internal_flags CMARK_NODE__TABLE_VISITED;
|
16
|
+
|
14
17
|
cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,
|
15
18
|
CMARK_NODE_TABLE_CELL;
|
16
19
|
|
20
|
+
typedef struct {
|
21
|
+
cmark_strbuf *buf;
|
22
|
+
int start_offset, end_offset, internal_offset;
|
23
|
+
} node_cell;
|
24
|
+
|
17
25
|
typedef struct {
|
18
26
|
uint16_t n_columns;
|
19
27
|
int paragraph_offset;
|
20
|
-
|
28
|
+
node_cell *cells;
|
21
29
|
} table_row;
|
22
30
|
|
23
31
|
typedef struct {
|
@@ -29,24 +37,24 @@ typedef struct {
|
|
29
37
|
bool is_header;
|
30
38
|
} node_table_row;
|
31
39
|
|
32
|
-
|
33
|
-
cmark_strbuf *buf;
|
34
|
-
int start_offset, end_offset, internal_offset;
|
35
|
-
} node_cell;
|
36
|
-
|
37
|
-
static void free_table_cell(cmark_mem *mem, void *data) {
|
38
|
-
node_cell *cell = (node_cell *)data;
|
40
|
+
static void free_table_cell(cmark_mem *mem, node_cell *cell) {
|
39
41
|
cmark_strbuf_free((cmark_strbuf *)cell->buf);
|
40
42
|
mem->free(cell->buf);
|
41
|
-
|
43
|
+
}
|
44
|
+
|
45
|
+
static void free_row_cells(cmark_mem *mem, table_row *row) {
|
46
|
+
while (row->n_columns > 0) {
|
47
|
+
free_table_cell(mem, &row->cells[--row->n_columns]);
|
48
|
+
}
|
49
|
+
mem->free(row->cells);
|
50
|
+
row->cells = NULL;
|
42
51
|
}
|
43
52
|
|
44
53
|
static void free_table_row(cmark_mem *mem, table_row *row) {
|
45
54
|
if (!row)
|
46
55
|
return;
|
47
56
|
|
48
|
-
|
49
|
-
|
57
|
+
free_row_cells(mem, row);
|
50
58
|
mem->free(row);
|
51
59
|
}
|
52
60
|
|
@@ -111,6 +119,24 @@ static cmark_strbuf *unescape_pipes(cmark_mem *mem, unsigned char *string, bufsi
|
|
111
119
|
return res;
|
112
120
|
}
|
113
121
|
|
122
|
+
// Adds a new cell to the end of the row. A pointer to the new cell is returned
|
123
|
+
// for the caller to initialize.
|
124
|
+
static node_cell* append_row_cell(cmark_mem *mem, table_row *row) {
|
125
|
+
const uint32_t n_columns = row->n_columns + 1;
|
126
|
+
// realloc when n_columns is a power of 2
|
127
|
+
if ((n_columns & (n_columns-1)) == 0) {
|
128
|
+
// make sure we never wrap row->n_columns
|
129
|
+
// offset will != len and our exit will clean up as intended
|
130
|
+
if (n_columns > UINT16_MAX) {
|
131
|
+
return NULL;
|
132
|
+
}
|
133
|
+
// Use realloc to double the size of the buffer.
|
134
|
+
row->cells = (node_cell *)mem->realloc(row->cells, (2 * n_columns - 1) * sizeof(node_cell));
|
135
|
+
}
|
136
|
+
row->n_columns = (uint16_t)n_columns;
|
137
|
+
return &row->cells[n_columns-1];
|
138
|
+
}
|
139
|
+
|
114
140
|
static table_row *row_from_string(cmark_syntax_extension *self,
|
115
141
|
cmark_parser *parser, unsigned char *string,
|
116
142
|
int len) {
|
@@ -152,24 +178,22 @@ static table_row *row_from_string(cmark_syntax_extension *self,
|
|
152
178
|
cell_matched);
|
153
179
|
cmark_strbuf_trim(cell_buf);
|
154
180
|
|
155
|
-
node_cell *cell = (
|
181
|
+
node_cell *cell = append_row_cell(parser->mem, row);
|
182
|
+
if (!cell) {
|
183
|
+
int_overflow_abort = 1;
|
184
|
+
cmark_strbuf_free(cell_buf);
|
185
|
+
parser->mem->free(cell_buf);
|
186
|
+
break;
|
187
|
+
}
|
156
188
|
cell->buf = cell_buf;
|
157
189
|
cell->start_offset = offset;
|
158
190
|
cell->end_offset = offset + cell_matched - 1;
|
191
|
+
cell->internal_offset = 0;
|
159
192
|
|
160
|
-
while (cell->start_offset >
|
193
|
+
while (cell->start_offset > row->paragraph_offset && string[cell->start_offset - 1] != '|') {
|
161
194
|
--cell->start_offset;
|
162
195
|
++cell->internal_offset;
|
163
196
|
}
|
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
197
|
}
|
174
198
|
|
175
199
|
offset += cell_matched + pipe_matched;
|
@@ -187,9 +211,7 @@ static table_row *row_from_string(cmark_syntax_extension *self,
|
|
187
211
|
if (row_end_offset && offset != len) {
|
188
212
|
row->paragraph_offset = offset;
|
189
213
|
|
190
|
-
|
191
|
-
row->cells = NULL;
|
192
|
-
row->n_columns = 0;
|
214
|
+
free_row_cells(parser->mem, row);
|
193
215
|
|
194
216
|
// Scan past the (optional) leading pipe.
|
195
217
|
offset += scan_table_cell_end(string, len, offset);
|
@@ -240,6 +262,10 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
240
262
|
const char *parent_string;
|
241
263
|
uint16_t i;
|
242
264
|
|
265
|
+
if (parent_container->flags & CMARK_NODE__TABLE_VISITED) {
|
266
|
+
return parent_container;
|
267
|
+
}
|
268
|
+
|
243
269
|
if (!scan_table_start(input, len, cmark_parser_get_first_nonspace(parser))) {
|
244
270
|
return parent_container;
|
245
271
|
}
|
@@ -267,6 +293,7 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
267
293
|
free_table_row(parser->mem, marker_row);
|
268
294
|
free_table_row(parser->mem, header_row);
|
269
295
|
cmark_arena_pop();
|
296
|
+
parent_container->flags |= CMARK_NODE__TABLE_VISITED;
|
270
297
|
return parent_container;
|
271
298
|
}
|
272
299
|
|
@@ -303,9 +330,8 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
303
330
|
// since we populate the alignments array based on marker_row->cells
|
304
331
|
uint8_t *alignments =
|
305
332
|
(uint8_t *)parser->mem->calloc(marker_row->n_columns, sizeof(uint8_t));
|
306
|
-
|
307
|
-
|
308
|
-
node_cell *node = (node_cell *)it->data;
|
333
|
+
for (i = 0; i < marker_row->n_columns; ++i) {
|
334
|
+
node_cell *node = &marker_row->cells[i];
|
309
335
|
bool left = node->buf->ptr[0] == ':', right = node->buf->ptr[node->buf->size - 1] == ':';
|
310
336
|
|
311
337
|
if (left && right)
|
@@ -328,10 +354,8 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
328
354
|
ntr->is_header = true;
|
329
355
|
|
330
356
|
{
|
331
|
-
|
332
|
-
|
333
|
-
for (tmp = header_row->cells; tmp; tmp = tmp->next) {
|
334
|
-
node_cell *cell = (node_cell *) tmp->data;
|
357
|
+
for (i = 0; i < header_row->n_columns; ++i) {
|
358
|
+
node_cell *cell = &header_row->cells[i];
|
335
359
|
cmark_node *header_cell = cmark_parser_add_child(parser, table_header,
|
336
360
|
CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);
|
337
361
|
header_cell->start_line = header_cell->end_line = parent_container->start_line;
|
@@ -378,11 +402,10 @@ static cmark_node *try_opening_table_row(cmark_syntax_extension *self,
|
|
378
402
|
}
|
379
403
|
|
380
404
|
{
|
381
|
-
cmark_llist *tmp;
|
382
405
|
int i, table_columns = get_n_table_columns(parent_container);
|
383
406
|
|
384
|
-
for (
|
385
|
-
node_cell *cell =
|
407
|
+
for (i = 0; i < row->n_columns && i < table_columns; ++i) {
|
408
|
+
node_cell *cell = &row->cells[i];
|
386
409
|
cmark_node *node = cmark_parser_add_child(parser, table_row_block,
|
387
410
|
CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);
|
388
411
|
node->internal_offset = cell->internal_offset;
|
@@ -785,6 +808,7 @@ static int escape(cmark_syntax_extension *self, cmark_node *node, int c) {
|
|
785
808
|
cmark_syntax_extension *create_table_extension(void) {
|
786
809
|
cmark_syntax_extension *self = cmark_syntax_extension_new("table");
|
787
810
|
|
811
|
+
cmark_register_node_flag(&CMARK_NODE__TABLE_VISITED);
|
788
812
|
cmark_syntax_extension_set_match_block_func(self, matches);
|
789
813
|
cmark_syntax_extension_set_open_block_func(self, try_opening_table_block);
|
790
814
|
cmark_syntax_extension_set_get_type_string_func(self, get_type_string);
|
data/ext/qiita_marker/xml.c
CHANGED
@@ -11,6 +11,7 @@
|
|
11
11
|
#include "syntax_extension.h"
|
12
12
|
|
13
13
|
#define BUFFER_SIZE 100
|
14
|
+
#define MAX_INDENT 40
|
14
15
|
|
15
16
|
// Functions to convert cmark_nodes to XML strings.
|
16
17
|
|
@@ -26,7 +27,7 @@ struct render_state {
|
|
26
27
|
|
27
28
|
static CMARK_INLINE void indent(struct render_state *state) {
|
28
29
|
int i;
|
29
|
-
for (i = 0; i < state->indent; i++) {
|
30
|
+
for (i = 0; i < state->indent && i < MAX_INDENT; i++) {
|
30
31
|
cmark_strbuf_putc(state->xml, ' ');
|
31
32
|
}
|
32
33
|
}
|
data/lib/qiita_marker/config.rb
CHANGED
@@ -38,20 +38,22 @@ module QiitaMarker
|
|
38
38
|
format: [:html, :xml, :commonmark, :plaintext].freeze,
|
39
39
|
}.freeze
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
class << self
|
42
|
+
def process_options(option, type)
|
43
|
+
case option
|
44
|
+
when Symbol
|
45
|
+
OPTS.fetch(type).fetch(option)
|
46
|
+
when Array
|
47
|
+
raise TypeError if option.none?
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
# neckbearding around. the map will both check the opts and then bitwise-OR it
|
50
|
+
OPTS.fetch(type).fetch_values(*option).inject(0, :|)
|
51
|
+
else
|
52
|
+
raise TypeError, "option type must be a valid symbol or array of symbols within the #{name}::OPTS[:#{type}] context"
|
53
|
+
end
|
54
|
+
rescue KeyError => e
|
55
|
+
raise TypeError, "option ':#{e.key}' does not exist for #{name}::OPTS[:#{type}]"
|
52
56
|
end
|
53
|
-
rescue KeyError => e
|
54
|
-
raise TypeError, "option ':#{e.key}' does not exist for #{name}::OPTS[:#{type}]"
|
55
57
|
end
|
56
58
|
end
|
57
59
|
end
|
@@ -9,8 +9,15 @@ module QiitaMarker
|
|
9
9
|
|
10
10
|
def header(node)
|
11
11
|
block do
|
12
|
-
out(
|
13
|
-
"
|
12
|
+
out(
|
13
|
+
"<h",
|
14
|
+
node.header_level,
|
15
|
+
"#{sourcepos(node)}>",
|
16
|
+
:children,
|
17
|
+
"</h",
|
18
|
+
node.header_level,
|
19
|
+
">",
|
20
|
+
)
|
14
21
|
end
|
15
22
|
end
|
16
23
|
|
@@ -133,8 +140,12 @@ module QiitaMarker
|
|
133
140
|
out("<em>", :children, "</em>")
|
134
141
|
end
|
135
142
|
|
136
|
-
def strong(
|
137
|
-
|
143
|
+
def strong(node)
|
144
|
+
if node.parent&.type == :strong
|
145
|
+
out(:children)
|
146
|
+
else
|
147
|
+
out("<strong>", :children, "</strong>")
|
148
|
+
end
|
138
149
|
end
|
139
150
|
|
140
151
|
def link(node)
|
data/lib/qiita_marker/version.rb
CHANGED
data/lib/qiita_marker.rb
CHANGED
@@ -12,32 +12,34 @@ begin
|
|
12
12
|
require "awesome_print"
|
13
13
|
rescue LoadError; end # rubocop:disable Lint/SuppressedException
|
14
14
|
module QiitaMarker
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
class << self
|
16
|
+
# Public: Parses a Markdown string into an HTML string.
|
17
|
+
#
|
18
|
+
# text - A {String} of text
|
19
|
+
# option - Either a {Symbol} or {Array of Symbol}s indicating the render options
|
20
|
+
# extensions - An {Array of Symbol}s indicating the extensions to use
|
21
|
+
#
|
22
|
+
# Returns a {String} of converted HTML.
|
23
|
+
def render_html(text, options = :DEFAULT, extensions = [])
|
24
|
+
raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
opts = Config.process_options(options, :render)
|
27
|
+
Node.markdown_to_html(text.encode("UTF-8"), opts, extensions)
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
30
|
+
# Public: Parses a Markdown string into a `document` node.
|
31
|
+
#
|
32
|
+
# string - {String} to be parsed
|
33
|
+
# option - A {Symbol} or {Array of Symbol}s indicating the parse options
|
34
|
+
# extensions - An {Array of Symbol}s indicating the extensions to use
|
35
|
+
#
|
36
|
+
# Returns the `document` node.
|
37
|
+
def render_doc(text, options = :DEFAULT, extensions = [])
|
38
|
+
raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
opts = Config.process_options(options, :parse)
|
41
|
+
text = text.encode("UTF-8")
|
42
|
+
Node.parse_document(text, text.bytesize, opts, extensions)
|
43
|
+
end
|
42
44
|
end
|
43
45
|
end
|
data/qiita_marker.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qiita_marker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.23.
|
4
|
+
version: 0.23.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Qiita Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: awesome_print
|
@@ -252,7 +252,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
252
252
|
requirements:
|
253
253
|
- - ">="
|
254
254
|
- !ruby/object:Gem::Version
|
255
|
-
version: '
|
255
|
+
version: '3.0'
|
256
256
|
- - "<"
|
257
257
|
- !ruby/object:Gem::Version
|
258
258
|
version: '4.0'
|
@@ -262,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
262
262
|
- !ruby/object:Gem::Version
|
263
263
|
version: '0'
|
264
264
|
requirements: []
|
265
|
-
rubygems_version: 3.
|
265
|
+
rubygems_version: 3.2.33
|
266
266
|
signing_key:
|
267
267
|
specification_version: 4
|
268
268
|
summary: Qiita Marker is a Ruby library for Markdown processing, based on CommonMarker.
|