diff --git a/api_test/main.c b/api_test/main.c index d7202343b..e9777f1ac 100644 --- a/api_test/main.c +++ b/api_test/main.c @@ -103,6 +103,8 @@ static void accessors(test_batch_runner *runner) { cmark_node *bullet_list = cmark_node_next(heading); INT_EQ(runner, cmark_node_get_list_type(bullet_list), CMARK_BULLET_LIST, "get_list_type bullet"); + INT_EQ(runner, cmark_node_get_list_marker(bullet_list), CMARK_ASTERISK_MARKER, + "get_list_marker asterisk"); INT_EQ(runner, cmark_node_get_list_tight(bullet_list), 1, "get_list_tight tight"); @@ -111,6 +113,8 @@ static void accessors(test_batch_runner *runner) { "get_list_type ordered"); INT_EQ(runner, cmark_node_get_list_delim(ordered_list), CMARK_PERIOD_DELIM, "get_list_delim ordered"); + INT_EQ(runner, cmark_node_get_list_marker(ordered_list), CMARK_NUMERIC_MARKER, + "get_list_marker numeric"); INT_EQ(runner, cmark_node_get_list_start(ordered_list), 2, "get_list_start"); INT_EQ(runner, cmark_node_get_list_tight(ordered_list), 0, "get_list_tight loose"); @@ -144,10 +148,14 @@ static void accessors(test_batch_runner *runner) { OK(runner, cmark_node_set_heading_level(heading, 3), "set_heading_level"); + OK(runner, cmark_node_set_list_marker(bullet_list, CMARK_HYPHEN_MARKER), + "set_list_marker hyphen"); OK(runner, cmark_node_set_list_type(bullet_list, CMARK_ORDERED_LIST), "set_list_type ordered"); OK(runner, cmark_node_set_list_delim(bullet_list, CMARK_PAREN_DELIM), "set_list_delim paren"); + OK(runner, cmark_node_set_list_marker(bullet_list, CMARK_NUMERIC_MARKER), + "set_list_marker numeric"); OK(runner, cmark_node_set_list_start(bullet_list, 3), "set_list_start"); OK(runner, cmark_node_set_list_tight(bullet_list, 0), "set_list_tight loose"); diff --git a/src/blocks.c b/src/blocks.c index 5a293b2e0..4382ec26b 100644 --- a/src/blocks.c +++ b/src/blocks.c @@ -414,6 +414,13 @@ static bufsize_t parse_list_marker(cmark_mem *mem, cmark_chunk *input, data->marker_offset = 0; // will be adjusted later data->list_type = CMARK_BULLET_LIST; data->bullet_char = c; + if (c == '*') { + data->marker = CMARK_ASTERISK_MARKER; + } else if (c == '-') { + data->marker = CMARK_HYPHEN_MARKER; + } else if (c == '+') { + data->marker = CMARK_PLUS_MARKER; + } data->start = 0; data->delimiter = CMARK_NO_DELIM; data->tight = false; @@ -454,6 +461,7 @@ static bufsize_t parse_list_marker(cmark_mem *mem, cmark_chunk *input, data->marker_offset = 0; // will be adjusted later data->list_type = CMARK_ORDERED_LIST; data->bullet_char = 0; + data->marker = CMARK_NUMERIC_MARKER; data->start = start; data->delimiter = (c == '.' ? CMARK_PERIOD_DELIM : CMARK_PAREN_DELIM); data->tight = false; diff --git a/src/cmark.h b/src/cmark.h index d1a65aa88..ea099446d 100644 --- a/src/cmark.h +++ b/src/cmark.h @@ -83,6 +83,14 @@ typedef enum { CMARK_PAREN_DELIM } cmark_delim_type; +typedef enum { + CMARK_NO_MARKER, + CMARK_NUMERIC_MARKER, + CMARK_ASTERISK_MARKER, + CMARK_HYPHEN_MARKER, + CMARK_PLUS_MARKER +} cmark_marker_type; + typedef struct cmark_node cmark_node; typedef struct cmark_parser cmark_parser; typedef struct cmark_iter cmark_iter; @@ -308,6 +316,16 @@ CMARK_EXPORT cmark_delim_type cmark_node_get_list_delim(cmark_node *node); CMARK_EXPORT int cmark_node_set_list_delim(cmark_node *node, cmark_delim_type delim); +/** Returns the marker type of 'node' or CMARK_NO_MARKER if 'node' is not a + * list. + */ +CMARK_EXPORT cmark_marker_type cmark_node_get_list_marker(cmark_node *node); + +/** Sets the marker type of 'node', returning 1 on success and 0 on error. + */ +CMARK_EXPORT int cmark_node_set_list_marker(cmark_node *node, + cmark_marker_type marker); + /** Returns starting number of 'node', if it is an ordered list, otherwise 0. */ CMARK_EXPORT int cmark_node_get_list_start(cmark_node *node); @@ -633,8 +651,14 @@ const char *cmark_version_string(void); #define NODE_IMAGE CMARK_NODE_IMAGE #define BULLET_LIST CMARK_BULLET_LIST #define ORDERED_LIST CMARK_ORDERED_LIST +#define NO_DELIM CMARK_NO_DELIM #define PERIOD_DELIM CMARK_PERIOD_DELIM #define PAREN_DELIM CMARK_PAREN_DELIM +#define NO_MARKER CMARK_PERIOD_DELIM +#define NUMERIC_MARKER CMARK_NUMERIC_MARKER +#define ASTERISK_MARKER CMARK_ASTERISK_MARKER +#define HYPHEN_MARKER CMARK_HYPHEN_MARKER +#define PLUS_MARKER CMARK_PLUS_MARKER #endif #ifdef __cplusplus diff --git a/src/commonmark.c b/src/commonmark.c index 95a1ae5e5..e22f8f5fd 100644 --- a/src/commonmark.c +++ b/src/commonmark.c @@ -220,6 +220,14 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node, case CMARK_NODE_ITEM: if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) { marker_width = 4; + if (cmark_node_get_list_marker(node->parent) == CMARK_ASTERISK_MARKER) { + snprintf(listmarker, LISTMARKER_SIZE, " %s ", "*"); + } else if (cmark_node_get_list_marker(node->parent) == + CMARK_PLUS_MARKER) { + snprintf(listmarker, LISTMARKER_SIZE, " %s ", "+"); + } else { + snprintf(listmarker, LISTMARKER_SIZE, " %s ", "-"); + } } else { list_number = cmark_node_get_list_start(node->parent); list_delim = cmark_node_get_list_delim(node->parent); @@ -237,13 +245,8 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node, marker_width = strlen(listmarker); } if (entering) { - if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) { - LIT(" - "); - renderer->begin_content = true; - } else { - LIT(listmarker); - renderer->begin_content = true; - } + LIT(listmarker); + renderer->begin_content = true; for (i = marker_width; i--;) { cmark_strbuf_putc(renderer->prefix, ' '); } diff --git a/src/node.c b/src/node.c index c6c29028e..e44403c07 100644 --- a/src/node.c +++ b/src/node.c @@ -402,6 +402,52 @@ int cmark_node_set_list_delim(cmark_node *node, cmark_delim_type delim) { } } +cmark_marker_type cmark_node_get_list_marker(cmark_node *node) { + if (node == NULL) { + return CMARK_NO_MARKER; + } + + if (node->type == CMARK_NODE_LIST) { + return node->as.list.marker; + } else { + return CMARK_NO_MARKER; + } +} + +int cmark_node_set_list_marker(cmark_node *node, cmark_marker_type marker) { + if (node == NULL) { + return 0; + } + + if (node->type != CMARK_NODE_LIST) { + return 0; + } + + if (cmark_node_get_list_type(node) == CMARK_ORDERED_LIST && + marker == CMARK_NUMERIC_MARKER) { + node->as.list.bullet_char = 0; + node->as.list.marker = CMARK_NUMERIC_MARKER; + return 1; + } else if (cmark_node_get_list_type(node) == CMARK_BULLET_LIST && + marker == CMARK_ASTERISK_MARKER) { + node->as.list.bullet_char = '*'; + node->as.list.marker = marker; + return 1; + } else if (cmark_node_get_list_type(node) == CMARK_BULLET_LIST && + marker == CMARK_HYPHEN_MARKER) { + node->as.list.bullet_char = '-'; + node->as.list.marker = marker; + return 1; + } else if (cmark_node_get_list_type(node) == CMARK_BULLET_LIST && + marker == CMARK_PLUS_MARKER) { + node->as.list.bullet_char = '+'; + node->as.list.marker = marker; + return 1; + } else { + return 0; + } +} + int cmark_node_get_list_start(cmark_node *node) { if (node == NULL) { return 0; diff --git a/src/node.h b/src/node.h index 65d857f0b..c7f152fb3 100644 --- a/src/node.h +++ b/src/node.h @@ -20,6 +20,7 @@ typedef struct { cmark_delim_type delimiter; unsigned char bullet_char; bool tight; + cmark_marker_type marker; } cmark_list; typedef struct { diff --git a/src/xml.c b/src/xml.c index 4898cd2e8..8086a7609 100644 --- a/src/xml.c +++ b/src/xml.c @@ -35,6 +35,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type, cmark_strbuf *xml = state->xml; bool literal = false; cmark_delim_type delim; + cmark_marker_type marker; bool entering = (ev_type == CMARK_EVENT_ENTER); char buffer[BUFFER_SIZE]; @@ -79,9 +80,21 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type, } else if (delim == CMARK_PERIOD_DELIM) { cmark_strbuf_puts(xml, " delim=\"period\""); } + marker = cmark_node_get_list_marker(node); + if (marker == CMARK_NUMERIC_MARKER) { + cmark_strbuf_puts(xml, " marker=\"numeric\""); + } break; case CMARK_BULLET_LIST: cmark_strbuf_puts(xml, " type=\"bullet\""); + marker = cmark_node_get_list_marker(node); + if (marker == CMARK_ASTERISK_MARKER) { + cmark_strbuf_puts(xml, " marker=\"asterisk\""); + } else if (marker == CMARK_HYPHEN_MARKER) { + cmark_strbuf_puts(xml, " marker=\"hyphen\""); + } else if (marker == CMARK_PLUS_MARKER) { + cmark_strbuf_puts(xml, " marker=\"plus\""); + } break; default: break; diff --git a/wrappers/wrapper.rkt b/wrappers/wrapper.rkt index d9b34e849..5d0341f46 100644 --- a/wrappers/wrapper.rkt +++ b/wrappers/wrapper.rkt @@ -24,6 +24,8 @@ (_enum '(no_list bullet_list ordered_list))) (define _cmark_delim_type (_enum '(no_delim period_delim paren_delim))) + (define _cmark_marker_type + (_enum '(no_marker numeric_marker asterisk_marker hyphen_marker plus_marker))) (define _cmark_opts (_bitmask '(sourcepos = 1 hardbreaks = 2 normalize = 4 smart = 8))) @@ -62,6 +64,8 @@ (defcmark cmark_node_set_list_type (_fun _node _cmark_list_type -> _bool)) (defcmark cmark_node_get_list_delim (_fun _node -> _cmark_delim_type)) (defcmark cmark_node_set_list_delim (_fun _node _cmark_delim_type -> _bool)) + (defcmark cmark_node_get_list_marker (_fun _node -> _cmark_marker_type)) + (defcmark cmark_node_set_list_marker (_fun _node _cmark_marker_type -> _bool)) (defcmark cmark_node_get_list_start (_fun _node -> _int)) (defcmark cmark_node_set_list_start (_fun _node _int -> _bool)) (defcmark cmark_node_get_list_tight (_fun _node -> _bool)) @@ -110,7 +114,7 @@ (define-getters+setters getters+setters [header header_level] [code-block fence_info] [link url title] [image url title] - [list list_type list_delim list_start list_tight]) + [list list_type list_delim list_marker list_start list_tight]) (provide cmark->sexpr) (define (cmark->sexpr node)