commonmarker 0.19.0 → 0.21.1

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 (52) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +2 -3
  3. data/Rakefile +16 -4
  4. data/bin/commonmarker +82 -44
  5. data/commonmarker.gemspec +9 -12
  6. data/ext/commonmarker/blocks.c +89 -29
  7. data/ext/commonmarker/buffer.c +0 -1
  8. data/ext/commonmarker/chunk.h +0 -1
  9. data/ext/commonmarker/cmark-gfm-core-extensions.h +24 -1
  10. data/ext/commonmarker/cmark-gfm.h +14 -8
  11. data/ext/commonmarker/cmark-gfm_version.h +2 -2
  12. data/ext/commonmarker/commonmark.c +9 -4
  13. data/ext/commonmarker/commonmarker.c +120 -78
  14. data/ext/commonmarker/html.c +4 -4
  15. data/ext/commonmarker/inlines.c +21 -14
  16. data/ext/commonmarker/iterator.h +0 -1
  17. data/ext/commonmarker/map.h +0 -1
  18. data/ext/commonmarker/node.h +2 -0
  19. data/ext/commonmarker/parser.h +2 -1
  20. data/ext/commonmarker/render.c +16 -14
  21. data/ext/commonmarker/render.h +0 -1
  22. data/ext/commonmarker/scanners.c +777 -951
  23. data/ext/commonmarker/scanners.h +0 -2
  24. data/ext/commonmarker/table.c +52 -13
  25. data/ext/commonmarker/tasklist.c +34 -13
  26. data/lib/commonmarker.rb +5 -4
  27. data/lib/commonmarker/config.rb +5 -4
  28. data/lib/commonmarker/node.rb +1 -1
  29. data/lib/commonmarker/node/inspect.rb +12 -12
  30. data/lib/commonmarker/renderer.rb +7 -7
  31. data/lib/commonmarker/renderer/html_renderer.rb +22 -35
  32. data/lib/commonmarker/version.rb +1 -1
  33. data/test/benchmark.rb +1 -5
  34. data/test/fixtures/strong.md +1 -0
  35. data/test/fixtures/table.md +10 -0
  36. data/test/test_attributes.rb +3 -3
  37. data/test/test_commands.rb +31 -0
  38. data/test/test_commonmark.rb +11 -11
  39. data/test/test_encoding.rb +1 -2
  40. data/test/test_extensions.rb +40 -52
  41. data/test/test_footnotes.rb +9 -9
  42. data/test/test_gc.rb +2 -0
  43. data/test/test_helper.rb +15 -8
  44. data/test/test_maliciousness.rb +192 -190
  45. data/test/test_node.rb +10 -12
  46. data/test/test_options.rb +15 -15
  47. data/test/test_pathological_inputs.rb +2 -2
  48. data/test/test_plaintext.rb +21 -21
  49. data/test/test_renderer.rb +9 -9
  50. data/test/test_spec.rb +3 -2
  51. data/test/test_tasklists.rb +22 -6
  52. metadata +51 -46
@@ -10,7 +10,6 @@
10
10
  #include "config.h"
11
11
  #include "cmark_ctype.h"
12
12
  #include "buffer.h"
13
- #include "memory.h"
14
13
 
15
14
  /* Used as default value for cmark_strbuf->ptr so that people can always
16
15
  * assume ptr is non-NULL and zero terminated even for new cmark_strbufs.
@@ -6,7 +6,6 @@
6
6
  #include <assert.h>
7
7
  #include "cmark-gfm.h"
8
8
  #include "buffer.h"
9
- #include "memory.h"
10
9
  #include "cmark_ctype.h"
11
10
 
12
11
  #define CMARK_CHUNK_EMPTY \
@@ -7,6 +7,7 @@ extern "C" {
7
7
 
8
8
  #include "cmark-gfm-extension_api.h"
9
9
  #include "cmark-gfm-extensions_export.h"
10
+ #include "config.h" // for bool
10
11
  #include <stdint.h>
11
12
 
12
13
  CMARK_GFM_EXTENSIONS_EXPORT
@@ -15,14 +16,36 @@ void cmark_gfm_core_extensions_ensure_registered(void);
15
16
  CMARK_GFM_EXTENSIONS_EXPORT
16
17
  uint16_t cmark_gfm_extensions_get_table_columns(cmark_node *node);
17
18
 
19
+ /** Sets the number of columns for the table, returning 1 on success and 0 on error.
20
+ */
21
+ CMARK_GFM_EXTENSIONS_EXPORT
22
+ int cmark_gfm_extensions_set_table_columns(cmark_node *node, uint16_t n_columns);
23
+
18
24
  CMARK_GFM_EXTENSIONS_EXPORT
19
25
  uint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node);
20
26
 
27
+ /** Sets the alignments for the table, returning 1 on success and 0 on error.
28
+ */
29
+ CMARK_GFM_EXTENSIONS_EXPORT
30
+ int cmark_gfm_extensions_set_table_alignments(cmark_node *node, uint16_t ncols, uint8_t *alignments);
31
+
21
32
  CMARK_GFM_EXTENSIONS_EXPORT
22
33
  int cmark_gfm_extensions_get_table_row_is_header(cmark_node *node);
23
34
 
35
+ /** Sets whether the node is a table header row, returning 1 on success and 0 on error.
36
+ */
37
+ CMARK_GFM_EXTENSIONS_EXPORT
38
+ int cmark_gfm_extensions_set_table_row_is_header(cmark_node *node, int is_header);
39
+
40
+ CMARK_GFM_EXTENSIONS_EXPORT
41
+ bool cmark_gfm_extensions_get_tasklist_item_checked(cmark_node *node);
42
+ /* For backwards compatibility */
43
+ #define cmark_gfm_extensions_tasklist_is_checked cmark_gfm_extensions_get_tasklist_item_checked
44
+
45
+ /** Sets whether a tasklist item is "checked" (completed), returning 1 on success and 0 on error.
46
+ */
24
47
  CMARK_GFM_EXTENSIONS_EXPORT
25
- char *cmark_gfm_extensions_get_tasklist_state(cmark_node *node);
48
+ int cmark_gfm_extensions_set_tasklist_item_checked(cmark_node *node, bool is_checked);
26
49
 
27
50
  #ifdef __cplusplus
28
51
  }
@@ -690,6 +690,20 @@ char *cmark_render_latex_with_mem(cmark_node *root, int options, int width, cmar
690
690
  */
691
691
  #define CMARK_OPT_HARDBREAKS (1 << 2)
692
692
 
693
+ /** `CMARK_OPT_SAFE` is defined here for API compatibility,
694
+ but it no longer has any effect. "Safe" mode is now the default:
695
+ set `CMARK_OPT_UNSAFE` to disable it.
696
+ */
697
+ #define CMARK_OPT_SAFE (1 << 3)
698
+
699
+ /** Render raw HTML and unsafe links (`javascript:`, `vbscript:`,
700
+ * `file:`, and `data:`, except for `image/png`, `image/gif`,
701
+ * `image/jpeg`, or `image/webp` mime types). By default,
702
+ * raw HTML is replaced by a placeholder HTML comment. Unsafe
703
+ * links are replaced by empty strings.
704
+ */
705
+ #define CMARK_OPT_UNSAFE (1 << 17)
706
+
693
707
  /** Render `softbreak` elements as spaces.
694
708
  */
695
709
  #define CMARK_OPT_NOBREAKS (1 << 4)
@@ -738,14 +752,6 @@ char *cmark_render_latex_with_mem(cmark_node *root, int options, int width, cmar
738
752
  */
739
753
  #define CMARK_OPT_FULL_INFO_STRING (1 << 16)
740
754
 
741
- /** Allow raw HTML and unsafe links, `javascript:`, `vbscript:`, `file:`, and
742
- * all `data:` URLs -- by default, only `image/png`, `image/gif`, `image/jpeg`,
743
- * or `image/webp` mime types are allowed. Without this option, raw HTML is
744
- * replaced by a placeholder HTML comment, and unsafe links are replaced by
745
- * empty strings.
746
- */
747
- #define CMARK_OPT_UNSAFE (1 << 17)
748
-
749
755
  /**
750
756
  * ## Version information
751
757
  */
@@ -1,7 +1,7 @@
1
1
  #ifndef CMARK_GFM_VERSION_H
2
2
  #define CMARK_GFM_VERSION_H
3
3
 
4
- #define CMARK_GFM_VERSION ((0 << 24) | (28 << 16) | (3 << 8) | 20)
5
- #define CMARK_GFM_VERSION_STRING "0.28.3.gfm.20"
4
+ #define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 0)
5
+ #define CMARK_GFM_VERSION_STRING "0.29.0.gfm.0"
6
6
 
7
7
  #endif
@@ -34,7 +34,8 @@ static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node,
34
34
  needs_escaping =
35
35
  c < 0x80 && escape != LITERAL &&
36
36
  ((escape == NORMAL &&
37
- (c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||
37
+ (c < 0x20 ||
38
+ c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||
38
39
  c == '>' || c == '\\' || c == '`' || c == '~' || c == '!' ||
39
40
  (c == '&' && cmark_isalpha(nextc)) || (c == '!' && nextc == '[') ||
40
41
  (renderer->begin_content && (c == '-' || c == '+' || c == '=') &&
@@ -50,14 +51,18 @@ static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node,
50
51
  (c == '`' || c == '<' || c == '>' || c == '"' || c == '\\')));
51
52
 
52
53
  if (needs_escaping) {
53
- if (cmark_isspace((char)c)) {
54
+ if (escape == URL && cmark_isspace((char)c)) {
54
55
  // use percent encoding for spaces
55
- snprintf(encoded, ENCODED_SIZE, "%%%2x", c);
56
+ snprintf(encoded, ENCODED_SIZE, "%%%2X", c);
56
57
  cmark_strbuf_puts(renderer->buffer, encoded);
57
58
  renderer->column += 3;
58
- } else {
59
+ } else if (cmark_ispunct((char)c)) {
59
60
  cmark_render_ascii(renderer, "\\");
60
61
  cmark_render_code_point(renderer, c);
62
+ } else { // render as entity
63
+ snprintf(encoded, ENCODED_SIZE, "&#%d;", c);
64
+ cmark_strbuf_puts(renderer->buffer, encoded);
65
+ renderer->column += (int)strlen(encoded);
61
66
  }
62
67
  } else {
63
68
  cmark_render_code_point(renderer, c);
@@ -7,8 +7,8 @@
7
7
  #include "syntax_extension.h"
8
8
  #include "cmark-gfm-core-extensions.h"
9
9
 
10
- static VALUE rb_mNodeError;
11
- static VALUE rb_mNode;
10
+ static VALUE rb_eNodeError;
11
+ static VALUE rb_cNode;
12
12
 
13
13
  static VALUE sym_document;
14
14
  static VALUE sym_blockquote;
@@ -94,7 +94,7 @@ static VALUE rb_node_to_value(cmark_node *node) {
94
94
 
95
95
  /* Only free tree roots. */
96
96
  free_func = cmark_node_parent(node) ? NULL : rb_free_c_struct;
97
- val = Data_Wrap_Struct(rb_mNode, rb_mark_c_struct, free_func, node);
97
+ val = Data_Wrap_Struct(rb_cNode, rb_mark_c_struct, free_func, node);
98
98
  cmark_node_set_user_data(node, (void *)val);
99
99
 
100
100
  return val;
@@ -166,7 +166,7 @@ static VALUE rb_markdown_to_html(VALUE self, VALUE rb_text, VALUE rb_options, VA
166
166
  doc = cmark_parser_finish(parser);
167
167
  if (doc == NULL) {
168
168
  cmark_arena_reset();
169
- rb_raise(rb_mNodeError, "error parsing document");
169
+ rb_raise(rb_eNodeError, "error parsing document");
170
170
  }
171
171
 
172
172
  cmark_mem *default_mem = cmark_get_default_mem_allocator();
@@ -250,11 +250,11 @@ static VALUE rb_node_new(VALUE self, VALUE type) {
250
250
  else if (type == sym_footnote_definition)
251
251
  node_type = CMARK_NODE_FOOTNOTE_DEFINITION;
252
252
  else
253
- rb_raise(rb_mNodeError, "invalid node of type %d", node_type);
253
+ rb_raise(rb_eNodeError, "invalid node of type %d", node_type);
254
254
 
255
255
  node = cmark_node_new(node_type);
256
256
  if (node == NULL) {
257
- rb_raise(rb_mNodeError, "could not create node of type %d", node_type);
257
+ rb_raise(rb_eNodeError, "could not create node of type %d", node_type);
258
258
  }
259
259
 
260
260
  return rb_node_to_value(node);
@@ -283,7 +283,7 @@ static VALUE rb_parse_document(VALUE self, VALUE rb_text, VALUE rb_len,
283
283
  cmark_parser_feed(parser, text, len);
284
284
  doc = cmark_parser_finish(parser);
285
285
  if (doc == NULL) {
286
- rb_raise(rb_mNodeError, "error parsing document");
286
+ rb_raise(rb_eNodeError, "error parsing document");
287
287
  }
288
288
  cmark_parser_free(parser);
289
289
 
@@ -302,7 +302,7 @@ static VALUE rb_node_get_string_content(VALUE self) {
302
302
 
303
303
  text = cmark_node_get_literal(node);
304
304
  if (text == NULL) {
305
- rb_raise(rb_mNodeError, "could not get string content");
305
+ rb_raise(rb_eNodeError, "could not get string content");
306
306
  }
307
307
 
308
308
  return encode_utf8_string(text);
@@ -324,7 +324,7 @@ static VALUE rb_node_set_string_content(VALUE self, VALUE s) {
324
324
  text = StringValueCStr(s);
325
325
 
326
326
  if (!cmark_node_set_literal(node, text)) {
327
- rb_raise(rb_mNodeError, "could not set string content");
327
+ rb_raise(rb_eNodeError, "could not set string content");
328
328
  }
329
329
 
330
330
  return Qnil;
@@ -412,7 +412,7 @@ static VALUE rb_node_get_type(VALUE self) {
412
412
  s = node->extension->get_type_string_func(node->extension, node);
413
413
  return ID2SYM(rb_intern(s));
414
414
  }
415
- rb_raise(rb_mNodeError, "invalid node type %d", node_type);
415
+ rb_raise(rb_eNodeError, "invalid node type %d", node_type);
416
416
  }
417
417
 
418
418
  return symbol;
@@ -512,7 +512,7 @@ static VALUE rb_node_insert_before(VALUE self, VALUE sibling) {
512
512
  Data_Get_Struct(sibling, cmark_node, node2);
513
513
 
514
514
  if (!cmark_node_insert_before(node1, node2)) {
515
- rb_raise(rb_mNodeError, "could not insert before");
515
+ rb_raise(rb_eNodeError, "could not insert before");
516
516
  }
517
517
 
518
518
  rb_parent_added(sibling);
@@ -638,7 +638,7 @@ static VALUE rb_node_insert_after(VALUE self, VALUE sibling) {
638
638
  Data_Get_Struct(sibling, cmark_node, node2);
639
639
 
640
640
  if (!cmark_node_insert_after(node1, node2)) {
641
- rb_raise(rb_mNodeError, "could not insert after");
641
+ rb_raise(rb_eNodeError, "could not insert after");
642
642
  }
643
643
 
644
644
  rb_parent_added(sibling);
@@ -661,7 +661,7 @@ static VALUE rb_node_prepend_child(VALUE self, VALUE child) {
661
661
  Data_Get_Struct(child, cmark_node, node2);
662
662
 
663
663
  if (!cmark_node_prepend_child(node1, node2)) {
664
- rb_raise(rb_mNodeError, "could not prepend child");
664
+ rb_raise(rb_eNodeError, "could not prepend child");
665
665
  }
666
666
 
667
667
  rb_parent_added(child);
@@ -684,7 +684,7 @@ static VALUE rb_node_append_child(VALUE self, VALUE child) {
684
684
  Data_Get_Struct(child, cmark_node, node2);
685
685
 
686
686
  if (!cmark_node_append_child(node1, node2)) {
687
- rb_raise(rb_mNodeError, "could not append child");
687
+ rb_raise(rb_eNodeError, "could not append child");
688
688
  }
689
689
 
690
690
  rb_parent_added(child);
@@ -744,7 +744,7 @@ static VALUE rb_node_get_url(VALUE self) {
744
744
 
745
745
  text = cmark_node_get_url(node);
746
746
  if (text == NULL) {
747
- rb_raise(rb_mNodeError, "could not get url");
747
+ rb_raise(rb_eNodeError, "could not get url");
748
748
  }
749
749
 
750
750
  return rb_str_new2(text);
@@ -766,7 +766,7 @@ static VALUE rb_node_set_url(VALUE self, VALUE url) {
766
766
  text = StringValueCStr(url);
767
767
 
768
768
  if (!cmark_node_set_url(node, text)) {
769
- rb_raise(rb_mNodeError, "could not set url");
769
+ rb_raise(rb_eNodeError, "could not set url");
770
770
  }
771
771
 
772
772
  return Qnil;
@@ -785,7 +785,7 @@ static VALUE rb_node_get_title(VALUE self) {
785
785
 
786
786
  text = cmark_node_get_title(node);
787
787
  if (text == NULL) {
788
- rb_raise(rb_mNodeError, "could not get title");
788
+ rb_raise(rb_eNodeError, "could not get title");
789
789
  }
790
790
 
791
791
  return rb_str_new2(text);
@@ -807,7 +807,7 @@ static VALUE rb_node_set_title(VALUE self, VALUE title) {
807
807
  text = StringValueCStr(title);
808
808
 
809
809
  if (!cmark_node_set_title(node, text)) {
810
- rb_raise(rb_mNodeError, "could not set title");
810
+ rb_raise(rb_eNodeError, "could not set title");
811
811
  }
812
812
 
813
813
  return Qnil;
@@ -827,7 +827,7 @@ static VALUE rb_node_get_header_level(VALUE self) {
827
827
  header_level = cmark_node_get_header_level(node);
828
828
 
829
829
  if (header_level == 0) {
830
- rb_raise(rb_mNodeError, "could not get header_level");
830
+ rb_raise(rb_eNodeError, "could not get header_level");
831
831
  }
832
832
 
833
833
  return INT2NUM(header_level);
@@ -849,7 +849,7 @@ static VALUE rb_node_set_header_level(VALUE self, VALUE level) {
849
849
  l = FIX2INT(level);
850
850
 
851
851
  if (!cmark_node_set_header_level(node, l)) {
852
- rb_raise(rb_mNodeError, "could not set header_level");
852
+ rb_raise(rb_eNodeError, "could not set header_level");
853
853
  }
854
854
 
855
855
  return Qnil;
@@ -874,7 +874,7 @@ static VALUE rb_node_get_list_type(VALUE self) {
874
874
  } else if (list_type == CMARK_ORDERED_LIST) {
875
875
  symbol = sym_ordered_list;
876
876
  } else {
877
- rb_raise(rb_mNodeError, "could not get list_type");
877
+ rb_raise(rb_eNodeError, "could not get list_type");
878
878
  }
879
879
 
880
880
  return symbol;
@@ -899,11 +899,11 @@ static VALUE rb_node_set_list_type(VALUE self, VALUE list_type) {
899
899
  } else if (list_type == sym_ordered_list) {
900
900
  type = CMARK_ORDERED_LIST;
901
901
  } else {
902
- rb_raise(rb_mNodeError, "invalid list_type");
902
+ rb_raise(rb_eNodeError, "invalid list_type");
903
903
  }
904
904
 
905
905
  if (!cmark_node_set_list_type(node, type)) {
906
- rb_raise(rb_mNodeError, "could not set list_type");
906
+ rb_raise(rb_eNodeError, "could not set list_type");
907
907
  }
908
908
 
909
909
  return Qnil;
@@ -922,7 +922,7 @@ static VALUE rb_node_get_list_start(VALUE self) {
922
922
 
923
923
  if (cmark_node_get_type(node) != CMARK_NODE_LIST ||
924
924
  cmark_node_get_list_type(node) != CMARK_ORDERED_LIST) {
925
- rb_raise(rb_mNodeError, "can't get list_start for non-ordered list %d",
925
+ rb_raise(rb_eNodeError, "can't get list_start for non-ordered list %d",
926
926
  cmark_node_get_list_type(node));
927
927
  }
928
928
 
@@ -946,7 +946,7 @@ static VALUE rb_node_set_list_start(VALUE self, VALUE start) {
946
946
  s = FIX2INT(start);
947
947
 
948
948
  if (!cmark_node_set_list_start(node, s)) {
949
- rb_raise(rb_mNodeError, "could not set list_start");
949
+ rb_raise(rb_eNodeError, "could not set list_start");
950
950
  }
951
951
 
952
952
  return Qnil;
@@ -964,7 +964,7 @@ static VALUE rb_node_get_list_tight(VALUE self) {
964
964
  Data_Get_Struct(self, cmark_node, node);
965
965
 
966
966
  if (cmark_node_get_type(node) != CMARK_NODE_LIST) {
967
- rb_raise(rb_mNodeError, "can't get list_tight for non-list");
967
+ rb_raise(rb_eNodeError, "can't get list_tight for non-list");
968
968
  }
969
969
 
970
970
  flag = cmark_node_get_list_tight(node);
@@ -986,7 +986,7 @@ static VALUE rb_node_set_list_tight(VALUE self, VALUE tight) {
986
986
  t = RTEST(tight);
987
987
 
988
988
  if (!cmark_node_set_list_tight(node, t)) {
989
- rb_raise(rb_mNodeError, "could not set list_tight");
989
+ rb_raise(rb_eNodeError, "could not set list_tight");
990
990
  }
991
991
 
992
992
  return Qnil;
@@ -1006,7 +1006,7 @@ static VALUE rb_node_get_fence_info(VALUE self) {
1006
1006
  fence_info = cmark_node_get_fence_info(node);
1007
1007
 
1008
1008
  if (fence_info == NULL) {
1009
- rb_raise(rb_mNodeError, "could not get fence_info");
1009
+ rb_raise(rb_eNodeError, "could not get fence_info");
1010
1010
  }
1011
1011
 
1012
1012
  return rb_str_new2(fence_info);
@@ -1028,24 +1028,64 @@ static VALUE rb_node_set_fence_info(VALUE self, VALUE info) {
1028
1028
  text = StringValueCStr(info);
1029
1029
 
1030
1030
  if (!cmark_node_set_fence_info(node, text)) {
1031
- rb_raise(rb_mNodeError, "could not set fence_info");
1031
+ rb_raise(rb_eNodeError, "could not set fence_info");
1032
1032
  }
1033
1033
 
1034
1034
  return Qnil;
1035
1035
  }
1036
1036
 
1037
- static VALUE rb_node_get_tasklist_state(VALUE self) {
1038
- const char *tasklist_state;
1037
+ static VALUE rb_node_get_tasklist_item_checked(VALUE self) {
1038
+ int tasklist_state;
1039
+ cmark_node *node;
1040
+ Data_Get_Struct(self, cmark_node, node);
1041
+
1042
+ tasklist_state = cmark_gfm_extensions_get_tasklist_item_checked(node);
1043
+
1044
+ if (tasklist_state == 1) {
1045
+ return Qtrue;
1046
+ } else {
1047
+ return Qfalse;
1048
+ }
1049
+ }
1050
+
1051
+ /*
1052
+ * Public: Sets the checkbox state of the current node (must be a `:tasklist`).
1053
+ *
1054
+ * item_checked - A {Boolean} representing the new checkbox state
1055
+ *
1056
+ * Returns a {Boolean} representing the new checkbox state.
1057
+ * Raises a NodeError if the checkbox state can't be set.
1058
+ */
1059
+ static VALUE rb_node_set_tasklist_item_checked(VALUE self, VALUE item_checked) {
1060
+ int tasklist_state;
1039
1061
  cmark_node *node;
1040
1062
  Data_Get_Struct(self, cmark_node, node);
1063
+ tasklist_state = RTEST(item_checked);
1041
1064
 
1042
- tasklist_state = cmark_gfm_extensions_get_tasklist_state(node);
1065
+ if (!cmark_gfm_extensions_set_tasklist_item_checked(node, tasklist_state)) {
1066
+ rb_raise(rb_eNodeError, "could not set tasklist_item_checked");
1067
+ };
1043
1068
 
1044
- if (tasklist_state == NULL) {
1045
- rb_raise(rb_mNodeError, "could not get tasklist_state");
1069
+ if (tasklist_state) {
1070
+ return Qtrue;
1071
+ } else {
1072
+ return Qfalse;
1046
1073
  }
1074
+ }
1047
1075
 
1048
- return rb_str_new2(tasklist_state);
1076
+ // TODO: remove this, superseded by the above method
1077
+ static VALUE rb_node_get_tasklist_state(VALUE self) {
1078
+ int tasklist_state;
1079
+ cmark_node *node;
1080
+ Data_Get_Struct(self, cmark_node, node);
1081
+
1082
+ tasklist_state = cmark_gfm_extensions_get_tasklist_item_checked(node);
1083
+
1084
+ if (tasklist_state == 1) {
1085
+ return rb_str_new2("checked");
1086
+ } else {
1087
+ return rb_str_new2("unchecked");
1088
+ }
1049
1089
  }
1050
1090
 
1051
1091
  static VALUE rb_node_get_table_alignments(VALUE self) {
@@ -1059,7 +1099,7 @@ static VALUE rb_node_get_table_alignments(VALUE self) {
1059
1099
  alignments = cmark_gfm_extensions_get_table_alignments(node);
1060
1100
 
1061
1101
  if (!column_count || !alignments) {
1062
- rb_raise(rb_mNodeError, "could not get column_count or alignments");
1102
+ rb_raise(rb_eNodeError, "could not get column_count or alignments");
1063
1103
  }
1064
1104
 
1065
1105
  ary = rb_ary_new();
@@ -1164,49 +1204,51 @@ __attribute__((visibility("default"))) void Init_commonmarker() {
1164
1204
 
1165
1205
  module = rb_define_module("CommonMarker");
1166
1206
  rb_define_singleton_method(module, "extensions", rb_extensions, 0);
1167
- rb_mNodeError = rb_define_class_under(module, "NodeError", rb_eStandardError);
1168
- rb_mNode = rb_define_class_under(module, "Node", rb_cObject);
1169
- rb_define_singleton_method(rb_mNode, "markdown_to_html", rb_markdown_to_html,
1207
+ rb_eNodeError = rb_define_class_under(module, "NodeError", rb_eStandardError);
1208
+ rb_cNode = rb_define_class_under(module, "Node", rb_cObject);
1209
+ rb_define_singleton_method(rb_cNode, "markdown_to_html", rb_markdown_to_html,
1170
1210
  3);
1171
- rb_define_singleton_method(rb_mNode, "new", rb_node_new, 1);
1172
- rb_define_singleton_method(rb_mNode, "parse_document", rb_parse_document, 4);
1173
- rb_define_method(rb_mNode, "string_content", rb_node_get_string_content, 0);
1174
- rb_define_method(rb_mNode, "string_content=", rb_node_set_string_content, 1);
1175
- rb_define_method(rb_mNode, "type", rb_node_get_type, 0);
1176
- rb_define_method(rb_mNode, "type_string", rb_node_get_type_string, 0);
1177
- rb_define_method(rb_mNode, "sourcepos", rb_node_get_sourcepos, 0);
1178
- rb_define_method(rb_mNode, "delete", rb_node_unlink, 0);
1179
- rb_define_method(rb_mNode, "first_child", rb_node_first_child, 0);
1180
- rb_define_method(rb_mNode, "next", rb_node_next, 0);
1181
- rb_define_method(rb_mNode, "insert_before", rb_node_insert_before, 1);
1182
- rb_define_method(rb_mNode, "_render_html", rb_render_html, 2);
1183
- rb_define_method(rb_mNode, "_render_commonmark", rb_render_commonmark, -1);
1184
- rb_define_method(rb_mNode, "_render_plaintext", rb_render_plaintext, -1);
1185
- rb_define_method(rb_mNode, "insert_after", rb_node_insert_after, 1);
1186
- rb_define_method(rb_mNode, "prepend_child", rb_node_prepend_child, 1);
1187
- rb_define_method(rb_mNode, "append_child", rb_node_append_child, 1);
1188
- rb_define_method(rb_mNode, "last_child", rb_node_last_child, 0);
1189
- rb_define_method(rb_mNode, "parent", rb_node_parent, 0);
1190
- rb_define_method(rb_mNode, "previous", rb_node_previous, 0);
1191
- rb_define_method(rb_mNode, "url", rb_node_get_url, 0);
1192
- rb_define_method(rb_mNode, "url=", rb_node_set_url, 1);
1193
- rb_define_method(rb_mNode, "title", rb_node_get_title, 0);
1194
- rb_define_method(rb_mNode, "title=", rb_node_set_title, 1);
1195
- rb_define_method(rb_mNode, "header_level", rb_node_get_header_level, 0);
1196
- rb_define_method(rb_mNode, "header_level=", rb_node_set_header_level, 1);
1197
- rb_define_method(rb_mNode, "list_type", rb_node_get_list_type, 0);
1198
- rb_define_method(rb_mNode, "list_type=", rb_node_set_list_type, 1);
1199
- rb_define_method(rb_mNode, "list_start", rb_node_get_list_start, 0);
1200
- rb_define_method(rb_mNode, "list_start=", rb_node_set_list_start, 1);
1201
- rb_define_method(rb_mNode, "list_tight", rb_node_get_list_tight, 0);
1202
- rb_define_method(rb_mNode, "list_tight=", rb_node_set_list_tight, 1);
1203
- rb_define_method(rb_mNode, "fence_info", rb_node_get_fence_info, 0);
1204
- rb_define_method(rb_mNode, "fence_info=", rb_node_set_fence_info, 1);
1205
- rb_define_method(rb_mNode, "table_alignments", rb_node_get_table_alignments, 0);
1206
- rb_define_method(rb_mNode, "tasklist_state", rb_node_get_tasklist_state, 0);
1207
-
1208
- rb_define_method(rb_mNode, "html_escape_href", rb_html_escape_href, 1);
1209
- rb_define_method(rb_mNode, "html_escape_html", rb_html_escape_html, 1);
1211
+ rb_define_singleton_method(rb_cNode, "new", rb_node_new, 1);
1212
+ rb_define_singleton_method(rb_cNode, "parse_document", rb_parse_document, 4);
1213
+ rb_define_method(rb_cNode, "string_content", rb_node_get_string_content, 0);
1214
+ rb_define_method(rb_cNode, "string_content=", rb_node_set_string_content, 1);
1215
+ rb_define_method(rb_cNode, "type", rb_node_get_type, 0);
1216
+ rb_define_method(rb_cNode, "type_string", rb_node_get_type_string, 0);
1217
+ rb_define_method(rb_cNode, "sourcepos", rb_node_get_sourcepos, 0);
1218
+ rb_define_method(rb_cNode, "delete", rb_node_unlink, 0);
1219
+ rb_define_method(rb_cNode, "first_child", rb_node_first_child, 0);
1220
+ rb_define_method(rb_cNode, "next", rb_node_next, 0);
1221
+ rb_define_method(rb_cNode, "insert_before", rb_node_insert_before, 1);
1222
+ rb_define_method(rb_cNode, "_render_html", rb_render_html, 2);
1223
+ rb_define_method(rb_cNode, "_render_commonmark", rb_render_commonmark, -1);
1224
+ rb_define_method(rb_cNode, "_render_plaintext", rb_render_plaintext, -1);
1225
+ rb_define_method(rb_cNode, "insert_after", rb_node_insert_after, 1);
1226
+ rb_define_method(rb_cNode, "prepend_child", rb_node_prepend_child, 1);
1227
+ rb_define_method(rb_cNode, "append_child", rb_node_append_child, 1);
1228
+ rb_define_method(rb_cNode, "last_child", rb_node_last_child, 0);
1229
+ rb_define_method(rb_cNode, "parent", rb_node_parent, 0);
1230
+ rb_define_method(rb_cNode, "previous", rb_node_previous, 0);
1231
+ rb_define_method(rb_cNode, "url", rb_node_get_url, 0);
1232
+ rb_define_method(rb_cNode, "url=", rb_node_set_url, 1);
1233
+ rb_define_method(rb_cNode, "title", rb_node_get_title, 0);
1234
+ rb_define_method(rb_cNode, "title=", rb_node_set_title, 1);
1235
+ rb_define_method(rb_cNode, "header_level", rb_node_get_header_level, 0);
1236
+ rb_define_method(rb_cNode, "header_level=", rb_node_set_header_level, 1);
1237
+ rb_define_method(rb_cNode, "list_type", rb_node_get_list_type, 0);
1238
+ rb_define_method(rb_cNode, "list_type=", rb_node_set_list_type, 1);
1239
+ rb_define_method(rb_cNode, "list_start", rb_node_get_list_start, 0);
1240
+ rb_define_method(rb_cNode, "list_start=", rb_node_set_list_start, 1);
1241
+ rb_define_method(rb_cNode, "list_tight", rb_node_get_list_tight, 0);
1242
+ rb_define_method(rb_cNode, "list_tight=", rb_node_set_list_tight, 1);
1243
+ rb_define_method(rb_cNode, "fence_info", rb_node_get_fence_info, 0);
1244
+ rb_define_method(rb_cNode, "fence_info=", rb_node_set_fence_info, 1);
1245
+ rb_define_method(rb_cNode, "table_alignments", rb_node_get_table_alignments, 0);
1246
+ rb_define_method(rb_cNode, "tasklist_state", rb_node_get_tasklist_state, 0);
1247
+ rb_define_method(rb_cNode, "tasklist_item_checked?", rb_node_get_tasklist_item_checked, 0);
1248
+ rb_define_method(rb_cNode, "tasklist_item_checked=", rb_node_set_tasklist_item_checked, 1);
1249
+
1250
+ rb_define_method(rb_cNode, "html_escape_href", rb_html_escape_href, 1);
1251
+ rb_define_method(rb_cNode, "html_escape_html", rb_html_escape_html, 1);
1210
1252
 
1211
1253
  cmark_gfm_core_extensions_ensure_registered();
1212
1254
  }