commonmarker 0.17.13 → 0.18.0

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6f11a40dfa6f3039bd560b2845c835d884f48351
4
- data.tar.gz: 1137f49d8b7e1689e8b433e57f381617f51a97df
3
+ metadata.gz: 11d4791ae4e26e529efbad366fef1bf1b0354caa
4
+ data.tar.gz: 67dec1b64e22464e2b5fce687171ae338a80221f
5
5
  SHA512:
6
- metadata.gz: a58dee4e21d3b6b982f92075a3a9a6e5ac636ecd4babab6208074e8ff56b42b132ea99ef1f425368db14c4081bc53a0ac8d16c756463e0249041498c65f1faee
7
- data.tar.gz: 7f5b3476d7359b9d03b5352b6660ef269f54968b76440a74c02ef2feb93b495264ae0cc1e90bde520ee12fd035ff92e094b64180b841efe6edebf01ba69083ab
6
+ metadata.gz: 77749bbebb465097693ce23e1436f38cdc9995389d3527b5e52fe0f1ef37cafd4438416c2d60ebf7863d4d3713f580244fd7f0aa8c3f718d9f7ebb5baf20630d
7
+ data.tar.gz: 40ef8944199e42c68b7a61aa4d667778d555ad83502267b768e1d8c9424a8d9302e85ca68fe92c99b76fdf37d66afb05b093986792ed933973ac00a94bb20e0b
data/README.md CHANGED
@@ -146,7 +146,7 @@ CommonMarker accepts the same options that CMark does, as symbols. Note that the
146
146
  | `:GITHUB_PRE_LANG` | Use GitHub-style `<pre lang>` for fenced code blocks. |
147
147
  | `:HARDBREAKS` | Treat `\n` as hardbreaks (by adding `<br/>`). |
148
148
  | `:NOBREAKS` | Translate `\n` in the source to a single whitespace. |
149
- | `:SAFE` | Suppress raw HTML and unsafe links. |
149
+ | `:UNSAFE` | Allow raw HTML and unsafe links. |
150
150
  | `:SOURCEPOS` | Include source position in rendered HTML. |
151
151
  | `:TABLE_PREFER_STYLE_ATTRIBUTES` | Use `style` insted of `align` for table cells |
152
152
  | `:FULL_INFO_STRING` | Include full info strings of code blocks in separate attribute |
@@ -177,7 +177,7 @@ The available extensions are:
177
177
  * `:table` - This provides support for tables.
178
178
  * `:strikethrough` - This provides support for strikethroughs.
179
179
  * `:autolink` - This provides support for automatically converting URLs to anchor tags.
180
- * `:tagfilter` - This strips out [several "unsafe" HTML tags](https://github.github.com/gfm/#disallowed-raw-html-extension-) from being used.
180
+ * `:tagfilter` - This escapes [several "unsafe" HTML tags](https://github.github.com/gfm/#disallowed-raw-html-extension-), causing them to not have any effect.
181
181
 
182
182
  ## Developing locally
183
183
 
@@ -18,6 +18,9 @@ uint16_t cmark_gfm_extensions_get_table_columns(cmark_node *node);
18
18
  CMARK_GFM_EXTENSIONS_EXPORT
19
19
  uint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node);
20
20
 
21
+ CMARK_GFM_EXTENSIONS_EXPORT
22
+ int cmark_gfm_extensions_get_table_row_is_header(cmark_node *node);
23
+
21
24
  #ifdef __cplusplus
22
25
  }
23
26
  #endif
@@ -106,8 +106,6 @@ typedef struct cmark_plugin cmark_plugin;
106
106
  * with 'cmark_syntax_extension_set_private',
107
107
  * and optionally define a free function for this data.
108
108
  */
109
- typedef struct cmark_syntax_extension cmark_syntax_extension;
110
-
111
109
  typedef struct subject cmark_inline_parser;
112
110
 
113
111
  /** Exposed raw for now */
@@ -238,6 +236,9 @@ typedef int (*cmark_commonmark_escape_func) (cmark_syntax_extension *extension,
238
236
  cmark_node *node,
239
237
  int c);
240
238
 
239
+ typedef const char* (*cmark_xml_attr_func) (cmark_syntax_extension *extension,
240
+ cmark_node *node);
241
+
241
242
  typedef void (*cmark_html_render_func) (cmark_syntax_extension *extension,
242
243
  struct cmark_html_renderer *renderer,
243
244
  cmark_node *node,
@@ -254,6 +255,10 @@ typedef cmark_node *(*cmark_postprocess_func) (cmark_syntax_extension *extension
254
255
 
255
256
  typedef int (*cmark_ispunct_func) (char c);
256
257
 
258
+ typedef void (*cmark_opaque_alloc_func) (cmark_syntax_extension *extension,
259
+ cmark_mem *mem,
260
+ cmark_node *node);
261
+
257
262
  typedef void (*cmark_opaque_free_func) (cmark_syntax_extension *extension,
258
263
  cmark_mem *mem,
259
264
  cmark_node *node);
@@ -343,6 +348,12 @@ void cmark_syntax_extension_set_latex_render_func(cmark_syntax_extension *extens
343
348
  /** See the documentation for 'cmark_syntax_extension'
344
349
  */
345
350
  CMARK_GFM_EXPORT
351
+ void cmark_syntax_extension_set_xml_attr_func(cmark_syntax_extension *extension,
352
+ cmark_xml_attr_func func);
353
+
354
+ /** See the documentation for 'cmark_syntax_extension'
355
+ */
356
+ CMARK_GFM_EXPORT
346
357
  void cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension,
347
358
  cmark_common_render_func func);
348
359
 
@@ -382,6 +393,12 @@ CMARK_GFM_EXPORT
382
393
  void cmark_syntax_extension_set_postprocess_func(cmark_syntax_extension *extension,
383
394
  cmark_postprocess_func func);
384
395
 
396
+ /** See the documentation for 'cmark_syntax_extension'
397
+ */
398
+ CMARK_GFM_EXPORT
399
+ void cmark_syntax_extension_set_opaque_alloc_func(cmark_syntax_extension *extension,
400
+ cmark_opaque_alloc_func func);
401
+
385
402
  /** See the documentation for 'cmark_syntax_extension'
386
403
  */
387
404
  CMARK_GFM_EXPORT
@@ -92,6 +92,7 @@ typedef enum {
92
92
  typedef struct cmark_node cmark_node;
93
93
  typedef struct cmark_parser cmark_parser;
94
94
  typedef struct cmark_iter cmark_iter;
95
+ typedef struct cmark_syntax_extension cmark_syntax_extension;
95
96
 
96
97
  /**
97
98
  * ## Custom memory allocator support
@@ -187,6 +188,13 @@ CMARK_GFM_EXPORT cmark_node *cmark_node_new(cmark_node_type type);
187
188
  CMARK_GFM_EXPORT cmark_node *cmark_node_new_with_mem(cmark_node_type type,
188
189
  cmark_mem *mem);
189
190
 
191
+ CMARK_GFM_EXPORT cmark_node *cmark_node_new_with_ext(cmark_node_type type,
192
+ cmark_syntax_extension *extension);
193
+
194
+ CMARK_GFM_EXPORT cmark_node *cmark_node_new_with_mem_and_ext(cmark_node_type type,
195
+ cmark_mem *mem,
196
+ cmark_syntax_extension *extension);
197
+
190
198
  /** Frees the memory allocated for a node and any children.
191
199
  */
192
200
  CMARK_GFM_EXPORT void cmark_node_free(cmark_node *node);
@@ -682,14 +690,6 @@ char *cmark_render_latex_with_mem(cmark_node *root, int options, int width, cmar
682
690
  */
683
691
  #define CMARK_OPT_HARDBREAKS (1 << 2)
684
692
 
685
- /** Suppress raw HTML and unsafe links (`javascript:`, `vbscript:`,
686
- * `file:`, and `data:`, except for `image/png`, `image/gif`,
687
- * `image/jpeg`, or `image/webp` mime types). Raw HTML is replaced
688
- * by a placeholder HTML comment. Unsafe links are replaced by
689
- * empty strings.
690
- */
691
- #define CMARK_OPT_SAFE (1 << 3)
692
-
693
693
  /** Render `softbreak` elements as spaces.
694
694
  */
695
695
  #define CMARK_OPT_NOBREAKS (1 << 4)
@@ -738,6 +738,14 @@ char *cmark_render_latex_with_mem(cmark_node *root, int options, int width, cmar
738
738
  */
739
739
  #define CMARK_OPT_FULL_INFO_STRING (1 << 16)
740
740
 
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
+
741
749
  /**
742
750
  * ## Version information
743
751
  */
@@ -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) | 16)
5
- #define CMARK_GFM_VERSION_STRING "0.28.3.gfm.16"
4
+ #define CMARK_GFM_VERSION ((0 << 24) | (28 << 16) | (3 << 8) | 18)
5
+ #define CMARK_GFM_VERSION_STRING "0.28.3.gfm.18"
6
6
 
7
7
  #endif
@@ -168,6 +168,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
168
168
  int list_number;
169
169
  cmark_delim_type list_delim;
170
170
  int numticks;
171
+ bool extra_spaces;
171
172
  int i;
172
173
  bool entering = (ev_type == CMARK_EVENT_ENTER);
173
174
  const char *info, *code, *title;
@@ -369,14 +370,17 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
369
370
  code = cmark_node_get_literal(node);
370
371
  code_len = strlen(code);
371
372
  numticks = shortest_unused_backtick_sequence(code);
373
+ extra_spaces = code_len == 0 ||
374
+ code[0] == '`' || code[code_len - 1] == '`' ||
375
+ code[0] == ' ' || code[code_len - 1] == ' ';
372
376
  for (i = 0; i < numticks; i++) {
373
377
  LIT("`");
374
378
  }
375
- if (code_len == 0 || code[0] == '`') {
379
+ if (extra_spaces) {
376
380
  LIT(" ");
377
381
  }
378
382
  OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);
379
- if (code_len == 0 || code[code_len - 1] == '`') {
383
+ if (extra_spaces) {
380
384
  LIT(" ");
381
385
  }
382
386
  for (i = 0; i < numticks; i++) {
@@ -227,7 +227,7 @@ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
227
227
 
228
228
  case CMARK_NODE_HTML_BLOCK:
229
229
  cmark_html_render_cr(html);
230
- if (options & CMARK_OPT_SAFE) {
230
+ if (!(options & CMARK_OPT_UNSAFE)) {
231
231
  cmark_strbuf_puts(html, "<!-- raw HTML omitted -->");
232
232
  } else if (renderer->filter_extensions) {
233
233
  filter_html_block(renderer, node->as.literal.data, node->as.literal.len);
@@ -305,7 +305,7 @@ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
305
305
  break;
306
306
 
307
307
  case CMARK_NODE_HTML_INLINE:
308
- if (options & CMARK_OPT_SAFE) {
308
+ if (!(options & CMARK_OPT_UNSAFE)) {
309
309
  cmark_strbuf_puts(html, "<!-- raw HTML omitted -->");
310
310
  } else {
311
311
  filtered = false;
@@ -354,7 +354,7 @@ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
354
354
  case CMARK_NODE_LINK:
355
355
  if (entering) {
356
356
  cmark_strbuf_puts(html, "<a href=\"");
357
- if (!((options & CMARK_OPT_SAFE) &&
357
+ if (!(!(options & CMARK_OPT_UNSAFE) &&
358
358
  scan_dangerous_url(&node->as.link.url, 0))) {
359
359
  houdini_escape_href(html, node->as.link.url.data,
360
360
  node->as.link.url.len);
@@ -372,7 +372,7 @@ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
372
372
  case CMARK_NODE_IMAGE:
373
373
  if (entering) {
374
374
  cmark_strbuf_puts(html, "<img src=\"");
375
- if (!((options & CMARK_OPT_SAFE) &&
375
+ if (!(!(options & CMARK_OPT_UNSAFE) &&
376
376
  scan_dangerous_url(&node->as.link.url, 0))) {
377
377
  houdini_escape_href(html, node->as.link.url.data,
378
378
  node->as.link.url.len);
@@ -321,6 +321,37 @@ static bufsize_t scan_to_closing_backticks(subject *subj,
321
321
  return 0;
322
322
  }
323
323
 
324
+ // Destructively modify string, converting newlines to
325
+ // spaces, then removing a single leading + trailing space.
326
+ static void S_normalize_code(cmark_strbuf *s) {
327
+ bufsize_t r, w;
328
+
329
+ for (r = 0, w = 0; r < s->size; ++r) {
330
+ switch (s->ptr[r]) {
331
+ case '\r':
332
+ if (s->ptr[r + 1] != '\n') {
333
+ s->ptr[w++] = ' ';
334
+ }
335
+ break;
336
+ case '\n':
337
+ s->ptr[w++] = ' ';
338
+ break;
339
+ default:
340
+ s->ptr[w++] = s->ptr[r];
341
+ }
342
+ }
343
+
344
+ // begins and ends with space?
345
+ if (s->ptr[0] == ' ' && s->ptr[w - 1] == ' ') {
346
+ cmark_strbuf_drop(s, 1);
347
+ cmark_strbuf_truncate(s, w - 2);
348
+ } else {
349
+ cmark_strbuf_truncate(s, w);
350
+ }
351
+
352
+ }
353
+
354
+
324
355
  // Parse backtick code section or raw backticks, return an inline.
325
356
  // Assumes that the subject has a backtick at the current position.
326
357
  static cmark_node *handle_backticks(subject *subj, int options) {
@@ -336,8 +367,7 @@ static cmark_node *handle_backticks(subject *subj, int options) {
336
367
 
337
368
  cmark_strbuf_set(&buf, subj->input.data + startpos,
338
369
  endpos - startpos - openticks.len);
339
- cmark_strbuf_trim(&buf);
340
- cmark_strbuf_normalize_whitespace(&buf);
370
+ S_normalize_code(&buf);
341
371
 
342
372
  cmark_node *node = make_code(subj, startpos, endpos - openticks.len - 1, cmark_chunk_buf_detach(&buf));
343
373
  adjust_subj_node_newlines(subj, node, endpos - startpos, openticks.len, options);
@@ -345,6 +375,7 @@ static cmark_node *handle_backticks(subject *subj, int options) {
345
375
  }
346
376
  }
347
377
 
378
+
348
379
  // Scan ***, **, or * and return number scanned, or 0.
349
380
  // Advances position.
350
381
  static int scan_delims(subject *subj, unsigned char c, bool *can_open,
@@ -1410,7 +1441,7 @@ bufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_chunk *input,
1410
1441
  // parse optional link_title
1411
1442
  beforetitle = subj.pos;
1412
1443
  spnl(&subj);
1413
- matchlen = scan_link_title(&subj.input, subj.pos);
1444
+ matchlen = subj.pos == beforetitle ? 0 : scan_link_title(&subj.input, subj.pos);
1414
1445
  if (matchlen) {
1415
1446
  title = cmark_chunk_dup(&subj.input, subj.pos, matchlen);
1416
1447
  subj.pos += matchlen;
@@ -69,10 +69,11 @@ static bool S_can_contain(cmark_node *node, cmark_node *child) {
69
69
  return cmark_node_can_contain_type(node, (cmark_node_type) child->type);
70
70
  }
71
71
 
72
- cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {
72
+ cmark_node *cmark_node_new_with_mem_and_ext(cmark_node_type type, cmark_mem *mem, cmark_syntax_extension *extension) {
73
73
  cmark_node *node = (cmark_node *)mem->calloc(1, sizeof(*node));
74
74
  cmark_strbuf_init(mem, &node->content, 0);
75
75
  node->type = (uint16_t)type;
76
+ node->extension = extension;
76
77
 
77
78
  switch (node->type) {
78
79
  case CMARK_NODE_HEADING:
@@ -91,12 +92,25 @@ cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {
91
92
  break;
92
93
  }
93
94
 
95
+ if (node->extension && node->extension->opaque_alloc_func) {
96
+ node->extension->opaque_alloc_func(node->extension, mem, node);
97
+ }
98
+
94
99
  return node;
95
100
  }
96
101
 
97
- cmark_node *cmark_node_new(cmark_node_type type) {
102
+ cmark_node *cmark_node_new_with_ext(cmark_node_type type, cmark_syntax_extension *extension) {
98
103
  extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;
99
- return cmark_node_new_with_mem(type, &CMARK_DEFAULT_MEM_ALLOCATOR);
104
+ return cmark_node_new_with_mem_and_ext(type, &CMARK_DEFAULT_MEM_ALLOCATOR, extension);
105
+ }
106
+
107
+ cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem)
108
+ {
109
+ return cmark_node_new_with_mem_and_ext(type, mem, NULL);
110
+ }
111
+
112
+ cmark_node *cmark_node_new(cmark_node_type type) {
113
+ return cmark_node_new_with_ext(type, NULL);
100
114
  }
101
115
 
102
116
  static void free_node_as(cmark_node *node) {
@@ -28,7 +28,7 @@ static cmark_node *match(cmark_syntax_extension *self, cmark_parser *parser,
28
28
  res->start_column = cmark_inline_parser_get_column(inline_parser) - delims;
29
29
 
30
30
  if ((left_flanking || right_flanking) &&
31
- (!(parser->options & CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE) || delims == 2)) {
31
+ (delims == 2 || (!(parser->options & CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE) && delims == 1))) {
32
32
  cmark_inline_parser_push_delimiter(inline_parser, character, left_flanking,
33
33
  right_flanking, res);
34
34
  }
@@ -46,6 +46,9 @@ static delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser,
46
46
 
47
47
  strikethrough = opener->inl_text;
48
48
 
49
+ if (opener->inl_text->as.literal.len != closer->inl_text->as.literal.len)
50
+ goto done;
51
+
49
52
  if (!cmark_node_set_type(strikethrough, CMARK_NODE_STRIKETHROUGH))
50
53
  goto done;
51
54
 
@@ -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;
@@ -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
  };
@@ -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;
@@ -488,6 +489,27 @@ static void latex_render(cmark_syntax_extension *extension,
488
489
  }
489
490
  }
490
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
+
491
513
  static void man_render(cmark_syntax_extension *extension,
492
514
  cmark_renderer *renderer, cmark_node *node,
493
515
  cmark_event_type ev_type, int options) {
@@ -648,6 +670,16 @@ static void html_render(cmark_syntax_extension *extension,
648
670
  }
649
671
  }
650
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
+
651
683
  static void opaque_free(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) {
652
684
  if (node->type == CMARK_NODE_TABLE) {
653
685
  free_node_table(mem, node->as.opaque);
@@ -675,8 +707,10 @@ cmark_syntax_extension *create_table_extension(void) {
675
707
  cmark_syntax_extension_set_commonmark_render_func(self, commonmark_render);
676
708
  cmark_syntax_extension_set_plaintext_render_func(self, commonmark_render);
677
709
  cmark_syntax_extension_set_latex_render_func(self, latex_render);
710
+ cmark_syntax_extension_set_xml_attr_func(self, xml_attr);
678
711
  cmark_syntax_extension_set_man_render_func(self, man_render);
679
712
  cmark_syntax_extension_set_html_render_func(self, html_render);
713
+ cmark_syntax_extension_set_opaque_alloc_func(self, opaque_alloc);
680
714
  cmark_syntax_extension_set_opaque_free_func(self, opaque_free);
681
715
  cmark_syntax_extension_set_commonmark_escape_func(self, escape);
682
716
  CMARK_NODE_TABLE = cmark_syntax_extension_add_node(0);
@@ -699,3 +733,30 @@ uint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node) {
699
733
 
700
734
  return ((node_table *)node->as.opaque)->alignments;
701
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
+ }
@@ -8,6 +8,7 @@
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));
@@ -19,7 +19,7 @@ module CommonMarker
19
19
  define :DEFAULT, 0
20
20
  define :SOURCEPOS, (1 << 1)
21
21
  define :HARDBREAKS, (1 << 2)
22
- define :SAFE, (1 << 3)
22
+ define :UNSAFE, (1 << 17)
23
23
  define :NOBREAKS, (1 << 4)
24
24
  define :GITHUB_PRE_LANG, (1 << 11)
25
25
  define :TABLE_PREFER_STYLE_ATTRIBUTES, (1 << 15)
@@ -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
 
@@ -1,3 +1,3 @@
1
1
  module CommonMarker
2
- VERSION = '0.17.13'.freeze
2
+ VERSION = '0.18.0'.freeze
3
3
  end
@@ -73,7 +73,7 @@ Another extension:
73
73
 
74
74
  def test_comments_are_kept_as_expected
75
75
  assert_equal "<!--hello--> <blah> &lt;xmp>\n",
76
- CommonMarker.render_html("<!--hello--> <blah> <xmp>\n", :DEFAULT, %i[tagfilter])
76
+ CommonMarker.render_html("<!--hello--> <blah> <xmp>\n", :UNSAFE, %i[tagfilter])
77
77
  end
78
78
 
79
79
  def test_table_prefer_style_attributes
@@ -9,18 +9,18 @@ class TestSpec < Minitest::Test
9
9
  doc = CommonMarker.render_doc(testcase[:markdown], :DEFAULT, testcase[:extensions])
10
10
 
11
11
  define_method("test_to_html_example_#{testcase[:example]}") do
12
- actual = doc.to_html(:DEFAULT, testcase[:extensions]).rstrip
12
+ actual = doc.to_html(:UNSAFE, testcase[:extensions]).rstrip
13
13
  assert_equal testcase[:html], actual, testcase[:markdown]
14
14
  end
15
15
 
16
16
  define_method("test_html_renderer_example_#{testcase[:example]}") do
17
- actual = HtmlRenderer.new(extensions: testcase[:extensions]).render(doc).rstrip
17
+ actual = HtmlRenderer.new(options: :UNSAFE, extensions: testcase[:extensions]).render(doc).rstrip
18
18
  assert_equal testcase[:html], actual, testcase[:markdown]
19
19
  end
20
20
 
21
21
  define_method("test_sourcepos_example_#{testcase[:example]}") do
22
- lhs = doc.to_html(:SOURCEPOS, testcase[:extensions]).rstrip
23
- rhs = HtmlRenderer.new(options: :SOURCEPOS, extensions: testcase[:extensions]).render(doc).rstrip
22
+ lhs = doc.to_html([:UNSAFE, :SOURCEPOS], testcase[:extensions]).rstrip
23
+ rhs = HtmlRenderer.new(options: [:UNSAFE, :SOURCEPOS], extensions: testcase[:extensions]).render(doc).rstrip
24
24
  assert_equal lhs, rhs, testcase[:markdown]
25
25
  end
26
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: commonmarker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.13
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garen Torikian
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-09-10 00:00:00.000000000 Z
12
+ date: 2018-10-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ruby-enum
@@ -243,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
243
  version: '0'
244
244
  requirements: []
245
245
  rubyforge_project:
246
- rubygems_version: 2.5.1
246
+ rubygems_version: 2.5.2.3
247
247
  signing_key:
248
248
  specification_version: 4
249
249
  summary: CommonMark parser and renderer. Written in C, wrapped in Ruby.