commonmarker 0.17.13 → 0.23.4
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.
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
@@ -7,8 +7,8 @@
|
|
7
7
|
#include "syntax_extension.h"
|
8
8
|
#include "cmark-gfm-core-extensions.h"
|
9
9
|
|
10
|
-
static VALUE
|
11
|
-
static VALUE
|
10
|
+
static VALUE rb_eNodeError;
|
11
|
+
static VALUE rb_cNode;
|
12
12
|
|
13
13
|
static VALUE sym_document;
|
14
14
|
static VALUE sym_blockquote;
|
@@ -45,6 +45,13 @@ static VALUE encode_utf8_string(const char *c_string) {
|
|
45
45
|
return string;
|
46
46
|
}
|
47
47
|
|
48
|
+
/* Encode a C string using the encoding from Ruby string +source+. */
|
49
|
+
static VALUE encode_source_string(const char *c_string, VALUE source) {
|
50
|
+
VALUE string = rb_str_new2(c_string);
|
51
|
+
rb_enc_copy(string, source);
|
52
|
+
return string;
|
53
|
+
}
|
54
|
+
|
48
55
|
static void rb_mark_c_struct(void *data) {
|
49
56
|
cmark_node *node = data;
|
50
57
|
cmark_node *child;
|
@@ -94,7 +101,7 @@ static VALUE rb_node_to_value(cmark_node *node) {
|
|
94
101
|
|
95
102
|
/* Only free tree roots. */
|
96
103
|
free_func = cmark_node_parent(node) ? NULL : rb_free_c_struct;
|
97
|
-
val = Data_Wrap_Struct(
|
104
|
+
val = Data_Wrap_Struct(rb_cNode, rb_mark_c_struct, free_func, node);
|
98
105
|
cmark_node_set_user_data(node, (void *)val);
|
99
106
|
|
100
107
|
return val;
|
@@ -108,25 +115,23 @@ static void rb_parent_removed(VALUE val) {
|
|
108
115
|
RDATA(val)->dfree = rb_free_c_struct;
|
109
116
|
}
|
110
117
|
|
111
|
-
static cmark_parser *prepare_parser(VALUE rb_options, VALUE rb_extensions
|
118
|
+
static cmark_parser *prepare_parser(VALUE rb_options, VALUE rb_extensions) {
|
112
119
|
int options;
|
113
|
-
int extensions_len;
|
114
120
|
VALUE rb_ext_name;
|
115
121
|
int i;
|
116
122
|
|
117
|
-
|
123
|
+
FIXNUM_P(rb_options);
|
124
|
+
options = FIX2INT(rb_options);
|
125
|
+
|
118
126
|
Check_Type(rb_extensions, T_ARRAY);
|
119
127
|
|
120
|
-
|
121
|
-
extensions_len = RARRAY_LEN(rb_extensions);
|
128
|
+
cmark_parser *parser = cmark_parser_new(options);
|
122
129
|
|
123
|
-
|
124
|
-
|
125
|
-
rb_ext_name = RARRAY_PTR(rb_extensions)[i];
|
130
|
+
for (i = 0; i < RARRAY_LEN(rb_extensions); ++i) {
|
131
|
+
rb_ext_name = rb_ary_entry(rb_extensions, i);
|
126
132
|
|
127
133
|
if (!SYMBOL_P(rb_ext_name)) {
|
128
134
|
cmark_parser_free(parser);
|
129
|
-
cmark_arena_reset();
|
130
135
|
rb_raise(rb_eTypeError, "extension names should be Symbols; got a %"PRIsVALUE"", rb_obj_class(rb_ext_name));
|
131
136
|
}
|
132
137
|
|
@@ -135,7 +140,6 @@ static cmark_parser *prepare_parser(VALUE rb_options, VALUE rb_extensions, cmark
|
|
135
140
|
|
136
141
|
if (!syntax_extension) {
|
137
142
|
cmark_parser_free(parser);
|
138
|
-
cmark_arena_reset();
|
139
143
|
rb_raise(rb_eArgError, "extension %s not found", rb_id2name(SYM2ID(rb_ext_name)));
|
140
144
|
}
|
141
145
|
|
@@ -150,33 +154,57 @@ static cmark_parser *prepare_parser(VALUE rb_options, VALUE rb_extensions, cmark
|
|
150
154
|
*
|
151
155
|
*/
|
152
156
|
static VALUE rb_markdown_to_html(VALUE self, VALUE rb_text, VALUE rb_options, VALUE rb_extensions) {
|
153
|
-
char *
|
154
|
-
int len;
|
157
|
+
char *html;
|
155
158
|
cmark_parser *parser;
|
156
159
|
cmark_node *doc;
|
160
|
+
|
157
161
|
Check_Type(rb_text, T_STRING);
|
158
|
-
Check_Type(rb_options, T_FIXNUM);
|
159
162
|
|
160
|
-
parser = prepare_parser(rb_options, rb_extensions
|
163
|
+
parser = prepare_parser(rb_options, rb_extensions);
|
164
|
+
|
165
|
+
cmark_parser_feed(parser, StringValuePtr(rb_text), RSTRING_LEN(rb_text));
|
166
|
+
doc = cmark_parser_finish(parser);
|
167
|
+
|
168
|
+
if (doc == NULL) {
|
169
|
+
cmark_parser_free(parser);
|
170
|
+
rb_raise(rb_eNodeError, "error parsing document");
|
171
|
+
}
|
172
|
+
|
173
|
+
html = cmark_render_html(doc, parser->options, parser->syntax_extensions);
|
174
|
+
|
175
|
+
cmark_parser_free(parser);
|
176
|
+
cmark_node_free(doc);
|
177
|
+
|
178
|
+
return rb_utf8_str_new_cstr(html);
|
179
|
+
}
|
161
180
|
|
162
|
-
|
163
|
-
|
181
|
+
/*
|
182
|
+
* Internal: Parses a Markdown string into an HTML string.
|
183
|
+
*
|
184
|
+
*/
|
185
|
+
static VALUE rb_markdown_to_xml(VALUE self, VALUE rb_text, VALUE rb_options, VALUE rb_extensions) {
|
186
|
+
char *xml;
|
187
|
+
cmark_parser *parser;
|
188
|
+
cmark_node *doc;
|
189
|
+
|
190
|
+
Check_Type(rb_text, T_STRING);
|
164
191
|
|
165
|
-
|
192
|
+
parser = prepare_parser(rb_options, rb_extensions);
|
193
|
+
|
194
|
+
cmark_parser_feed(parser, StringValuePtr(rb_text), RSTRING_LEN(rb_text));
|
166
195
|
doc = cmark_parser_finish(parser);
|
196
|
+
|
167
197
|
if (doc == NULL) {
|
168
|
-
|
169
|
-
rb_raise(
|
198
|
+
cmark_parser_free(parser);
|
199
|
+
rb_raise(rb_eNodeError, "error parsing document");
|
170
200
|
}
|
171
201
|
|
172
|
-
|
173
|
-
html = cmark_render_html_with_mem(doc, FIX2INT(rb_options), parser->syntax_extensions, default_mem);
|
174
|
-
cmark_arena_reset();
|
202
|
+
xml = cmark_render_xml(doc, parser->options);
|
175
203
|
|
176
|
-
|
177
|
-
|
204
|
+
cmark_parser_free(parser);
|
205
|
+
cmark_node_free(doc);
|
178
206
|
|
179
|
-
return
|
207
|
+
return rb_utf8_str_new_cstr(xml);
|
180
208
|
}
|
181
209
|
|
182
210
|
/*
|
@@ -250,11 +278,11 @@ static VALUE rb_node_new(VALUE self, VALUE type) {
|
|
250
278
|
else if (type == sym_footnote_definition)
|
251
279
|
node_type = CMARK_NODE_FOOTNOTE_DEFINITION;
|
252
280
|
else
|
253
|
-
rb_raise(
|
281
|
+
rb_raise(rb_eNodeError, "invalid node of type %d", node_type);
|
254
282
|
|
255
283
|
node = cmark_node_new(node_type);
|
256
284
|
if (node == NULL) {
|
257
|
-
rb_raise(
|
285
|
+
rb_raise(rb_eNodeError, "could not create node of type %d", node_type);
|
258
286
|
}
|
259
287
|
|
260
288
|
return rb_node_to_value(node);
|
@@ -267,23 +295,22 @@ static VALUE rb_node_new(VALUE self, VALUE type) {
|
|
267
295
|
static VALUE rb_parse_document(VALUE self, VALUE rb_text, VALUE rb_len,
|
268
296
|
VALUE rb_options, VALUE rb_extensions) {
|
269
297
|
char *text;
|
270
|
-
int len
|
298
|
+
int len;
|
271
299
|
cmark_parser *parser;
|
272
300
|
cmark_node *doc;
|
273
301
|
Check_Type(rb_text, T_STRING);
|
274
302
|
Check_Type(rb_len, T_FIXNUM);
|
275
303
|
Check_Type(rb_options, T_FIXNUM);
|
276
304
|
|
277
|
-
parser = prepare_parser(rb_options, rb_extensions
|
305
|
+
parser = prepare_parser(rb_options, rb_extensions);
|
278
306
|
|
279
307
|
text = (char *)RSTRING_PTR(rb_text);
|
280
308
|
len = FIX2INT(rb_len);
|
281
|
-
options = FIX2INT(rb_options);
|
282
309
|
|
283
310
|
cmark_parser_feed(parser, text, len);
|
284
311
|
doc = cmark_parser_finish(parser);
|
285
312
|
if (doc == NULL) {
|
286
|
-
rb_raise(
|
313
|
+
rb_raise(rb_eNodeError, "error parsing document");
|
287
314
|
}
|
288
315
|
cmark_parser_free(parser);
|
289
316
|
|
@@ -302,7 +329,7 @@ static VALUE rb_node_get_string_content(VALUE self) {
|
|
302
329
|
|
303
330
|
text = cmark_node_get_literal(node);
|
304
331
|
if (text == NULL) {
|
305
|
-
rb_raise(
|
332
|
+
rb_raise(rb_eNodeError, "could not get string content");
|
306
333
|
}
|
307
334
|
|
308
335
|
return encode_utf8_string(text);
|
@@ -324,7 +351,7 @@ static VALUE rb_node_set_string_content(VALUE self, VALUE s) {
|
|
324
351
|
text = StringValueCStr(s);
|
325
352
|
|
326
353
|
if (!cmark_node_set_literal(node, text)) {
|
327
|
-
rb_raise(
|
354
|
+
rb_raise(rb_eNodeError, "could not set string content");
|
328
355
|
}
|
329
356
|
|
330
357
|
return Qnil;
|
@@ -412,7 +439,7 @@ static VALUE rb_node_get_type(VALUE self) {
|
|
412
439
|
s = node->extension->get_type_string_func(node->extension, node);
|
413
440
|
return ID2SYM(rb_intern(s));
|
414
441
|
}
|
415
|
-
rb_raise(
|
442
|
+
rb_raise(rb_eNodeError, "invalid node type %d", node_type);
|
416
443
|
}
|
417
444
|
|
418
445
|
return symbol;
|
@@ -512,7 +539,7 @@ static VALUE rb_node_insert_before(VALUE self, VALUE sibling) {
|
|
512
539
|
Data_Get_Struct(sibling, cmark_node, node2);
|
513
540
|
|
514
541
|
if (!cmark_node_insert_before(node1, node2)) {
|
515
|
-
rb_raise(
|
542
|
+
rb_raise(rb_eNodeError, "could not insert before");
|
516
543
|
}
|
517
544
|
|
518
545
|
rb_parent_added(sibling);
|
@@ -567,6 +594,27 @@ static VALUE rb_render_html(VALUE self, VALUE rb_options, VALUE rb_extensions) {
|
|
567
594
|
return ruby_html;
|
568
595
|
}
|
569
596
|
|
597
|
+
/* Internal: Convert the node to an XML string.
|
598
|
+
*
|
599
|
+
* Returns a {String}.
|
600
|
+
*/
|
601
|
+
static VALUE rb_render_xml(VALUE self, VALUE rb_options) {
|
602
|
+
int options;
|
603
|
+
cmark_node *node;
|
604
|
+
Check_Type(rb_options, T_FIXNUM);
|
605
|
+
|
606
|
+
options = FIX2INT(rb_options);
|
607
|
+
|
608
|
+
Data_Get_Struct(self, cmark_node, node);
|
609
|
+
|
610
|
+
char *xml = cmark_render_xml(node, options);
|
611
|
+
VALUE ruby_xml = rb_str_new2(xml);
|
612
|
+
|
613
|
+
free(xml);
|
614
|
+
|
615
|
+
return ruby_xml;
|
616
|
+
}
|
617
|
+
|
570
618
|
/* Internal: Convert the node to a CommonMark string.
|
571
619
|
*
|
572
620
|
* Returns a {String}.
|
@@ -638,7 +686,7 @@ static VALUE rb_node_insert_after(VALUE self, VALUE sibling) {
|
|
638
686
|
Data_Get_Struct(sibling, cmark_node, node2);
|
639
687
|
|
640
688
|
if (!cmark_node_insert_after(node1, node2)) {
|
641
|
-
rb_raise(
|
689
|
+
rb_raise(rb_eNodeError, "could not insert after");
|
642
690
|
}
|
643
691
|
|
644
692
|
rb_parent_added(sibling);
|
@@ -661,7 +709,7 @@ static VALUE rb_node_prepend_child(VALUE self, VALUE child) {
|
|
661
709
|
Data_Get_Struct(child, cmark_node, node2);
|
662
710
|
|
663
711
|
if (!cmark_node_prepend_child(node1, node2)) {
|
664
|
-
rb_raise(
|
712
|
+
rb_raise(rb_eNodeError, "could not prepend child");
|
665
713
|
}
|
666
714
|
|
667
715
|
rb_parent_added(child);
|
@@ -684,7 +732,7 @@ static VALUE rb_node_append_child(VALUE self, VALUE child) {
|
|
684
732
|
Data_Get_Struct(child, cmark_node, node2);
|
685
733
|
|
686
734
|
if (!cmark_node_append_child(node1, node2)) {
|
687
|
-
rb_raise(
|
735
|
+
rb_raise(rb_eNodeError, "could not append child");
|
688
736
|
}
|
689
737
|
|
690
738
|
rb_parent_added(child);
|
@@ -744,7 +792,7 @@ static VALUE rb_node_get_url(VALUE self) {
|
|
744
792
|
|
745
793
|
text = cmark_node_get_url(node);
|
746
794
|
if (text == NULL) {
|
747
|
-
rb_raise(
|
795
|
+
rb_raise(rb_eNodeError, "could not get url");
|
748
796
|
}
|
749
797
|
|
750
798
|
return rb_str_new2(text);
|
@@ -766,7 +814,7 @@ static VALUE rb_node_set_url(VALUE self, VALUE url) {
|
|
766
814
|
text = StringValueCStr(url);
|
767
815
|
|
768
816
|
if (!cmark_node_set_url(node, text)) {
|
769
|
-
rb_raise(
|
817
|
+
rb_raise(rb_eNodeError, "could not set url");
|
770
818
|
}
|
771
819
|
|
772
820
|
return Qnil;
|
@@ -785,7 +833,7 @@ static VALUE rb_node_get_title(VALUE self) {
|
|
785
833
|
|
786
834
|
text = cmark_node_get_title(node);
|
787
835
|
if (text == NULL) {
|
788
|
-
rb_raise(
|
836
|
+
rb_raise(rb_eNodeError, "could not get title");
|
789
837
|
}
|
790
838
|
|
791
839
|
return rb_str_new2(text);
|
@@ -807,7 +855,7 @@ static VALUE rb_node_set_title(VALUE self, VALUE title) {
|
|
807
855
|
text = StringValueCStr(title);
|
808
856
|
|
809
857
|
if (!cmark_node_set_title(node, text)) {
|
810
|
-
rb_raise(
|
858
|
+
rb_raise(rb_eNodeError, "could not set title");
|
811
859
|
}
|
812
860
|
|
813
861
|
return Qnil;
|
@@ -827,7 +875,7 @@ static VALUE rb_node_get_header_level(VALUE self) {
|
|
827
875
|
header_level = cmark_node_get_header_level(node);
|
828
876
|
|
829
877
|
if (header_level == 0) {
|
830
|
-
rb_raise(
|
878
|
+
rb_raise(rb_eNodeError, "could not get header_level");
|
831
879
|
}
|
832
880
|
|
833
881
|
return INT2NUM(header_level);
|
@@ -849,7 +897,7 @@ static VALUE rb_node_set_header_level(VALUE self, VALUE level) {
|
|
849
897
|
l = FIX2INT(level);
|
850
898
|
|
851
899
|
if (!cmark_node_set_header_level(node, l)) {
|
852
|
-
rb_raise(
|
900
|
+
rb_raise(rb_eNodeError, "could not set header_level");
|
853
901
|
}
|
854
902
|
|
855
903
|
return Qnil;
|
@@ -874,7 +922,7 @@ static VALUE rb_node_get_list_type(VALUE self) {
|
|
874
922
|
} else if (list_type == CMARK_ORDERED_LIST) {
|
875
923
|
symbol = sym_ordered_list;
|
876
924
|
} else {
|
877
|
-
rb_raise(
|
925
|
+
rb_raise(rb_eNodeError, "could not get list_type");
|
878
926
|
}
|
879
927
|
|
880
928
|
return symbol;
|
@@ -899,11 +947,11 @@ static VALUE rb_node_set_list_type(VALUE self, VALUE list_type) {
|
|
899
947
|
} else if (list_type == sym_ordered_list) {
|
900
948
|
type = CMARK_ORDERED_LIST;
|
901
949
|
} else {
|
902
|
-
rb_raise(
|
950
|
+
rb_raise(rb_eNodeError, "invalid list_type");
|
903
951
|
}
|
904
952
|
|
905
953
|
if (!cmark_node_set_list_type(node, type)) {
|
906
|
-
rb_raise(
|
954
|
+
rb_raise(rb_eNodeError, "could not set list_type");
|
907
955
|
}
|
908
956
|
|
909
957
|
return Qnil;
|
@@ -922,7 +970,7 @@ static VALUE rb_node_get_list_start(VALUE self) {
|
|
922
970
|
|
923
971
|
if (cmark_node_get_type(node) != CMARK_NODE_LIST ||
|
924
972
|
cmark_node_get_list_type(node) != CMARK_ORDERED_LIST) {
|
925
|
-
rb_raise(
|
973
|
+
rb_raise(rb_eNodeError, "can't get list_start for non-ordered list %d",
|
926
974
|
cmark_node_get_list_type(node));
|
927
975
|
}
|
928
976
|
|
@@ -946,7 +994,7 @@ static VALUE rb_node_set_list_start(VALUE self, VALUE start) {
|
|
946
994
|
s = FIX2INT(start);
|
947
995
|
|
948
996
|
if (!cmark_node_set_list_start(node, s)) {
|
949
|
-
rb_raise(
|
997
|
+
rb_raise(rb_eNodeError, "could not set list_start");
|
950
998
|
}
|
951
999
|
|
952
1000
|
return Qnil;
|
@@ -964,7 +1012,7 @@ static VALUE rb_node_get_list_tight(VALUE self) {
|
|
964
1012
|
Data_Get_Struct(self, cmark_node, node);
|
965
1013
|
|
966
1014
|
if (cmark_node_get_type(node) != CMARK_NODE_LIST) {
|
967
|
-
rb_raise(
|
1015
|
+
rb_raise(rb_eNodeError, "can't get list_tight for non-list");
|
968
1016
|
}
|
969
1017
|
|
970
1018
|
flag = cmark_node_get_list_tight(node);
|
@@ -986,7 +1034,7 @@ static VALUE rb_node_set_list_tight(VALUE self, VALUE tight) {
|
|
986
1034
|
t = RTEST(tight);
|
987
1035
|
|
988
1036
|
if (!cmark_node_set_list_tight(node, t)) {
|
989
|
-
rb_raise(
|
1037
|
+
rb_raise(rb_eNodeError, "could not set list_tight");
|
990
1038
|
}
|
991
1039
|
|
992
1040
|
return Qnil;
|
@@ -1006,7 +1054,7 @@ static VALUE rb_node_get_fence_info(VALUE self) {
|
|
1006
1054
|
fence_info = cmark_node_get_fence_info(node);
|
1007
1055
|
|
1008
1056
|
if (fence_info == NULL) {
|
1009
|
-
rb_raise(
|
1057
|
+
rb_raise(rb_eNodeError, "could not get fence_info");
|
1010
1058
|
}
|
1011
1059
|
|
1012
1060
|
return rb_str_new2(fence_info);
|
@@ -1028,12 +1076,66 @@ static VALUE rb_node_set_fence_info(VALUE self, VALUE info) {
|
|
1028
1076
|
text = StringValueCStr(info);
|
1029
1077
|
|
1030
1078
|
if (!cmark_node_set_fence_info(node, text)) {
|
1031
|
-
rb_raise(
|
1079
|
+
rb_raise(rb_eNodeError, "could not set fence_info");
|
1032
1080
|
}
|
1033
1081
|
|
1034
1082
|
return Qnil;
|
1035
1083
|
}
|
1036
1084
|
|
1085
|
+
static VALUE rb_node_get_tasklist_item_checked(VALUE self) {
|
1086
|
+
int tasklist_state;
|
1087
|
+
cmark_node *node;
|
1088
|
+
Data_Get_Struct(self, cmark_node, node);
|
1089
|
+
|
1090
|
+
tasklist_state = cmark_gfm_extensions_get_tasklist_item_checked(node);
|
1091
|
+
|
1092
|
+
if (tasklist_state == 1) {
|
1093
|
+
return Qtrue;
|
1094
|
+
} else {
|
1095
|
+
return Qfalse;
|
1096
|
+
}
|
1097
|
+
}
|
1098
|
+
|
1099
|
+
/*
|
1100
|
+
* Public: Sets the checkbox state of the current node (must be a `:tasklist`).
|
1101
|
+
*
|
1102
|
+
* item_checked - A {Boolean} representing the new checkbox state
|
1103
|
+
*
|
1104
|
+
* Returns a {Boolean} representing the new checkbox state.
|
1105
|
+
* Raises a NodeError if the checkbox state can't be set.
|
1106
|
+
*/
|
1107
|
+
static VALUE rb_node_set_tasklist_item_checked(VALUE self, VALUE item_checked) {
|
1108
|
+
int tasklist_state;
|
1109
|
+
cmark_node *node;
|
1110
|
+
Data_Get_Struct(self, cmark_node, node);
|
1111
|
+
tasklist_state = RTEST(item_checked);
|
1112
|
+
|
1113
|
+
if (!cmark_gfm_extensions_set_tasklist_item_checked(node, tasklist_state)) {
|
1114
|
+
rb_raise(rb_eNodeError, "could not set tasklist_item_checked");
|
1115
|
+
};
|
1116
|
+
|
1117
|
+
if (tasklist_state) {
|
1118
|
+
return Qtrue;
|
1119
|
+
} else {
|
1120
|
+
return Qfalse;
|
1121
|
+
}
|
1122
|
+
}
|
1123
|
+
|
1124
|
+
// TODO: remove this, superseded by the above method
|
1125
|
+
static VALUE rb_node_get_tasklist_state(VALUE self) {
|
1126
|
+
int tasklist_state;
|
1127
|
+
cmark_node *node;
|
1128
|
+
Data_Get_Struct(self, cmark_node, node);
|
1129
|
+
|
1130
|
+
tasklist_state = cmark_gfm_extensions_get_tasklist_item_checked(node);
|
1131
|
+
|
1132
|
+
if (tasklist_state == 1) {
|
1133
|
+
return rb_str_new2("checked");
|
1134
|
+
} else {
|
1135
|
+
return rb_str_new2("unchecked");
|
1136
|
+
}
|
1137
|
+
}
|
1138
|
+
|
1037
1139
|
static VALUE rb_node_get_table_alignments(VALUE self) {
|
1038
1140
|
uint16_t column_count, i;
|
1039
1141
|
uint8_t *alignments;
|
@@ -1045,7 +1147,7 @@ static VALUE rb_node_get_table_alignments(VALUE self) {
|
|
1045
1147
|
alignments = cmark_gfm_extensions_get_table_alignments(node);
|
1046
1148
|
|
1047
1149
|
if (!column_count || !alignments) {
|
1048
|
-
rb_raise(
|
1150
|
+
rb_raise(rb_eNodeError, "could not get column_count or alignments");
|
1049
1151
|
}
|
1050
1152
|
|
1051
1153
|
ary = rb_ary_new();
|
@@ -1076,7 +1178,8 @@ static VALUE rb_html_escape_href(VALUE self, VALUE rb_text) {
|
|
1076
1178
|
if (houdini_escape_href(&buf, (const uint8_t *)RSTRING_PTR(rb_text),
|
1077
1179
|
RSTRING_LEN(rb_text))) {
|
1078
1180
|
result = (char *)cmark_strbuf_detach(&buf);
|
1079
|
-
return
|
1181
|
+
return encode_source_string(result, rb_text);
|
1182
|
+
|
1080
1183
|
}
|
1081
1184
|
|
1082
1185
|
return rb_text;
|
@@ -1096,7 +1199,7 @@ static VALUE rb_html_escape_html(VALUE self, VALUE rb_text) {
|
|
1096
1199
|
if (houdini_escape_html0(&buf, (const uint8_t *)RSTRING_PTR(rb_text),
|
1097
1200
|
RSTRING_LEN(rb_text), 0)) {
|
1098
1201
|
result = (char *)cmark_strbuf_detach(&buf);
|
1099
|
-
return
|
1202
|
+
return encode_source_string(result, rb_text);
|
1100
1203
|
}
|
1101
1204
|
|
1102
1205
|
return rb_text;
|
@@ -1150,48 +1253,54 @@ __attribute__((visibility("default"))) void Init_commonmarker() {
|
|
1150
1253
|
|
1151
1254
|
module = rb_define_module("CommonMarker");
|
1152
1255
|
rb_define_singleton_method(module, "extensions", rb_extensions, 0);
|
1153
|
-
|
1154
|
-
|
1155
|
-
rb_define_singleton_method(
|
1256
|
+
rb_eNodeError = rb_define_class_under(module, "NodeError", rb_eStandardError);
|
1257
|
+
rb_cNode = rb_define_class_under(module, "Node", rb_cObject);
|
1258
|
+
rb_define_singleton_method(rb_cNode, "markdown_to_html", rb_markdown_to_html,
|
1259
|
+
3);
|
1260
|
+
rb_define_singleton_method(rb_cNode, "markdown_to_xml", rb_markdown_to_xml,
|
1156
1261
|
3);
|
1157
|
-
rb_define_singleton_method(
|
1158
|
-
rb_define_singleton_method(
|
1159
|
-
rb_define_method(
|
1160
|
-
rb_define_method(
|
1161
|
-
rb_define_method(
|
1162
|
-
rb_define_method(
|
1163
|
-
rb_define_method(
|
1164
|
-
rb_define_method(
|
1165
|
-
rb_define_method(
|
1166
|
-
rb_define_method(
|
1167
|
-
rb_define_method(
|
1168
|
-
rb_define_method(
|
1169
|
-
rb_define_method(
|
1170
|
-
rb_define_method(
|
1171
|
-
rb_define_method(
|
1172
|
-
rb_define_method(
|
1173
|
-
rb_define_method(
|
1174
|
-
rb_define_method(
|
1175
|
-
rb_define_method(
|
1176
|
-
rb_define_method(
|
1177
|
-
rb_define_method(
|
1178
|
-
rb_define_method(
|
1179
|
-
rb_define_method(
|
1180
|
-
rb_define_method(
|
1181
|
-
rb_define_method(
|
1182
|
-
rb_define_method(
|
1183
|
-
rb_define_method(
|
1184
|
-
rb_define_method(
|
1185
|
-
rb_define_method(
|
1186
|
-
rb_define_method(
|
1187
|
-
rb_define_method(
|
1188
|
-
rb_define_method(
|
1189
|
-
rb_define_method(
|
1190
|
-
rb_define_method(
|
1191
|
-
rb_define_method(
|
1192
|
-
|
1193
|
-
rb_define_method(
|
1194
|
-
rb_define_method(
|
1262
|
+
rb_define_singleton_method(rb_cNode, "new", rb_node_new, 1);
|
1263
|
+
rb_define_singleton_method(rb_cNode, "parse_document", rb_parse_document, 4);
|
1264
|
+
rb_define_method(rb_cNode, "string_content", rb_node_get_string_content, 0);
|
1265
|
+
rb_define_method(rb_cNode, "string_content=", rb_node_set_string_content, 1);
|
1266
|
+
rb_define_method(rb_cNode, "type", rb_node_get_type, 0);
|
1267
|
+
rb_define_method(rb_cNode, "type_string", rb_node_get_type_string, 0);
|
1268
|
+
rb_define_method(rb_cNode, "sourcepos", rb_node_get_sourcepos, 0);
|
1269
|
+
rb_define_method(rb_cNode, "delete", rb_node_unlink, 0);
|
1270
|
+
rb_define_method(rb_cNode, "first_child", rb_node_first_child, 0);
|
1271
|
+
rb_define_method(rb_cNode, "next", rb_node_next, 0);
|
1272
|
+
rb_define_method(rb_cNode, "insert_before", rb_node_insert_before, 1);
|
1273
|
+
rb_define_method(rb_cNode, "_render_html", rb_render_html, 2);
|
1274
|
+
rb_define_method(rb_cNode, "_render_xml", rb_render_xml, 1);
|
1275
|
+
rb_define_method(rb_cNode, "_render_commonmark", rb_render_commonmark, -1);
|
1276
|
+
rb_define_method(rb_cNode, "_render_plaintext", rb_render_plaintext, -1);
|
1277
|
+
rb_define_method(rb_cNode, "insert_after", rb_node_insert_after, 1);
|
1278
|
+
rb_define_method(rb_cNode, "prepend_child", rb_node_prepend_child, 1);
|
1279
|
+
rb_define_method(rb_cNode, "append_child", rb_node_append_child, 1);
|
1280
|
+
rb_define_method(rb_cNode, "last_child", rb_node_last_child, 0);
|
1281
|
+
rb_define_method(rb_cNode, "parent", rb_node_parent, 0);
|
1282
|
+
rb_define_method(rb_cNode, "previous", rb_node_previous, 0);
|
1283
|
+
rb_define_method(rb_cNode, "url", rb_node_get_url, 0);
|
1284
|
+
rb_define_method(rb_cNode, "url=", rb_node_set_url, 1);
|
1285
|
+
rb_define_method(rb_cNode, "title", rb_node_get_title, 0);
|
1286
|
+
rb_define_method(rb_cNode, "title=", rb_node_set_title, 1);
|
1287
|
+
rb_define_method(rb_cNode, "header_level", rb_node_get_header_level, 0);
|
1288
|
+
rb_define_method(rb_cNode, "header_level=", rb_node_set_header_level, 1);
|
1289
|
+
rb_define_method(rb_cNode, "list_type", rb_node_get_list_type, 0);
|
1290
|
+
rb_define_method(rb_cNode, "list_type=", rb_node_set_list_type, 1);
|
1291
|
+
rb_define_method(rb_cNode, "list_start", rb_node_get_list_start, 0);
|
1292
|
+
rb_define_method(rb_cNode, "list_start=", rb_node_set_list_start, 1);
|
1293
|
+
rb_define_method(rb_cNode, "list_tight", rb_node_get_list_tight, 0);
|
1294
|
+
rb_define_method(rb_cNode, "list_tight=", rb_node_set_list_tight, 1);
|
1295
|
+
rb_define_method(rb_cNode, "fence_info", rb_node_get_fence_info, 0);
|
1296
|
+
rb_define_method(rb_cNode, "fence_info=", rb_node_set_fence_info, 1);
|
1297
|
+
rb_define_method(rb_cNode, "table_alignments", rb_node_get_table_alignments, 0);
|
1298
|
+
rb_define_method(rb_cNode, "tasklist_state", rb_node_get_tasklist_state, 0);
|
1299
|
+
rb_define_method(rb_cNode, "tasklist_item_checked?", rb_node_get_tasklist_item_checked, 0);
|
1300
|
+
rb_define_method(rb_cNode, "tasklist_item_checked=", rb_node_set_tasklist_item_checked, 1);
|
1301
|
+
|
1302
|
+
rb_define_method(rb_cNode, "html_escape_href", rb_html_escape_href, 1);
|
1303
|
+
rb_define_method(rb_cNode, "html_escape_html", rb_html_escape_html, 1);
|
1195
1304
|
|
1196
1305
|
cmark_gfm_core_extensions_ensure_registered();
|
1197
1306
|
}
|
@@ -3,6 +3,7 @@
|
|
3
3
|
#include "strikethrough.h"
|
4
4
|
#include "table.h"
|
5
5
|
#include "tagfilter.h"
|
6
|
+
#include "tasklist.h"
|
6
7
|
#include "registry.h"
|
7
8
|
#include "plugin.h"
|
8
9
|
|
@@ -12,6 +13,7 @@ static int core_extensions_registration(cmark_plugin *plugin) {
|
|
12
13
|
create_strikethrough_extension());
|
13
14
|
cmark_plugin_register_syntax_extension(plugin, create_autolink_extension());
|
14
15
|
cmark_plugin_register_syntax_extension(plugin, create_tagfilter_extension());
|
16
|
+
cmark_plugin_register_syntax_extension(plugin, create_tasklist_extension());
|
15
17
|
return 1;
|
16
18
|
}
|
17
19
|
|