summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkivikakk <>2020-09-16 01:57:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2020-09-16 01:57:00 (GMT)
commitf52956f8c14ae70a7f0712574cb0c1911fc5e3d9 (patch)
treeb415e65fbd19c475154436d9bc86336426d66067
parent3e971c9cc22647dd7b461f732893a1469477dd24 (diff)
version 0.2.2HEAD0.2.2master
-rw-r--r--cbits/cmark-gfm-core-extensions.h25
-rw-r--r--cbits/ext_scanners.c1000
-rw-r--r--cbits/node.h1
-rw-r--r--cbits/table.c114
-rw-r--r--cbits/tasklist.c47
-rw-r--r--changelog4
-rw-r--r--cmark-gfm.cabal4
7 files changed, 511 insertions, 684 deletions
diff --git a/cbits/cmark-gfm-core-extensions.h b/cbits/cmark-gfm-core-extensions.h
index 8ab049d..0645915 100644
--- a/cbits/cmark-gfm-core-extensions.h
+++ b/cbits/cmark-gfm-core-extensions.h
@@ -7,6 +7,7 @@ extern "C" {
#include "cmark-gfm-extension_api.h"
#include "cmark-gfm-extensions_export.h"
+#include "config.h" // for bool
#include <stdint.h>
CMARK_GFM_EXTENSIONS_EXPORT
@@ -15,14 +16,36 @@ void cmark_gfm_core_extensions_ensure_registered(void);
CMARK_GFM_EXTENSIONS_EXPORT
uint16_t cmark_gfm_extensions_get_table_columns(cmark_node *node);
+/** Sets the number of columns for the table, returning 1 on success and 0 on error.
+ */
+CMARK_GFM_EXTENSIONS_EXPORT
+int cmark_gfm_extensions_set_table_columns(cmark_node *node, uint16_t n_columns);
+
CMARK_GFM_EXTENSIONS_EXPORT
uint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node);
+/** Sets the alignments for the table, returning 1 on success and 0 on error.
+ */
+CMARK_GFM_EXTENSIONS_EXPORT
+int cmark_gfm_extensions_set_table_alignments(cmark_node *node, uint16_t ncols, uint8_t *alignments);
+
CMARK_GFM_EXTENSIONS_EXPORT
int cmark_gfm_extensions_get_table_row_is_header(cmark_node *node);
+/** Sets whether the node is a table header row, returning 1 on success and 0 on error.
+ */
+CMARK_GFM_EXTENSIONS_EXPORT
+int cmark_gfm_extensions_set_table_row_is_header(cmark_node *node, int is_header);
+
+CMARK_GFM_EXTENSIONS_EXPORT
+bool cmark_gfm_extensions_get_tasklist_item_checked(cmark_node *node);
+/* For backwards compatibility */
+#define cmark_gfm_extensions_tasklist_is_checked cmark_gfm_extensions_get_tasklist_item_checked
+
+/** Sets whether a tasklist item is "checked" (completed), returning 1 on success and 0 on error.
+ */
CMARK_GFM_EXTENSIONS_EXPORT
-char *cmark_gfm_extensions_get_tasklist_state(cmark_node *node);
+int cmark_gfm_extensions_set_tasklist_item_checked(cmark_node *node, bool is_checked);
#ifdef __cplusplus
}
diff --git a/cbits/ext_scanners.c b/cbits/ext_scanners.c
index c3de227..0d3ba28 100644
--- a/cbits/ext_scanners.c
+++ b/cbits/ext_scanners.c
@@ -1,4 +1,5 @@
-/* Generated by re2c 1.1.1 */
+/* Generated by re2c 1.3 */
+
#include "ext_scanners.h"
#include <stdlib.h>
@@ -39,265 +40,180 @@ bufsize_t _scan_table_start(const unsigned char *p) {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
- yych = *(marker = p);
- if (yych <= '{') {
- if (yych <= 0x1F) {
- if (yych <= '\t') {
- if (yych <= 0x08)
- goto yy3;
+ yych = *p;
+ if (yych <= ' ') {
+ if (yych <= '\n') {
+ if (yych == '\t')
goto yy4;
- } else {
- if (yych <= '\n')
- goto yy2;
- if (yych <= '\f')
- goto yy4;
- goto yy3;
- }
} else {
- if (yych <= '-') {
- if (yych <= ' ')
- goto yy4;
- if (yych <= ',')
- goto yy3;
- goto yy5;
- } else {
- if (yych == ':')
- goto yy6;
- goto yy3;
- }
+ if (yych <= '\f')
+ goto yy4;
+ if (yych >= ' ')
+ goto yy4;
}
} else {
- if (yych <= 0xEC) {
- if (yych <= 0xC1) {
- if (yych <= '|')
- goto yy4;
- if (yych <= 0x7F)
- goto yy3;
- } else {
- if (yych <= 0xDF)
- goto yy7;
- if (yych <= 0xE0)
- goto yy9;
- goto yy10;
- }
+ if (yych <= '9') {
+ if (yych == '-')
+ goto yy5;
} else {
- if (yych <= 0xF0) {
- if (yych <= 0xED)
- goto yy11;
- if (yych <= 0xEF)
- goto yy10;
- goto yy12;
- } else {
- if (yych <= 0xF3)
- goto yy13;
- if (yych <= 0xF4)
- goto yy14;
- }
+ if (yych <= ':')
+ goto yy6;
+ if (yych == '|')
+ goto yy4;
}
}
- yy2 : { return 0; }
- yy3:
++p;
- goto yy2;
+ yy3 : { return 0; }
yy4:
yych = *(marker = ++p);
if (yybm[0 + yych] & 64) {
- goto yy15;
+ goto yy7;
}
if (yych == '-')
- goto yy17;
+ goto yy10;
if (yych == ':')
- goto yy19;
- goto yy2;
+ goto yy12;
+ goto yy3;
yy5:
yych = *(marker = ++p);
if (yybm[0 + yych] & 128) {
- goto yy17;
+ goto yy10;
}
if (yych <= ' ') {
if (yych <= 0x08)
- goto yy2;
+ goto yy3;
if (yych <= '\r')
- goto yy21;
+ goto yy14;
if (yych <= 0x1F)
- goto yy2;
- goto yy21;
+ goto yy3;
+ goto yy14;
} else {
if (yych <= ':') {
if (yych <= '9')
- goto yy2;
- goto yy20;
+ goto yy3;
+ goto yy13;
} else {
if (yych == '|')
- goto yy21;
- goto yy2;
+ goto yy14;
+ goto yy3;
}
}
yy6:
yych = *(marker = ++p);
if (yybm[0 + yych] & 128) {
- goto yy17;
+ goto yy10;
}
- goto yy2;
+ goto yy3;
yy7:
yych = *++p;
- if (yych <= 0x7F)
- goto yy8;
- if (yych <= 0xBF)
- goto yy3;
- yy8:
- p = marker;
- goto yy2;
- yy9:
- yych = *++p;
- if (yych <= 0x9F)
- goto yy8;
- if (yych <= 0xBF)
- goto yy7;
- goto yy8;
- yy10:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy8;
- if (yych <= 0xBF)
- goto yy7;
- goto yy8;
- yy11:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy8;
- if (yych <= 0x9F)
- goto yy7;
- goto yy8;
- yy12:
- yych = *++p;
- if (yych <= 0x8F)
- goto yy8;
- if (yych <= 0xBF)
- goto yy10;
- goto yy8;
- yy13:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy8;
- if (yych <= 0xBF)
- goto yy10;
- goto yy8;
- yy14:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy8;
- if (yych <= 0x8F)
- goto yy10;
- goto yy8;
- yy15:
- yych = *++p;
if (yybm[0 + yych] & 64) {
- goto yy15;
+ goto yy7;
}
if (yych == '-')
- goto yy17;
+ goto yy10;
if (yych == ':')
- goto yy19;
- goto yy8;
- yy17:
+ goto yy12;
+ yy9:
+ p = marker;
+ goto yy3;
+ yy10:
yych = *++p;
if (yybm[0 + yych] & 128) {
- goto yy17;
+ goto yy10;
}
if (yych <= 0x1F) {
if (yych <= '\n') {
if (yych <= 0x08)
- goto yy8;
+ goto yy9;
if (yych <= '\t')
- goto yy20;
- goto yy22;
+ goto yy13;
+ goto yy15;
} else {
if (yych <= '\f')
- goto yy20;
+ goto yy13;
if (yych <= '\r')
- goto yy24;
- goto yy8;
+ goto yy17;
+ goto yy9;
}
} else {
if (yych <= ':') {
if (yych <= ' ')
- goto yy20;
+ goto yy13;
if (yych <= '9')
- goto yy8;
- goto yy20;
+ goto yy9;
+ goto yy13;
} else {
if (yych == '|')
- goto yy25;
- goto yy8;
+ goto yy18;
+ goto yy9;
}
}
- yy19:
+ yy12:
yych = *++p;
if (yybm[0 + yych] & 128) {
- goto yy17;
+ goto yy10;
}
- goto yy8;
- yy20:
+ goto yy9;
+ yy13:
yych = *++p;
- yy21:
+ yy14:
if (yych <= '\r') {
if (yych <= '\t') {
if (yych <= 0x08)
- goto yy8;
- goto yy20;
+ goto yy9;
+ goto yy13;
} else {
if (yych <= '\n')
- goto yy22;
+ goto yy15;
if (yych <= '\f')
- goto yy20;
- goto yy24;
+ goto yy13;
+ goto yy17;
}
} else {
if (yych <= ' ') {
if (yych <= 0x1F)
- goto yy8;
- goto yy20;
+ goto yy9;
+ goto yy13;
} else {
if (yych == '|')
- goto yy25;
- goto yy8;
+ goto yy18;
+ goto yy9;
}
}
- yy22:
+ yy15:
++p;
{ return (bufsize_t)(p - start); }
- yy24:
+ yy17:
yych = *++p;
if (yych == '\n')
- goto yy22;
- goto yy8;
- yy25:
+ goto yy15;
+ goto yy9;
+ yy18:
yych = *++p;
if (yybm[0 + yych] & 128) {
- goto yy17;
+ goto yy10;
}
if (yych <= '\r') {
if (yych <= '\t') {
if (yych <= 0x08)
- goto yy8;
- goto yy25;
+ goto yy9;
+ goto yy18;
} else {
if (yych <= '\n')
- goto yy22;
+ goto yy15;
if (yych <= '\f')
- goto yy25;
- goto yy24;
+ goto yy18;
+ goto yy17;
}
} else {
if (yych <= ' ') {
if (yych <= 0x1F)
- goto yy8;
- goto yy25;
+ goto yy9;
+ goto yy18;
} else {
if (yych == ':')
- goto yy19;
- goto yy8;
+ goto yy12;
+ goto yy9;
}
}
}
@@ -309,6 +225,7 @@ bufsize_t _scan_table_cell(const unsigned char *p) {
{
unsigned char yych;
+ unsigned int yyaccept = 0;
static const unsigned char yybm[] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 64, 64, 0, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
@@ -326,53 +243,51 @@ bufsize_t _scan_table_cell(const unsigned char *p) {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
};
- yych = *(marker = p);
+ yych = *p;
if (yybm[0 + yych] & 64) {
- goto yy30;
+ goto yy22;
}
- if (yych <= 0xE0) {
- if (yych <= '\\') {
- if (yych <= '\n')
- goto yy29;
+ if (yych <= 0xEC) {
+ if (yych <= 0xC1) {
if (yych <= '\r')
- goto yy32;
- goto yy34;
+ goto yy25;
+ if (yych <= '\\')
+ goto yy27;
+ goto yy25;
} else {
- if (yych <= '|')
- goto yy32;
- if (yych <= 0xC1)
- goto yy29;
if (yych <= 0xDF)
- goto yy36;
- goto yy38;
+ goto yy29;
+ if (yych <= 0xE0)
+ goto yy30;
+ goto yy31;
}
} else {
- if (yych <= 0xEF) {
- if (yych == 0xED)
- goto yy40;
- goto yy39;
+ if (yych <= 0xF0) {
+ if (yych <= 0xED)
+ goto yy32;
+ if (yych <= 0xEF)
+ goto yy31;
+ goto yy33;
} else {
- if (yych <= 0xF0)
- goto yy41;
if (yych <= 0xF3)
- goto yy42;
+ goto yy34;
if (yych <= 0xF4)
- goto yy43;
+ goto yy35;
+ goto yy25;
}
}
- yy29 : { return (bufsize_t)(p - start); }
- yy30:
+ yy22:
+ yyaccept = 0;
yych = *(marker = ++p);
if (yybm[0 + yych] & 64) {
- goto yy30;
+ goto yy22;
}
if (yych <= 0xEC) {
if (yych <= 0xC1) {
if (yych <= '\r')
- goto yy29;
+ goto yy24;
if (yych <= '\\')
- goto yy34;
- goto yy29;
+ goto yy27;
} else {
if (yych <= 0xDF)
goto yy36;
@@ -392,29 +307,31 @@ bufsize_t _scan_table_cell(const unsigned char *p) {
goto yy42;
if (yych <= 0xF4)
goto yy43;
- goto yy29;
}
}
- yy32:
+ yy24 : { return (bufsize_t)(p - start); }
+ yy25:
++p;
- { return 0; }
- yy34:
+ yy26 : { return 0; }
+ yy27:
+ yyaccept = 0;
yych = *(marker = ++p);
if (yybm[0 + yych] & 128) {
- goto yy34;
+ goto yy27;
}
if (yych <= 0xDF) {
if (yych <= '\f') {
if (yych == '\n')
- goto yy29;
- goto yy30;
+ goto yy24;
+ goto yy22;
} else {
if (yych <= '\r')
- goto yy29;
+ goto yy24;
if (yych <= 0x7F)
- goto yy30;
+ goto yy22;
if (yych <= 0xC1)
- goto yy29;
+ goto yy24;
+ goto yy36;
}
} else {
if (yych <= 0xEF) {
@@ -430,18 +347,77 @@ bufsize_t _scan_table_cell(const unsigned char *p) {
goto yy42;
if (yych <= 0xF4)
goto yy43;
- goto yy29;
+ goto yy24;
}
}
+ yy29:
+ yych = *++p;
+ if (yych <= 0x7F)
+ goto yy26;
+ if (yych <= 0xBF)
+ goto yy22;
+ goto yy26;
+ yy30:
+ yyaccept = 1;
+ yych = *(marker = ++p);
+ if (yych <= 0x9F)
+ goto yy26;
+ if (yych <= 0xBF)
+ goto yy36;
+ goto yy26;
+ yy31:
+ yyaccept = 1;
+ yych = *(marker = ++p);
+ if (yych <= 0x7F)
+ goto yy26;
+ if (yych <= 0xBF)
+ goto yy36;
+ goto yy26;
+ yy32:
+ yyaccept = 1;
+ yych = *(marker = ++p);
+ if (yych <= 0x7F)
+ goto yy26;
+ if (yych <= 0x9F)
+ goto yy36;
+ goto yy26;
+ yy33:
+ yyaccept = 1;
+ yych = *(marker = ++p);
+ if (yych <= 0x8F)
+ goto yy26;
+ if (yych <= 0xBF)
+ goto yy39;
+ goto yy26;
+ yy34:
+ yyaccept = 1;
+ yych = *(marker = ++p);
+ if (yych <= 0x7F)
+ goto yy26;
+ if (yych <= 0xBF)
+ goto yy39;
+ goto yy26;
+ yy35:
+ yyaccept = 1;
+ yych = *(marker = ++p);
+ if (yych <= 0x7F)
+ goto yy26;
+ if (yych <= 0x8F)
+ goto yy39;
+ goto yy26;
yy36:
yych = *++p;
if (yych <= 0x7F)
goto yy37;
if (yych <= 0xBF)
- goto yy30;
+ goto yy22;
yy37:
p = marker;
- goto yy29;
+ if (yyaccept == 0) {
+ goto yy24;
+ } else {
+ goto yy26;
+ }
yy38:
yych = *++p;
if (yych <= 0x9F)
@@ -488,12 +464,10 @@ bufsize_t _scan_table_cell(const unsigned char *p) {
}
bufsize_t _scan_table_cell_end(const unsigned char *p) {
- const unsigned char *marker = NULL;
const unsigned char *start = p;
{
unsigned char yych;
- unsigned int yyaccept = 0;
static const unsigned char yybm[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0,
@@ -509,115 +483,17 @@ bufsize_t _scan_table_cell_end(const unsigned char *p) {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
- yych = *(marker = p);
- if (yych <= 0xDF) {
- if (yych <= '{') {
- if (yych != '\n')
- goto yy47;
- } else {
- if (yych <= '|')
- goto yy48;
- if (yych <= 0x7F)
- goto yy47;
- if (yych >= 0xC2)
- goto yy51;
- }
- } else {
- if (yych <= 0xEF) {
- if (yych <= 0xE0)
- goto yy53;
- if (yych == 0xED)
- goto yy55;
- goto yy54;
- } else {
- if (yych <= 0xF0)
- goto yy56;
- if (yych <= 0xF3)
- goto yy57;
- if (yych <= 0xF4)
- goto yy58;
- }
- }
- yy46 : { return 0; }
- yy47:
+ yych = *p;
+ if (yych == '|')
+ goto yy48;
++p;
- goto yy46;
+ { return 0; }
yy48:
- yyaccept = 1;
- yych = *(marker = ++p);
+ yych = *++p;
if (yybm[0 + yych] & 128) {
goto yy48;
}
- if (yych <= 0x08)
- goto yy50;
- if (yych <= '\n')
- goto yy59;
- if (yych <= '\r')
- goto yy60;
- yy50 : { return (bufsize_t)(p - start); }
- yy51:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy52;
- if (yych <= 0xBF)
- goto yy47;
- yy52:
- p = marker;
- if (yyaccept == 0) {
- goto yy46;
- } else {
- goto yy50;
- }
- yy53:
- yych = *++p;
- if (yych <= 0x9F)
- goto yy52;
- if (yych <= 0xBF)
- goto yy51;
- goto yy52;
- yy54:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy52;
- if (yych <= 0xBF)
- goto yy51;
- goto yy52;
- yy55:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy52;
- if (yych <= 0x9F)
- goto yy51;
- goto yy52;
- yy56:
- yych = *++p;
- if (yych <= 0x8F)
- goto yy52;
- if (yych <= 0xBF)
- goto yy54;
- goto yy52;
- yy57:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy52;
- if (yych <= 0xBF)
- goto yy54;
- goto yy52;
- yy58:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy52;
- if (yych <= 0x8F)
- goto yy54;
- goto yy52;
- yy59:
- ++p;
- goto yy50;
- yy60:
- yych = *++p;
- if (yych == '\n')
- goto yy59;
- goto yy52;
+ { return (bufsize_t)(p - start); }
}
}
@@ -642,138 +518,62 @@ bufsize_t _scan_table_row_end(const unsigned char *p) {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
- yych = *(marker = p);
- if (yych <= 0xC1) {
- if (yych <= '\f') {
- if (yych <= 0x08)
- goto yy64;
- if (yych == '\n')
- goto yy66;
- goto yy65;
- } else {
- if (yych <= 0x1F) {
- if (yych <= '\r')
- goto yy68;
- goto yy64;
- } else {
- if (yych <= ' ')
- goto yy65;
- if (yych <= 0x7F)
- goto yy64;
- }
- }
+ yych = *p;
+ if (yych <= '\f') {
+ if (yych <= 0x08)
+ goto yy53;
+ if (yych == '\n')
+ goto yy56;
+ goto yy55;
} else {
- if (yych <= 0xED) {
- if (yych <= 0xDF)
- goto yy69;
- if (yych <= 0xE0)
- goto yy71;
- if (yych <= 0xEC)
- goto yy72;
- goto yy73;
- } else {
- if (yych <= 0xF0) {
- if (yych <= 0xEF)
- goto yy72;
- goto yy74;
- } else {
- if (yych <= 0xF3)
- goto yy75;
- if (yych <= 0xF4)
- goto yy76;
- }
- }
+ if (yych <= '\r')
+ goto yy58;
+ if (yych == ' ')
+ goto yy55;
}
- yy63 : { return 0; }
- yy64:
+ yy53:
++p;
- goto yy63;
- yy65:
+ yy54 : { return 0; }
+ yy55:
yych = *(marker = ++p);
if (yych <= 0x08)
- goto yy63;
+ goto yy54;
if (yych <= '\r')
- goto yy78;
+ goto yy60;
if (yych == ' ')
- goto yy78;
- goto yy63;
- yy66:
+ goto yy60;
+ goto yy54;
+ yy56:
++p;
{ return (bufsize_t)(p - start); }
- yy68:
+ yy58:
yych = *++p;
if (yych == '\n')
- goto yy66;
- goto yy63;
- yy69:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy70;
- if (yych <= 0xBF)
- goto yy64;
- yy70:
- p = marker;
- goto yy63;
- yy71:
- yych = *++p;
- if (yych <= 0x9F)
- goto yy70;
- if (yych <= 0xBF)
- goto yy69;
- goto yy70;
- yy72:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy70;
- if (yych <= 0xBF)
- goto yy69;
- goto yy70;
- yy73:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy70;
- if (yych <= 0x9F)
- goto yy69;
- goto yy70;
- yy74:
- yych = *++p;
- if (yych <= 0x8F)
- goto yy70;
- if (yych <= 0xBF)
- goto yy72;
- goto yy70;
- yy75:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy70;
- if (yych <= 0xBF)
- goto yy72;
- goto yy70;
- yy76:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy70;
- if (yych <= 0x8F)
- goto yy72;
- goto yy70;
- yy77:
+ goto yy56;
+ goto yy54;
+ yy59:
yych = *++p;
- yy78:
+ yy60:
if (yybm[0 + yych] & 128) {
- goto yy77;
+ goto yy59;
}
if (yych <= 0x08)
- goto yy70;
+ goto yy61;
if (yych <= '\n')
- goto yy66;
- if (yych >= 0x0E)
- goto yy70;
+ goto yy56;
+ if (yych <= '\r')
+ goto yy62;
+ yy61:
+ p = marker;
+ goto yy54;
+ yy62:
yych = *++p;
if (yych == '\n')
- goto yy66;
- goto yy70;
+ goto yy56;
+ goto yy61;
}
}
+
bufsize_t _scan_tasklist(const unsigned char *p) {
const unsigned char *marker = NULL;
const unsigned char *start = p;
@@ -798,361 +598,281 @@ bufsize_t _scan_tasklist(const unsigned char *p) {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
- yych = *(marker = p);
- if (yych <= '/') {
- if (yych <= 0x1F) {
- if (yych <= '\t') {
- if (yych <= 0x08)
- goto yy83;
- goto yy84;
- } else {
- if (yych <= '\n')
- goto yy82;
- if (yych <= '\f')
- goto yy84;
- goto yy83;
- }
+ yych = *p;
+ if (yych <= ' ') {
+ if (yych <= '\n') {
+ if (yych == '\t')
+ goto yy67;
} else {
- if (yych <= '+') {
- if (yych <= ' ')
- goto yy84;
- if (yych <= ')')
- goto yy83;
- goto yy85;
- } else {
- if (yych == '-')
- goto yy85;
- goto yy83;
- }
+ if (yych <= '\f')
+ goto yy67;
+ if (yych >= ' ')
+ goto yy67;
}
} else {
- if (yych <= 0xEC) {
- if (yych <= 0xC1) {
- if (yych <= '9')
- goto yy86;
- if (yych <= 0x7F)
- goto yy83;
- } else {
- if (yych <= 0xDF)
- goto yy87;
- if (yych <= 0xE0)
- goto yy89;
- goto yy90;
- }
+ if (yych <= ',') {
+ if (yych <= ')')
+ goto yy65;
+ if (yych <= '+')
+ goto yy68;
} else {
- if (yych <= 0xF0) {
- if (yych <= 0xED)
- goto yy91;
- if (yych <= 0xEF)
- goto yy90;
- goto yy92;
- } else {
- if (yych <= 0xF3)
- goto yy93;
- if (yych <= 0xF4)
- goto yy94;
- }
+ if (yych <= '-')
+ goto yy68;
+ if (yych <= '/')
+ goto yy65;
+ if (yych <= '9')
+ goto yy69;
}
}
- yy82 : { return 0; }
- yy83:
+ yy65:
++p;
- goto yy82;
- yy84:
+ yy66 : { return 0; }
+ yy67:
yych = *(marker = ++p);
if (yybm[0 + yych] & 64) {
- goto yy95;
+ goto yy70;
}
if (yych <= ',') {
if (yych <= ')')
- goto yy82;
+ goto yy66;
if (yych <= '+')
- goto yy97;
- goto yy82;
+ goto yy73;
+ goto yy66;
} else {
if (yych <= '-')
- goto yy97;
+ goto yy73;
if (yych <= '/')
- goto yy82;
+ goto yy66;
if (yych <= '9')
- goto yy98;
- goto yy82;
+ goto yy74;
+ goto yy66;
}
- yy85:
+ yy68:
yych = *(marker = ++p);
if (yych <= '\n') {
if (yych == '\t')
- goto yy99;
- goto yy82;
+ goto yy75;
+ goto yy66;
} else {
if (yych <= '\f')
- goto yy99;
+ goto yy75;
if (yych == ' ')
- goto yy99;
- goto yy82;
+ goto yy75;
+ goto yy66;
}
- yy86:
+ yy69:
yych = *(marker = ++p);
if (yych <= 0x1F) {
if (yych <= '\t') {
if (yych <= 0x08)
- goto yy102;
- goto yy97;
+ goto yy78;
+ goto yy73;
} else {
if (yych <= '\n')
- goto yy82;
+ goto yy66;
if (yych <= '\f')
- goto yy97;
- goto yy102;
+ goto yy73;
+ goto yy78;
}
} else {
if (yych <= 0x7F) {
if (yych <= ' ')
- goto yy97;
- goto yy102;
+ goto yy73;
+ goto yy78;
} else {
if (yych <= 0xC1)
- goto yy82;
+ goto yy66;
if (yych <= 0xF4)
- goto yy102;
- goto yy82;
+ goto yy78;
+ goto yy66;
}
}
- yy87:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy88;
- if (yych <= 0xBF)
- goto yy83;
- yy88:
- p = marker;
- goto yy82;
- yy89:
- yych = *++p;
- if (yych <= 0x9F)
- goto yy88;
- if (yych <= 0xBF)
- goto yy87;
- goto yy88;
- yy90:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy88;
- if (yych <= 0xBF)
- goto yy87;
- goto yy88;
- yy91:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy88;
- if (yych <= 0x9F)
- goto yy87;
- goto yy88;
- yy92:
- yych = *++p;
- if (yych <= 0x8F)
- goto yy88;
- if (yych <= 0xBF)
- goto yy90;
- goto yy88;
- yy93:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy88;
- if (yych <= 0xBF)
- goto yy90;
- goto yy88;
- yy94:
- yych = *++p;
- if (yych <= 0x7F)
- goto yy88;
- if (yych <= 0x8F)
- goto yy90;
- goto yy88;
- yy95:
+ yy70:
yych = *++p;
if (yybm[0 + yych] & 64) {
- goto yy95;
+ goto yy70;
}
if (yych <= ',') {
if (yych <= ')')
- goto yy88;
- if (yych >= ',')
- goto yy88;
+ goto yy72;
+ if (yych <= '+')
+ goto yy73;
} else {
if (yych <= '-')
- goto yy97;
+ goto yy73;
if (yych <= '/')
- goto yy88;
+ goto yy72;
if (yych <= '9')
- goto yy98;
- goto yy88;
+ goto yy74;
}
- yy97:
+ yy72:
+ p = marker;
+ goto yy66;
+ yy73:
yych = *++p;
if (yych == '[')
- goto yy88;
- goto yy100;
- yy98:
+ goto yy72;
+ goto yy76;
+ yy74:
yych = *++p;
if (yych <= '\n') {
if (yych == '\t')
- goto yy97;
- goto yy102;
+ goto yy73;
+ goto yy78;
} else {
if (yych <= '\f')
- goto yy97;
+ goto yy73;
if (yych == ' ')
- goto yy97;
- goto yy102;
+ goto yy73;
+ goto yy78;
}
- yy99:
+ yy75:
yych = *++p;
- yy100:
+ yy76:
if (yych <= '\f') {
if (yych == '\t')
- goto yy99;
+ goto yy75;
if (yych <= '\n')
- goto yy88;
- goto yy99;
+ goto yy72;
+ goto yy75;
} else {
if (yych <= ' ') {
if (yych <= 0x1F)
- goto yy88;
- goto yy99;
+ goto yy72;
+ goto yy75;
} else {
if (yych == '[')
- goto yy110;
- goto yy88;
+ goto yy86;
+ goto yy72;
}
}
- yy101:
+ yy77:
yych = *++p;
- yy102:
+ yy78:
if (yybm[0 + yych] & 128) {
- goto yy101;
+ goto yy77;
}
if (yych <= 0xC1) {
if (yych <= '\f') {
if (yych <= 0x08)
- goto yy97;
+ goto yy73;
if (yych == '\n')
- goto yy88;
- goto yy99;
+ goto yy72;
+ goto yy75;
} else {
if (yych == ' ')
- goto yy99;
+ goto yy75;
if (yych <= 0x7F)
- goto yy97;
- goto yy88;
+ goto yy73;
+ goto yy72;
}
} else {
if (yych <= 0xED) {
if (yych <= 0xDF)
- goto yy103;
+ goto yy79;
if (yych <= 0xE0)
- goto yy104;
+ goto yy80;
if (yych <= 0xEC)
- goto yy105;
- goto yy106;
+ goto yy81;
+ goto yy82;
} else {
if (yych <= 0xF0) {
if (yych <= 0xEF)
- goto yy105;
- goto yy107;
+ goto yy81;
+ goto yy83;
} else {
if (yych <= 0xF3)
- goto yy108;
+ goto yy84;
if (yych <= 0xF4)
- goto yy109;
- goto yy88;
+ goto yy85;
+ goto yy72;
}
}
}
- yy103:
+ yy79:
yych = *++p;
if (yych <= 0x7F)
- goto yy88;
+ goto yy72;
if (yych <= 0xBF)
- goto yy97;
- goto yy88;
- yy104:
+ goto yy73;
+ goto yy72;
+ yy80:
yych = *++p;
if (yych <= 0x9F)
- goto yy88;
+ goto yy72;
if (yych <= 0xBF)
- goto yy103;
- goto yy88;
- yy105:
+ goto yy79;
+ goto yy72;
+ yy81:
yych = *++p;
if (yych <= 0x7F)
- goto yy88;
+ goto yy72;
if (yych <= 0xBF)
- goto yy103;
- goto yy88;
- yy106:
+ goto yy79;
+ goto yy72;
+ yy82:
yych = *++p;
if (yych <= 0x7F)
- goto yy88;
+ goto yy72;
if (yych <= 0x9F)
- goto yy103;
- goto yy88;
- yy107:
+ goto yy79;
+ goto yy72;
+ yy83:
yych = *++p;
if (yych <= 0x8F)
- goto yy88;
+ goto yy72;
if (yych <= 0xBF)
- goto yy105;
- goto yy88;
- yy108:
+ goto yy81;
+ goto yy72;
+ yy84:
yych = *++p;
if (yych <= 0x7F)
- goto yy88;
+ goto yy72;
if (yych <= 0xBF)
- goto yy105;
- goto yy88;
- yy109:
+ goto yy81;
+ goto yy72;
+ yy85:
yych = *++p;
if (yych <= 0x7F)
- goto yy88;
+ goto yy72;
if (yych <= 0x8F)
- goto yy105;
- goto yy88;
- yy110:
+ goto yy81;
+ goto yy72;
+ yy86:
yych = *++p;
if (yych <= 'W') {
if (yych != ' ')
- goto yy88;
+ goto yy72;
} else {
if (yych <= 'X')
- goto yy111;
+ goto yy87;
if (yych != 'x')
- goto yy88;
+ goto yy72;
}
- yy111:
+ yy87:
yych = *++p;
if (yych != ']')
- goto yy88;
+ goto yy72;
yych = *++p;
if (yych <= '\n') {
if (yych != '\t')
- goto yy88;
+ goto yy72;
} else {
if (yych <= '\f')
- goto yy113;
+ goto yy89;
if (yych != ' ')
- goto yy88;
+ goto yy72;
}
- yy113:
+ yy89:
yych = *++p;
if (yych <= '\n') {
if (yych == '\t')
- goto yy113;
+ goto yy89;
} else {
if (yych <= '\f')
- goto yy113;
+ goto yy89;
if (yych == ' ')
- goto yy113;
+ goto yy89;
}
{ return (bufsize_t)(p - start); }
}
diff --git a/cbits/node.h b/cbits/node.h
index 6b05df1..6391db9 100644
--- a/cbits/node.h
+++ b/cbits/node.h
@@ -21,6 +21,7 @@ typedef struct {
cmark_delim_type delimiter;
unsigned char bullet_char;
bool tight;
+ bool checked; // For task list extension
} cmark_list;
typedef struct {
diff --git a/cbits/table.c b/cbits/table.c
index 9829c3d..a5bb440 100644
--- a/cbits/table.c
+++ b/cbits/table.c
@@ -16,6 +16,7 @@ cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,
typedef struct {
uint16_t n_columns;
+ int paragraph_offset;
cmark_llist *cells;
} table_row;
@@ -113,22 +114,39 @@ static cmark_strbuf *unescape_pipes(cmark_mem *mem, unsigned char *string, bufsi
static table_row *row_from_string(cmark_syntax_extension *self,
cmark_parser *parser, unsigned char *string,
int len) {
+ // Parses a single table row. It has the following form:
+ // `delim? table_cell (delim table_cell)* delim? newline`
+ // Note that cells are allowed to be empty.
+ //
+ // From the GitHub-flavored Markdown specification:
+ //
+ // > Each row consists of cells containing arbitrary text, in which inlines
+ // > are parsed, separated by pipes (|). A leading and trailing pipe is also
+ // > recommended for clarity of reading, and if there’s otherwise parsing
+ // > ambiguity.
+
table_row *row = NULL;
bufsize_t cell_matched = 1, pipe_matched = 1, offset;
+ int expect_more_cells = 1;
+ int row_end_offset = 0;
row = (table_row *)parser->mem->calloc(1, sizeof(table_row));
row->n_columns = 0;
row->cells = NULL;
+ // Scan past the (optional) leading pipe.
offset = scan_table_cell_end(string, len, 0);
// Parse the cells of the row. Stop if we reach the end of the input, or if we
// cannot detect any more cells.
- while (offset < len && (cell_matched || pipe_matched)) {
+ while (offset < len && expect_more_cells) {
cell_matched = scan_table_cell(string, len, offset);
pipe_matched = scan_table_cell_end(string, len, offset + cell_matched);
if (cell_matched || pipe_matched) {
+ // We are guaranteed to have a cell, since (1) either we found some
+ // content and cell_matched, or (2) we found an empty cell followed by a
+ // pipe.
cmark_strbuf *cell_buf = unescape_pipes(parser->mem, string + offset,
cell_matched);
cmark_strbuf_trim(cell_buf);
@@ -137,23 +155,46 @@ static table_row *row_from_string(cmark_syntax_extension *self,
cell->buf = cell_buf;
cell->start_offset = offset;
cell->end_offset = offset + cell_matched - 1;
+
while (cell->start_offset > 0 && string[cell->start_offset - 1] != '|') {
--cell->start_offset;
++cell->internal_offset;
}
+
row->n_columns += 1;
row->cells = cmark_llist_append(parser->mem, row->cells, cell);
}
offset += cell_matched + pipe_matched;
- if (!pipe_matched) {
- pipe_matched = scan_table_row_end(string, len, offset);
- offset += pipe_matched;
+ if (pipe_matched) {
+ expect_more_cells = 1;
+ } else {
+ // We've scanned the last cell. Check if we have reached the end of the row
+ row_end_offset = scan_table_row_end(string, len, offset);
+ offset += row_end_offset;
+
+ // If the end of the row is not the end of the input,
+ // the row is not a real row but potentially part of the paragraph
+ // preceding the table.
+ if (row_end_offset && offset != len) {
+ row->paragraph_offset = offset;
+
+ cmark_llist_free_full(parser->mem, row->cells, (cmark_free_func)free_table_cell);
+ row->cells = NULL;
+ row->n_columns = 0;
+
+ // Scan past the (optional) leading pipe.
+ offset += scan_table_cell_end(string, len, offset);
+
+ expect_more_cells = 1;
+ } else {
+ expect_more_cells = 0;
+ }
}
}
- if (offset != len || !row->n_columns) {
+ if (offset != len || row->n_columns == 0) {
free_table_row(parser->mem, row);
row = NULL;
}
@@ -161,12 +202,30 @@ static table_row *row_from_string(cmark_syntax_extension *self,
return row;
}
+static void try_inserting_table_header_paragraph(cmark_parser *parser,
+ cmark_node *parent_container,
+ unsigned char *parent_string,
+ int paragraph_offset) {
+ cmark_node *paragraph;
+ cmark_strbuf *paragraph_content;
+
+ paragraph = cmark_node_new_with_mem(CMARK_NODE_PARAGRAPH, parser->mem);
+
+ paragraph_content = unescape_pipes(parser->mem, parent_string, paragraph_offset);
+ cmark_strbuf_trim(paragraph_content);
+ cmark_node_set_string_content(paragraph, (char *) paragraph_content->ptr);
+ cmark_strbuf_free(paragraph_content);
+ parser->mem->free(paragraph_content);
+
+ if (!cmark_node_insert_before(parent_container, paragraph)) {
+ parser->mem->free(paragraph);
+ }
+}
+
static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
cmark_parser *parser,
cmark_node *parent_container,
unsigned char *input, int len) {
- bufsize_t matched =
- scan_table_start(input, len, cmark_parser_get_first_nonspace(parser));
cmark_node *table_header;
table_row *header_row = NULL;
table_row *marker_row = NULL;
@@ -174,41 +233,37 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
const char *parent_string;
uint16_t i;
- if (!matched)
- return parent_container;
-
- parent_string = cmark_node_get_string_content(parent_container);
-
- cmark_arena_push();
-
- header_row = row_from_string(self, parser, (unsigned char *)parent_string,
- (int)strlen(parent_string));
-
- if (!header_row) {
- free_table_row(parser->mem, header_row);
- cmark_arena_pop();
+ if (!scan_table_start(input, len, cmark_parser_get_first_nonspace(parser))) {
return parent_container;
}
+ // Since scan_table_start was successful, we must have a marker row.
marker_row = row_from_string(self, parser,
input + cmark_parser_get_first_nonspace(parser),
len - cmark_parser_get_first_nonspace(parser));
-
assert(marker_row);
- if (header_row->n_columns != marker_row->n_columns) {
- free_table_row(parser->mem, header_row);
+ cmark_arena_push();
+
+ // Check for a matching header row. We call `row_from_string` with the entire
+ // (potentially long) parent container as input, but this should be safe since
+ // `row_from_string` bails out early if it does not find a row.
+ parent_string = cmark_node_get_string_content(parent_container);
+ header_row = row_from_string(self, parser, (unsigned char *)parent_string,
+ (int)strlen(parent_string));
+ if (!header_row || header_row->n_columns != marker_row->n_columns) {
free_table_row(parser->mem, marker_row);
+ free_table_row(parser->mem, header_row);
cmark_arena_pop();
return parent_container;
}
if (cmark_arena_pop()) {
+ marker_row = row_from_string(
+ self, parser, input + cmark_parser_get_first_nonspace(parser),
+ len - cmark_parser_get_first_nonspace(parser));
header_row = row_from_string(self, parser, (unsigned char *)parent_string,
(int)strlen(parent_string));
- marker_row = row_from_string(self, parser,
- input + cmark_parser_get_first_nonspace(parser),
- len - cmark_parser_get_first_nonspace(parser));
}
if (!cmark_node_set_type(parent_container, CMARK_NODE_TABLE)) {
@@ -217,10 +272,13 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
return parent_container;
}
- cmark_node_set_syntax_extension(parent_container, self);
+ if (header_row->paragraph_offset) {
+ try_inserting_table_header_paragraph(parser, parent_container, (unsigned char *)parent_string,
+ header_row->paragraph_offset);
+ }
+ cmark_node_set_syntax_extension(parent_container, self);
parent_container->as.opaque = parser->mem->calloc(1, sizeof(node_table));
-
set_n_table_columns(parent_container, header_row->n_columns);
uint8_t *alignments =
diff --git a/cbits/tasklist.c b/cbits/tasklist.c
index 3c273fc..7bef454 100644
--- a/cbits/tasklist.c
+++ b/cbits/tasklist.c
@@ -9,19 +9,33 @@ typedef enum {
CMARK_TASKLIST_CHECKED,
} cmark_tasklist_type;
+// Local constants
+static const char *TYPE_STRING = "tasklist";
+
static const char *get_type_string(cmark_syntax_extension *extension, cmark_node *node) {
- return "tasklist";
+ return TYPE_STRING;
}
-char *cmark_gfm_extensions_get_tasklist_state(cmark_node *node) {
- if (!node || ((int)node->as.opaque != CMARK_TASKLIST_CHECKED && (int)node->as.opaque != CMARK_TASKLIST_NOCHECKED))
+
+// Return 1 if state was set, 0 otherwise
+int cmark_gfm_extensions_set_tasklist_item_checked(cmark_node *node, bool is_checked) {
+ // The node has to exist, and be an extension, and actually be the right type in order to get the value.
+ if (!node || !node->extension || strcmp(cmark_node_get_type_string(node), TYPE_STRING))
return 0;
- if ((int)node->as.opaque != CMARK_TASKLIST_CHECKED) {
- return "checked";
+ node->as.list.checked = is_checked;
+ return 1;
+}
+
+bool cmark_gfm_extensions_get_tasklist_item_checked(cmark_node *node) {
+ if (!node || !node->extension || strcmp(cmark_node_get_type_string(node), TYPE_STRING))
+ return false;
+
+ if (node->as.list.checked) {
+ return true;
}
else {
- return "unchecked";
+ return false;
}
}
@@ -74,11 +88,8 @@ static cmark_node *open_tasklist_item(cmark_syntax_extension *self,
cmark_node_set_syntax_extension(parent_container, self);
cmark_parser_advance_offset(parser, (char *)input, 3, false);
- if (strstr((char*)input, "[x]")) {
- parent_container->as.opaque = (void *)CMARK_TASKLIST_CHECKED;
- } else {
- parent_container->as.opaque = (void *)CMARK_TASKLIST_NOCHECKED;
- }
+ // Either an upper or lower case X means the task is completed.
+ parent_container->as.list.checked = (strstr((char*)input, "[x]") || strstr((char*)input, "[X]"));
return NULL;
}
@@ -89,7 +100,7 @@ static void commonmark_render(cmark_syntax_extension *extension,
bool entering = (ev_type == CMARK_EVENT_ENTER);
if (entering) {
renderer->cr(renderer);
- if ((int)node->as.opaque == CMARK_TASKLIST_CHECKED) {
+ if (node->as.list.checked) {
renderer->out(renderer, node, "- [x] ", false, LITERAL);
} else {
renderer->out(renderer, node, "- [ ] ", false, LITERAL);
@@ -110,7 +121,7 @@ static void html_render(cmark_syntax_extension *extension,
cmark_strbuf_puts(renderer->html, "<li");
cmark_html_render_sourcepos(node, renderer->html, options);
cmark_strbuf_putc(renderer->html, '>');
- if ((int)node->as.opaque == CMARK_TASKLIST_CHECKED) {
+ if (node->as.list.checked) {
cmark_strbuf_puts(renderer->html, "<input type=\"checkbox\" checked=\"\" disabled=\"\" /> ");
} else {
cmark_strbuf_puts(renderer->html, "<input type=\"checkbox\" disabled=\"\" /> ");
@@ -120,6 +131,15 @@ static void html_render(cmark_syntax_extension *extension,
}
}
+static const char *xml_attr(cmark_syntax_extension *extension,
+ cmark_node *node) {
+ if (node->as.list.checked) {
+ return " completed=\"true\"";
+ } else {
+ return " completed=\"false\"";
+ }
+}
+
cmark_syntax_extension *create_tasklist_extension(void) {
cmark_syntax_extension *ext = cmark_syntax_extension_new("tasklist");
@@ -130,6 +150,7 @@ cmark_syntax_extension *create_tasklist_extension(void) {
cmark_syntax_extension_set_commonmark_render_func(ext, commonmark_render);
cmark_syntax_extension_set_plaintext_render_func(ext, commonmark_render);
cmark_syntax_extension_set_html_render_func(ext, html_render);
+ cmark_syntax_extension_set_xml_attr_func(ext, xml_attr);
return ext;
}
diff --git a/changelog b/changelog
index 851336c..e632645 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,7 @@
+cmark-gfm 0.2.2 (16 Sep 2020)
+
+ * Pull in upstream changes.
+
cmark-gfm 0.2.1 (15 Nov 2019)
* Add tasklist support (#16, Christian Gill).
diff --git a/cmark-gfm.cabal b/cmark-gfm.cabal
index 016478c..506b3c5 100644
--- a/cmark-gfm.cabal
+++ b/cmark-gfm.cabal
@@ -1,5 +1,5 @@
name: cmark-gfm
-version: 0.2.1
+version: 0.2.2
synopsis: Fast, accurate GitHub Flavored Markdown parser and renderer
description:
This package provides Haskell bindings for
@@ -13,7 +13,7 @@ homepage: https://github.com/kivikakk/cmark-gfm-hs
license: BSD3
license-file: LICENSE
author: Ashe Connor
-maintainer: kivikakk@github.com
+maintainer: ashe@kivikakk.ee
copyright: (C) 2015--17 John MacFarlane, (C) 2017--19 Ashe Connor
category: Text
build-type: Simple