commonmarker 0.17.7.1 → 0.18.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -17
  3. data/commonmarker.gemspec +1 -1
  4. data/ext/commonmarker/arena.c +2 -2
  5. data/ext/commonmarker/autolink.h +3 -3
  6. data/ext/commonmarker/blocks.c +21 -15
  7. data/ext/commonmarker/buffer.h +23 -23
  8. data/ext/commonmarker/chunk.h +1 -1
  9. data/ext/commonmarker/cmark-gfm-core-extensions.h +28 -0
  10. data/ext/commonmarker/{cmark_extension_api.h → cmark-gfm-extension_api.h} +86 -69
  11. data/ext/commonmarker/cmark-gfm-extensions_export.h +42 -0
  12. data/ext/commonmarker/{cmark.h → cmark-gfm.h} +118 -96
  13. data/ext/commonmarker/cmark-gfm_export.h +42 -0
  14. data/ext/commonmarker/cmark-gfm_version.h +7 -0
  15. data/ext/commonmarker/cmark.c +3 -3
  16. data/ext/commonmarker/cmark_ctype.h +6 -6
  17. data/ext/commonmarker/commonmark.c +8 -4
  18. data/ext/commonmarker/commonmarker.c +33 -15
  19. data/ext/commonmarker/commonmarker.h +1 -1
  20. data/ext/commonmarker/core-extensions.c +2 -2
  21. data/ext/commonmarker/ext_scanners.h +1 -1
  22. data/ext/commonmarker/footnotes.c +1 -1
  23. data/ext/commonmarker/houdini.h +6 -6
  24. data/ext/commonmarker/houdini_href_e.c +2 -2
  25. data/ext/commonmarker/html.c +15 -7
  26. data/ext/commonmarker/inlines.c +36 -5
  27. data/ext/commonmarker/inlines.h +1 -1
  28. data/ext/commonmarker/iterator.c +1 -1
  29. data/ext/commonmarker/iterator.h +1 -1
  30. data/ext/commonmarker/latex.c +1 -1
  31. data/ext/commonmarker/linked_list.c +1 -1
  32. data/ext/commonmarker/man.c +1 -1
  33. data/ext/commonmarker/node.c +17 -3
  34. data/ext/commonmarker/node.h +4 -4
  35. data/ext/commonmarker/plugin.h +2 -2
  36. data/ext/commonmarker/references.c +1 -1
  37. data/ext/commonmarker/registry.c +1 -1
  38. data/ext/commonmarker/registry.h +4 -4
  39. data/ext/commonmarker/render.c +1 -1
  40. data/ext/commonmarker/scanners.c +10550 -18051
  41. data/ext/commonmarker/scanners.h +1 -1
  42. data/ext/commonmarker/strikethrough.c +13 -3
  43. data/ext/commonmarker/strikethrough.h +3 -3
  44. data/ext/commonmarker/syntax_extension.c +11 -1
  45. data/ext/commonmarker/syntax_extension.h +4 -2
  46. data/ext/commonmarker/table.c +88 -9
  47. data/ext/commonmarker/table.h +7 -3
  48. data/ext/commonmarker/tagfilter.h +3 -3
  49. data/ext/commonmarker/utf8.h +6 -6
  50. data/ext/commonmarker/xml.c +10 -3
  51. data/lib/commonmarker/config.rb +4 -1
  52. data/lib/commonmarker/node.rb +6 -4
  53. data/lib/commonmarker/renderer/html_renderer.rb +12 -12
  54. data/lib/commonmarker/version.rb +1 -1
  55. data/test/test_extensions.rb +52 -1
  56. data/test/test_footnotes.rb +1 -1
  57. data/test/test_options.rb +35 -0
  58. data/test/test_spec.rb +4 -4
  59. metadata +12 -10
  60. data/ext/commonmarker/cmark_export.h +0 -42
  61. data/ext/commonmarker/cmark_version.h +0 -8
  62. data/ext/commonmarker/cmarkextensions_export.h +0 -42
  63. data/ext/commonmarker/core-extensions.h +0 -25
@@ -1,7 +1,7 @@
1
1
  #ifndef CMARK_SCANNERS_H
2
2
  #define CMARK_SCANNERS_H
3
3
 
4
- #include "cmark.h"
4
+ #include "cmark-gfm.h"
5
5
  #include "chunk.h"
6
6
 
7
7
  #ifdef __cplusplus
@@ -27,7 +27,8 @@ static cmark_node *match(cmark_syntax_extension *self, cmark_parser *parser,
27
27
  res->start_line = res->end_line = cmark_inline_parser_get_line(inline_parser);
28
28
  res->start_column = cmark_inline_parser_get_column(inline_parser) - delims;
29
29
 
30
- if (left_flanking || right_flanking) {
30
+ if ((left_flanking || right_flanking) &&
31
+ (delims == 2 || (!(parser->options & CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE) && delims == 1))) {
31
32
  cmark_inline_parser_push_delimiter(inline_parser, character, left_flanking,
32
33
  right_flanking, res);
33
34
  }
@@ -45,12 +46,14 @@ static delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser,
45
46
 
46
47
  strikethrough = opener->inl_text;
47
48
 
49
+ if (opener->inl_text->as.literal.len != closer->inl_text->as.literal.len)
50
+ goto done;
51
+
48
52
  if (!cmark_node_set_type(strikethrough, CMARK_NODE_STRIKETHROUGH))
49
53
  goto done;
50
54
 
51
55
  cmark_node_set_syntax_extension(strikethrough, self);
52
56
 
53
- cmark_node_set_string_content(strikethrough, "~");
54
57
  tmp = cmark_node_next(opener->inl_text);
55
58
 
56
59
  while (tmp) {
@@ -93,7 +96,7 @@ static int can_contain(cmark_syntax_extension *extension, cmark_node *node,
93
96
  static void commonmark_render(cmark_syntax_extension *extension,
94
97
  cmark_renderer *renderer, cmark_node *node,
95
98
  cmark_event_type ev_type, int options) {
96
- renderer->out(renderer, node, cmark_node_get_string_content(node), false, LITERAL);
99
+ renderer->out(renderer, node, "~~", false, LITERAL);
97
100
  }
98
101
 
99
102
  static void latex_render(cmark_syntax_extension *extension,
@@ -132,6 +135,12 @@ static void html_render(cmark_syntax_extension *extension,
132
135
  }
133
136
  }
134
137
 
138
+ static void plaintext_render(cmark_syntax_extension *extension,
139
+ cmark_renderer *renderer, cmark_node *node,
140
+ cmark_event_type ev_type, int options) {
141
+ renderer->out(renderer, node, "~", false, LITERAL);
142
+ }
143
+
135
144
  cmark_syntax_extension *create_strikethrough_extension(void) {
136
145
  cmark_syntax_extension *ext = cmark_syntax_extension_new("strikethrough");
137
146
  cmark_llist *special_chars = NULL;
@@ -142,6 +151,7 @@ cmark_syntax_extension *create_strikethrough_extension(void) {
142
151
  cmark_syntax_extension_set_latex_render_func(ext, latex_render);
143
152
  cmark_syntax_extension_set_man_render_func(ext, man_render);
144
153
  cmark_syntax_extension_set_html_render_func(ext, html_render);
154
+ cmark_syntax_extension_set_plaintext_render_func(ext, plaintext_render);
145
155
  CMARK_NODE_STRIKETHROUGH = cmark_syntax_extension_add_node(1);
146
156
 
147
157
  cmark_syntax_extension_set_match_inline_func(ext, match);
@@ -1,7 +1,7 @@
1
- #ifndef STRIKETHROUGH_H
2
- #define STRIKETHROUGH_H
1
+ #ifndef CMARK_GFM_STRIKETHROUGH_H
2
+ #define CMARK_GFM_STRIKETHROUGH_H
3
3
 
4
- #include "core-extensions.h"
4
+ #include "cmark-gfm-core-extensions.h"
5
5
 
6
6
  extern cmark_node_type CMARK_NODE_STRIKETHROUGH;
7
7
  cmark_syntax_extension *create_strikethrough_extension(void);
@@ -1,7 +1,7 @@
1
1
  #include <stdlib.h>
2
2
  #include <assert.h>
3
3
 
4
- #include "cmark.h"
4
+ #include "cmark-gfm.h"
5
5
  #include "syntax_extension.h"
6
6
  #include "buffer.h"
7
7
 
@@ -97,6 +97,11 @@ void cmark_syntax_extension_set_latex_render_func(cmark_syntax_extension *extens
97
97
  extension->latex_render_func = func;
98
98
  }
99
99
 
100
+ void cmark_syntax_extension_set_xml_attr_func(cmark_syntax_extension *extension,
101
+ cmark_xml_attr_func func) {
102
+ extension->xml_attr_func = func;
103
+ }
104
+
100
105
  void cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension,
101
106
  cmark_common_render_func func) {
102
107
  extension->man_render_func = func;
@@ -128,6 +133,11 @@ void *cmark_syntax_extension_get_private(cmark_syntax_extension *extension) {
128
133
  return extension->priv;
129
134
  }
130
135
 
136
+ void cmark_syntax_extension_set_opaque_alloc_func(cmark_syntax_extension *extension,
137
+ cmark_opaque_alloc_func func) {
138
+ extension->opaque_alloc_func = func;
139
+ }
140
+
131
141
  void cmark_syntax_extension_set_opaque_free_func(cmark_syntax_extension *extension,
132
142
  cmark_opaque_free_func func) {
133
143
  extension->opaque_free_func = func;
@@ -1,8 +1,8 @@
1
1
  #ifndef CMARK_SYNTAX_EXTENSION_H
2
2
  #define CMARK_SYNTAX_EXTENSION_H
3
3
 
4
- #include "cmark.h"
5
- #include "cmark_extension_api.h"
4
+ #include "cmark-gfm.h"
5
+ #include "cmark-gfm-extension_api.h"
6
6
  #include "config.h"
7
7
 
8
8
  struct cmark_syntax_extension {
@@ -21,10 +21,12 @@ struct cmark_syntax_extension {
21
21
  cmark_common_render_func commonmark_render_func;
22
22
  cmark_common_render_func plaintext_render_func;
23
23
  cmark_common_render_func latex_render_func;
24
+ cmark_xml_attr_func xml_attr_func;
24
25
  cmark_common_render_func man_render_func;
25
26
  cmark_html_render_func html_render_func;
26
27
  cmark_html_filter_func html_filter_func;
27
28
  cmark_postprocess_func postprocess_func;
29
+ cmark_opaque_alloc_func opaque_alloc_func;
28
30
  cmark_opaque_free_func opaque_free_func;
29
31
  cmark_commonmark_escape_func commonmark_escape_func;
30
32
  };
@@ -1,4 +1,4 @@
1
- #include <cmark_extension_api.h>
1
+ #include <cmark-gfm-extension_api.h>
2
2
  #include <html.h>
3
3
  #include <inlines.h>
4
4
  #include <parser.h>
@@ -9,6 +9,7 @@
9
9
  #include "ext_scanners.h"
10
10
  #include "strikethrough.h"
11
11
  #include "table.h"
12
+ #include "cmark-gfm-core-extensions.h"
12
13
 
13
14
  cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,
14
15
  CMARK_NODE_TABLE_CELL;
@@ -380,7 +381,8 @@ static int can_contain(cmark_syntax_extension *extension, cmark_node *node,
380
381
  child_type == CMARK_NODE_EMPH || child_type == CMARK_NODE_STRONG ||
381
382
  child_type == CMARK_NODE_LINK || child_type == CMARK_NODE_IMAGE ||
382
383
  child_type == CMARK_NODE_STRIKETHROUGH ||
383
- child_type == CMARK_NODE_HTML_INLINE;
384
+ child_type == CMARK_NODE_HTML_INLINE ||
385
+ child_type == CMARK_NODE_FOOTNOTE_REFERENCE;
384
386
  }
385
387
  return false;
386
388
  }
@@ -487,6 +489,27 @@ static void latex_render(cmark_syntax_extension *extension,
487
489
  }
488
490
  }
489
491
 
492
+ static const char *xml_attr(cmark_syntax_extension *extension,
493
+ cmark_node *node) {
494
+ if (node->type == CMARK_NODE_TABLE_CELL) {
495
+ if (cmark_gfm_extensions_get_table_row_is_header(node->parent)) {
496
+ uint8_t *alignments = get_table_alignments(node->parent->parent);
497
+ int i = 0;
498
+ cmark_node *n;
499
+ for (n = node->parent->first_child; n; n = n->next, ++i)
500
+ if (n == node)
501
+ break;
502
+ switch (alignments[i]) {
503
+ case 'l': return " align=\"left\"";
504
+ case 'c': return " align=\"center\"";
505
+ case 'r': return " align=\"right\"";
506
+ }
507
+ }
508
+ }
509
+
510
+ return NULL;
511
+ }
512
+
490
513
  static void man_render(cmark_syntax_extension *extension,
491
514
  cmark_renderer *renderer, cmark_node *node,
492
515
  cmark_event_type ev_type, int options) {
@@ -542,6 +565,18 @@ static void man_render(cmark_syntax_extension *extension,
542
565
  }
543
566
  }
544
567
 
568
+ static void html_table_add_align(cmark_strbuf* html, const char* align, int options) {
569
+ if (options & CMARK_OPT_TABLE_PREFER_STYLE_ATTRIBUTES) {
570
+ cmark_strbuf_puts(html, " style=\"text-align: ");
571
+ cmark_strbuf_puts(html, align);
572
+ cmark_strbuf_puts(html, "\"");
573
+ } else {
574
+ cmark_strbuf_puts(html, " align=\"");
575
+ cmark_strbuf_puts(html, align);
576
+ cmark_strbuf_puts(html, "\"");
577
+ }
578
+ }
579
+
545
580
  struct html_table_state {
546
581
  unsigned need_closing_table_body : 1;
547
582
  unsigned in_table_header : 1;
@@ -566,10 +601,15 @@ static void html_render(cmark_syntax_extension *extension,
566
601
  cmark_strbuf_putc(html, '>');
567
602
  table_state->need_closing_table_body = false;
568
603
  } else {
569
- if (table_state->need_closing_table_body)
604
+ if (table_state->need_closing_table_body) {
605
+ cmark_html_render_cr(html);
570
606
  cmark_strbuf_puts(html, "</tbody>");
607
+ cmark_html_render_cr(html);
608
+ }
571
609
  table_state->need_closing_table_body = false;
572
- cmark_strbuf_puts(html, "</table>\n");
610
+ cmark_html_render_cr(html);
611
+ cmark_strbuf_puts(html, "</table>");
612
+ cmark_html_render_cr(html);
573
613
  }
574
614
  } else if (node->type == CMARK_NODE_TABLE_ROW) {
575
615
  if (entering) {
@@ -611,9 +651,9 @@ static void html_render(cmark_syntax_extension *extension,
611
651
  break;
612
652
 
613
653
  switch (alignments[i]) {
614
- case 'l': cmark_strbuf_puts(html, " align=\"left\""); break;
615
- case 'c': cmark_strbuf_puts(html, " align=\"center\""); break;
616
- case 'r': cmark_strbuf_puts(html, " align=\"right\""); break;
654
+ case 'l': html_table_add_align(html, "left", options); break;
655
+ case 'c': html_table_add_align(html, "center", options); break;
656
+ case 'r': html_table_add_align(html, "right", options); break;
617
657
  }
618
658
 
619
659
  cmark_html_render_sourcepos(node, html, options);
@@ -630,6 +670,16 @@ static void html_render(cmark_syntax_extension *extension,
630
670
  }
631
671
  }
632
672
 
673
+ static void opaque_alloc(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) {
674
+ if (node->type == CMARK_NODE_TABLE) {
675
+ node->as.opaque = mem->calloc(1, sizeof(node_table));
676
+ } else if (node->type == CMARK_NODE_TABLE_ROW) {
677
+ node->as.opaque = mem->calloc(1, sizeof(node_table_row));
678
+ } else if (node->type == CMARK_NODE_TABLE_CELL) {
679
+ node->as.opaque = mem->calloc(1, sizeof(node_cell));
680
+ }
681
+ }
682
+
633
683
  static void opaque_free(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) {
634
684
  if (node->type == CMARK_NODE_TABLE) {
635
685
  free_node_table(mem, node->as.opaque);
@@ -657,8 +707,10 @@ cmark_syntax_extension *create_table_extension(void) {
657
707
  cmark_syntax_extension_set_commonmark_render_func(self, commonmark_render);
658
708
  cmark_syntax_extension_set_plaintext_render_func(self, commonmark_render);
659
709
  cmark_syntax_extension_set_latex_render_func(self, latex_render);
710
+ cmark_syntax_extension_set_xml_attr_func(self, xml_attr);
660
711
  cmark_syntax_extension_set_man_render_func(self, man_render);
661
712
  cmark_syntax_extension_set_html_render_func(self, html_render);
713
+ cmark_syntax_extension_set_opaque_alloc_func(self, opaque_alloc);
662
714
  cmark_syntax_extension_set_opaque_free_func(self, opaque_free);
663
715
  cmark_syntax_extension_set_commonmark_escape_func(self, escape);
664
716
  CMARK_NODE_TABLE = cmark_syntax_extension_add_node(0);
@@ -668,16 +720,43 @@ cmark_syntax_extension *create_table_extension(void) {
668
720
  return self;
669
721
  }
670
722
 
671
- uint16_t cmarkextensions_get_table_columns(cmark_node *node) {
723
+ uint16_t cmark_gfm_extensions_get_table_columns(cmark_node *node) {
672
724
  if (node->type != CMARK_NODE_TABLE)
673
725
  return 0;
674
726
 
675
727
  return ((node_table *)node->as.opaque)->n_columns;
676
728
  }
677
729
 
678
- uint8_t *cmarkextensions_get_table_alignments(cmark_node *node) {
730
+ uint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node) {
679
731
  if (node->type != CMARK_NODE_TABLE)
680
732
  return 0;
681
733
 
682
734
  return ((node_table *)node->as.opaque)->alignments;
683
735
  }
736
+
737
+ int cmark_gfm_extensions_set_table_columns(cmark_node *node, uint16_t n_columns) {
738
+ return set_n_table_columns(node, n_columns);
739
+ }
740
+
741
+ int cmark_gfm_extensions_set_table_alignments(cmark_node *node, uint16_t ncols, uint8_t *alignments) {
742
+ uint8_t *a = (uint8_t *)cmark_node_mem(node)->calloc(1, ncols);
743
+ memcpy(a, alignments, ncols);
744
+ return set_table_alignments(node, a);
745
+ }
746
+
747
+ int cmark_gfm_extensions_get_table_row_is_header(cmark_node *node)
748
+ {
749
+ if (!node || node->type != CMARK_NODE_TABLE_ROW)
750
+ return 0;
751
+
752
+ return ((node_table_row *)node->as.opaque)->is_header;
753
+ }
754
+
755
+ int cmark_gfm_extensions_set_table_row_is_header(cmark_node *node, int is_header)
756
+ {
757
+ if (!node || node->type != CMARK_NODE_TABLE_ROW)
758
+ return 0;
759
+
760
+ ((node_table_row *)node->as.opaque)->is_header = (is_header != 0);
761
+ return 1;
762
+ }
@@ -1,7 +1,11 @@
1
- #ifndef TABLE_H
2
- #define TABLE_H
1
+ #ifndef CMARK_GFM_TABLE_H
2
+ #define CMARK_GFM_TABLE_H
3
3
 
4
- #include "core-extensions.h"
4
+ #include "cmark-gfm-core-extensions.h"
5
+
6
+
7
+ extern cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,
8
+ CMARK_NODE_TABLE_CELL;
5
9
 
6
10
  cmark_syntax_extension *create_table_extension(void);
7
11
 
@@ -1,7 +1,7 @@
1
- #ifndef TAGFILTER_H
2
- #define TAGFILTER_H
1
+ #ifndef CMARK_GFM_TAGFILTER_H
2
+ #define CMARK_GFM_TAGFILTER_H
3
3
 
4
- #include "core-extensions.h"
4
+ #include "cmark-gfm-core-extensions.h"
5
5
 
6
6
  cmark_syntax_extension *create_tagfilter_extension(void);
7
7
 
@@ -8,24 +8,24 @@
8
8
  extern "C" {
9
9
  #endif
10
10
 
11
- CMARK_EXPORT
11
+ CMARK_GFM_EXPORT
12
12
  void cmark_utf8proc_case_fold(cmark_strbuf *dest, const uint8_t *str,
13
13
  bufsize_t len);
14
14
 
15
- CMARK_EXPORT
15
+ CMARK_GFM_EXPORT
16
16
  void cmark_utf8proc_encode_char(int32_t uc, cmark_strbuf *buf);
17
17
 
18
- CMARK_EXPORT
18
+ CMARK_GFM_EXPORT
19
19
  int cmark_utf8proc_iterate(const uint8_t *str, bufsize_t str_len, int32_t *dst);
20
20
 
21
- CMARK_EXPORT
21
+ CMARK_GFM_EXPORT
22
22
  void cmark_utf8proc_check(cmark_strbuf *dest, const uint8_t *line,
23
23
  bufsize_t size);
24
24
 
25
- CMARK_EXPORT
25
+ CMARK_GFM_EXPORT
26
26
  int cmark_utf8proc_is_space(int32_t uc);
27
27
 
28
- CMARK_EXPORT
28
+ CMARK_GFM_EXPORT
29
29
  int cmark_utf8proc_is_punctuation(int32_t uc);
30
30
 
31
31
  #ifdef __cplusplus
@@ -4,10 +4,11 @@
4
4
  #include <assert.h>
5
5
 
6
6
  #include "config.h"
7
- #include "cmark.h"
7
+ #include "cmark-gfm.h"
8
8
  #include "node.h"
9
9
  #include "buffer.h"
10
10
  #include "houdini.h"
11
+ #include "syntax_extension.h"
11
12
 
12
13
  #define BUFFER_SIZE 100
13
14
 
@@ -50,6 +51,12 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
50
51
  cmark_strbuf_puts(xml, buffer);
51
52
  }
52
53
 
54
+ if (node->extension && node->extension->xml_attr_func) {
55
+ const char* r = node->extension->xml_attr_func(node->extension, node);
56
+ if (r != NULL)
57
+ cmark_strbuf_puts(xml, r);
58
+ }
59
+
53
60
  literal = false;
54
61
 
55
62
  switch (node->type) {
@@ -60,7 +67,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
60
67
  case CMARK_NODE_CODE:
61
68
  case CMARK_NODE_HTML_BLOCK:
62
69
  case CMARK_NODE_HTML_INLINE:
63
- cmark_strbuf_puts(xml, ">");
70
+ cmark_strbuf_puts(xml, " xml:space=\"preserve\">");
64
71
  escape_xml(xml, node->as.literal.data, node->as.literal.len);
65
72
  cmark_strbuf_puts(xml, "</");
66
73
  cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
@@ -100,7 +107,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
100
107
  escape_xml(xml, node->as.code.info.data, node->as.code.info.len);
101
108
  cmark_strbuf_putc(xml, '"');
102
109
  }
103
- cmark_strbuf_puts(xml, ">");
110
+ cmark_strbuf_puts(xml, " xml:space=\"preserve\">");
104
111
  escape_xml(xml, node->as.code.literal.data, node->as.code.literal.len);
105
112
  cmark_strbuf_puts(xml, "</");
106
113
  cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
@@ -10,6 +10,7 @@ module CommonMarker
10
10
  define :SMART, (1 << 10)
11
11
  define :LIBERAL_HTML_TAG, (1 << 12)
12
12
  define :FOOTNOTES, (1 << 13)
13
+ define :STRIKETHROUGH_DOUBLE_TILDE, (1 << 14)
13
14
  end
14
15
 
15
16
  class Render
@@ -18,9 +19,11 @@ module CommonMarker
18
19
  define :DEFAULT, 0
19
20
  define :SOURCEPOS, (1 << 1)
20
21
  define :HARDBREAKS, (1 << 2)
21
- define :SAFE, (1 << 3)
22
+ define :UNSAFE, (1 << 17)
22
23
  define :NOBREAKS, (1 << 4)
23
24
  define :GITHUB_PRE_LANG, (1 << 11)
25
+ define :TABLE_PREFER_STYLE_ATTRIBUTES, (1 << 15)
26
+ define :FULL_INFO_STRING, (1 << 16)
24
27
  end
25
28
 
26
29
  def self.process_options(option, type)
@@ -31,21 +31,23 @@ module CommonMarker
31
31
  # Public: Convert the node to a CommonMark string.
32
32
  #
33
33
  # options - A {Symbol} or {Array of Symbol}s indicating the render options
34
+ # width - Column to wrap the output at
34
35
  #
35
36
  # Returns a {String}.
36
- def to_commonmark(options = :DEFAULT)
37
+ def to_commonmark(options = :DEFAULT, width = 120)
37
38
  opts = Config.process_options(options, :render)
38
- _render_commonmark(opts).force_encoding('utf-8')
39
+ _render_commonmark(opts, width).force_encoding('utf-8')
39
40
  end
40
41
 
41
42
  # Public: Convert the node to a plain text string.
42
43
  #
43
44
  # options - A {Symbol} or {Array of Symbol}s indicating the render options
45
+ # width - Column to wrap the output at
44
46
  #
45
47
  # Returns a {String}.
46
- def to_plaintext(options = :DEFAULT)
48
+ def to_plaintext(options = :DEFAULT, width = 120)
47
49
  opts = Config.process_options(options, :render)
48
- _render_plaintext(opts).force_encoding('utf-8')
50
+ _render_plaintext(opts, width).force_encoding('utf-8')
49
51
  end
50
52
 
51
53
  # Public: Iterate over the children (if any) of the current pointer.
@@ -103,19 +103,19 @@ module CommonMarker
103
103
 
104
104
  def html(node)
105
105
  block do
106
- if option_enabled?(:SAFE)
107
- out('<!-- raw HTML omitted -->')
108
- else
106
+ if option_enabled?(:UNSAFE)
109
107
  out(tagfilter(node.string_content))
108
+ else
109
+ out('<!-- raw HTML omitted -->')
110
110
  end
111
111
  end
112
112
  end
113
113
 
114
114
  def inline_html(node)
115
- if option_enabled?(:SAFE)
116
- out('<!-- raw HTML omitted -->')
117
- else
115
+ if option_enabled?(:UNSAFE)
118
116
  out(tagfilter(node.string_content))
117
+ else
118
+ out('<!-- raw HTML omitted -->')
119
119
  end
120
120
  end
121
121
 
@@ -174,7 +174,7 @@ module CommonMarker
174
174
  @alignments = node.table_alignments
175
175
  @needs_close_tbody = false
176
176
  out("<table#{sourcepos(node)}>\n", :children)
177
- out("</tbody>") if @needs_close_tbody
177
+ out("</tbody>\n") if @needs_close_tbody
178
178
  out("</table>\n")
179
179
  end
180
180
 
@@ -182,7 +182,7 @@ module CommonMarker
182
182
  @column_index = 0
183
183
 
184
184
  @in_header = true
185
- out("<thead>\n<tr#{sourcepos(node)}>", :children, "\n</tr>\n</thead>")
185
+ out("<thead>\n<tr#{sourcepos(node)}>\n", :children, "</tr>\n</thead>\n")
186
186
  @in_header = false
187
187
  end
188
188
 
@@ -190,9 +190,9 @@ module CommonMarker
190
190
  @column_index = 0
191
191
  if !@in_header && !@needs_close_tbody
192
192
  @needs_close_tbody = true
193
- out("\n<tbody>")
193
+ out("<tbody>\n")
194
194
  end
195
- out("\n<tr#{sourcepos(node)}>", :children, "\n</tr>")
195
+ out("<tr#{sourcepos(node)}>\n", :children, "</tr>\n")
196
196
  end
197
197
 
198
198
  def table_cell(node)
@@ -202,7 +202,7 @@ module CommonMarker
202
202
  when :center; ' align="center"'
203
203
  else; ''
204
204
  end
205
- out(@in_header ? "\n<th#{align}#{sourcepos(node)}>" : "\n<td#{align}#{sourcepos(node)}>", :children, @in_header ? "</th>" : "</td>")
205
+ out(@in_header ? "<th#{align}#{sourcepos(node)}>" : "<td#{align}#{sourcepos(node)}>", :children, @in_header ? "</th>\n" : "</td>\n")
206
206
  @column_index += 1
207
207
  end
208
208
 
@@ -211,7 +211,7 @@ module CommonMarker
211
211
  end
212
212
 
213
213
  def footnote_reference(node)
214
- out("<sup class=\"footnote-ref\"><a href=\"#fn#{node.string_content}\" id=\"fnref#{node.string_content}\">[#{node.string_content}]</a></sup>")
214
+ out("<sup class=\"footnote-ref\"><a href=\"#fn#{node.string_content}\" id=\"fnref#{node.string_content}\">#{node.string_content}</a></sup>")
215
215
  end
216
216
 
217
217
  def footnote_definition(_)
@@ -1,3 +1,3 @@
1
1
  module CommonMarker
2
- VERSION = '0.17.7.1'.freeze
2
+ VERSION = '0.18.0'.freeze
3
3
  end
@@ -35,6 +35,9 @@ Another extension:
35
35
  assert out.include?("<del>hi</del>")
36
36
  end
37
37
 
38
+ doc = CommonMarker.render_doc("~a~ ~~b~~ ~~~c~~~", :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])
39
+ assert_equal doc.to_html, "<p>~a~ <del>b</del> ~~~c~~~</p>\n"
40
+
38
41
  CommonMarker.render_html(@markdown, :DEFAULT, %i[table strikethrough]).tap do |out|
39
42
  refute out.include?("| a")
40
43
  refute out.include?("| <strong>x</strong>")
@@ -57,6 +60,9 @@ Another extension:
57
60
  %w(<table> <tr> <th> a </th> <td> c </td> <strong>x</strong>).each {|html| assert out.include?(html) }
58
61
  assert out.include?("~~hi~~")
59
62
  end
63
+
64
+ doc = CommonMarker.render_doc("~a~ ~~b~~ ~~~c~~~", :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])
65
+ assert_equal HtmlRenderer.new.render(doc), "<p>~a~ <del>b</del> ~~~c~~~</p>\n"
60
66
  end
61
67
 
62
68
  def test_bad_extension_specifications
@@ -67,6 +73,51 @@ Another extension:
67
73
 
68
74
  def test_comments_are_kept_as_expected
69
75
  assert_equal "<!--hello--> <blah> &lt;xmp>\n",
70
- CommonMarker.render_html("<!--hello--> <blah> <xmp>\n", :DEFAULT, %i[tagfilter])
76
+ CommonMarker.render_html("<!--hello--> <blah> <xmp>\n", :UNSAFE, %i[tagfilter])
77
+ end
78
+
79
+ def test_table_prefer_style_attributes
80
+ assert_equal(<<-HTML, CommonMarker.render_html(<<-MD, :TABLE_PREFER_STYLE_ATTRIBUTES, %i[table]))
81
+ <table>
82
+ <thead>
83
+ <tr>
84
+ <th style="text-align: left">aaa</th>
85
+ <th>bbb</th>
86
+ <th style="text-align: center">ccc</th>
87
+ <th>ddd</th>
88
+ <th style="text-align: right">eee</th>
89
+ </tr>
90
+ </thead>
91
+ <tbody>
92
+ <tr>
93
+ <td style="text-align: left">fff</td>
94
+ <td>ggg</td>
95
+ <td style="text-align: center">hhh</td>
96
+ <td>iii</td>
97
+ <td style="text-align: right">jjj</td>
98
+ </tr>
99
+ </tbody>
100
+ </table>
101
+ HTML
102
+ aaa | bbb | ccc | ddd | eee
103
+ :-- | --- | :-: | --- | --:
104
+ fff | ggg | hhh | iii | jjj
105
+ MD
106
+ end
107
+
108
+ def test_plaintext
109
+ assert_equal(<<-HTML, CommonMarker.render_doc(<<-MD, :DEFAULT, %i[table strikethrough]).to_plaintext)
110
+ Hello ~there~.
111
+
112
+ | a |
113
+ | --- |
114
+ | b |
115
+ HTML
116
+ Hello ~~there~~.
117
+
118
+ | a |
119
+ | - |
120
+ | b |
121
+ MD
71
122
  end
72
123
  end
@@ -4,7 +4,7 @@ class TestFootnotes < Minitest::Test
4
4
  def setup
5
5
  @doc = CommonMarker.render_doc("Hello[^hi].\n\n[^hi]: Hey!\n", :FOOTNOTES)
6
6
  @expected = <<-HTML
7
- <p>Hello<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>.</p>
7
+ <p>Hello<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup>.</p>
8
8
  <section class="footnotes">
9
9
  <ol>
10
10
  <li id="fn1">
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ class TestExtensions < Minitest::Test
4
+ def test_full_info_string
5
+ md = <<-MD
6
+ ```ruby
7
+ module Foo
8
+ ```
9
+ MD
10
+
11
+ CommonMarker.render_html(md, :FULL_INFO_STRING).tap do |out|
12
+ assert_includes out, %q(<pre><code class="language-ruby">)
13
+ end
14
+
15
+ md = <<-MD
16
+ ```ruby my info string
17
+ module Foo
18
+ ```
19
+ MD
20
+
21
+ CommonMarker.render_html(md, :FULL_INFO_STRING).tap do |out|
22
+ assert_includes out, %q(<pre><code class="language-ruby" data-meta="my info string">)
23
+ end
24
+
25
+ md = <<-MD
26
+ ```ruby my \x00 string
27
+ module Foo
28
+ ```
29
+ MD
30
+
31
+ CommonMarker.render_html(md, :FULL_INFO_STRING).tap do |out|
32
+ assert_includes out, %Q(<pre><code class="language-ruby" data-meta="my � string">)
33
+ end
34
+ end
35
+ end