qiita_marker 0.23.6.2 → 0.23.9.0
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 +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.
|