diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast.h | 4 | ||||
-rw-r--r-- | src/blocks.c | 237 | ||||
-rw-r--r-- | src/cmark.c | 23 | ||||
-rw-r--r-- | src/cmark.h | 19 | ||||
-rw-r--r-- | src/html/html.c | 45 | ||||
-rw-r--r-- | src/main.c | 4 | ||||
-rw-r--r-- | src/node.h | 30 | ||||
-rw-r--r-- | src/print.c | 45 |
8 files changed, 210 insertions, 197 deletions
@@ -89,8 +89,8 @@ struct cmark_node_block { struct cmark_doc_parser { struct cmark_reference_map *refmap; - struct cmark_node_block* root; - struct cmark_node_block* current; + struct cmark_node* root; + struct cmark_node* current; int line_number; cmark_strbuf *curline; }; diff --git a/src/blocks.c b/src/blocks.c index 45d43ec..9008070 100644 --- a/src/blocks.c +++ b/src/blocks.c @@ -6,6 +6,7 @@ #include "config.h" #include "ast.h" #include "cmark.h" +#include "node.h" #include "references.h" #include "utf8.h" #include "scanners.h" @@ -17,13 +18,13 @@ #define CODE_INDENT 4 #define peek_at(i, n) (i)->data[n] -static node_block* make_block(cmark_block_tag tag, int start_line, int start_column) +static cmark_node* make_block(cmark_node_type tag, int start_line, int start_column) { - node_block* e; + cmark_node* e; - e = (node_block *)calloc(1, sizeof(*e)); + e = (cmark_node *)calloc(1, sizeof(*e)); if(e != NULL) { - e->tag = tag; + e->type = tag; e->open = true; e->start_line = start_line; e->start_column = start_column; @@ -34,17 +35,17 @@ static node_block* make_block(cmark_block_tag tag, int start_line, int start_col return e; } -// Create a root document node_block. -static node_block* make_document() +// Create a root document cmark_node. +static cmark_node* make_document() { - node_block *e = make_block(BLOCK_DOCUMENT, 1, 1); + cmark_node *e = make_block(NODE_DOCUMENT, 1, 1); return e; } cmark_doc_parser *cmark_new_doc_parser() { cmark_doc_parser *parser = (cmark_doc_parser*)malloc(sizeof(cmark_doc_parser)); - node_block *document = make_document(); + cmark_node *document = make_document(); strbuf *line = (strbuf*)malloc(sizeof(strbuf)); cmark_strbuf_init(line, 256); @@ -65,7 +66,7 @@ void cmark_free_doc_parser(cmark_doc_parser *parser) free(parser); } -static void finalize(cmark_doc_parser *parser, node_block* b, int line_number); +static void finalize(cmark_doc_parser *parser, cmark_node* b, int line_number); // Returns true if line has only space characters, else false. static bool is_blank(strbuf *s, int offset) @@ -85,26 +86,26 @@ static bool is_blank(strbuf *s, int offset) return true; } -static inline bool can_contain(cmark_block_tag parent_type, cmark_block_tag child_type) +static inline bool can_contain(cmark_node_type parent_type, cmark_node_type child_type) { - return ( parent_type == BLOCK_DOCUMENT || - parent_type == BLOCK_BQUOTE || - parent_type == BLOCK_LIST_ITEM || - (parent_type == BLOCK_LIST && child_type == BLOCK_LIST_ITEM) ); + return ( parent_type == NODE_DOCUMENT || + parent_type == NODE_BQUOTE || + parent_type == NODE_LIST_ITEM || + (parent_type == NODE_LIST && child_type == NODE_LIST_ITEM) ); } -static inline bool accepts_lines(int block_type) +static inline bool accepts_lines(cmark_node_type block_type) { - return (block_type == BLOCK_PARAGRAPH || - block_type == BLOCK_ATX_HEADER || - block_type == BLOCK_INDENTED_CODE || - block_type == BLOCK_FENCED_CODE); + return (block_type == NODE_PARAGRAPH || + block_type == NODE_ATX_HEADER || + block_type == NODE_INDENTED_CODE || + block_type == NODE_FENCED_CODE); } -static void add_line(node_block* node_block, chunk *ch, int offset) +static void add_line(cmark_node* cmark_node, chunk *ch, int offset) { - assert(node_block->open); - strbuf_put(&node_block->string_content, ch->data + offset, ch->len - offset); + assert(cmark_node->open); + strbuf_put(&cmark_node->string_content, ch->data + offset, ch->len - offset); } static void remove_trailing_blank_lines(strbuf *ln) @@ -128,27 +129,27 @@ static void remove_trailing_blank_lines(strbuf *ln) strbuf_truncate(ln, i); } -// Check to see if a node_block ends with a blank line, descending +// Check to see if a cmark_node ends with a blank line, descending // if needed into lists and sublists. -static bool ends_with_blank_line(node_block* node_block) +static bool ends_with_blank_line(cmark_node* cmark_node) { - if (node_block->last_line_blank) { + if (cmark_node->last_line_blank) { return true; } - if ((node_block->tag == BLOCK_LIST || node_block->tag == BLOCK_LIST_ITEM) && node_block->last_child) { - return ends_with_blank_line(node_block->last_child); + if ((cmark_node->type == NODE_LIST || cmark_node->type == NODE_LIST_ITEM) && cmark_node->last_child) { + return ends_with_blank_line(cmark_node->last_child); } else { return false; } } // Break out of all containing lists -static int break_out_of_lists(cmark_doc_parser *parser, node_block ** bptr, int line_number) +static int break_out_of_lists(cmark_doc_parser *parser, cmark_node ** bptr, int line_number) { - node_block *container = *bptr; - node_block *b = parser->root; - // find first containing BLOCK_LIST: - while (b && b->tag != BLOCK_LIST) { + cmark_node *container = *bptr; + cmark_node *b = parser->root; + // find first containing NODE_LIST: + while (b && b->type != NODE_LIST) { b = b->last_child; } if (b) { @@ -163,15 +164,15 @@ static int break_out_of_lists(cmark_doc_parser *parser, node_block ** bptr, int } -static void finalize(cmark_doc_parser *parser, node_block* b, int line_number) +static void finalize(cmark_doc_parser *parser, cmark_node* b, int line_number) { int firstlinelen; int pos; - node_block* item; - node_block* subitem; + cmark_node* item; + cmark_node* subitem; if (!b->open) - return; // don't do anything if the node_block is already closed + return; // don't do anything if the cmark_node is already closed b->open = false; if (line_number > b->start_line) { @@ -180,8 +181,8 @@ static void finalize(cmark_doc_parser *parser, node_block* b, int line_number) b->end_line = line_number; } - switch (b->tag) { - case BLOCK_PARAGRAPH: + switch (b->type) { + case NODE_PARAGRAPH: pos = 0; while (strbuf_at(&b->string_content, 0) == '[' && (pos = parse_reference_inline(&b->string_content, parser->refmap))) { @@ -189,16 +190,16 @@ static void finalize(cmark_doc_parser *parser, node_block* b, int line_number) strbuf_drop(&b->string_content, pos); } if (is_blank(&b->string_content, 0)) { - b->tag = BLOCK_REFERENCE_DEF; + b->type = NODE_REFERENCE_DEF; } break; - case BLOCK_INDENTED_CODE: + case NODE_INDENTED_CODE: remove_trailing_blank_lines(&b->string_content); strbuf_putc(&b->string_content, '\n'); break; - case BLOCK_FENCED_CODE: + case NODE_FENCED_CODE: // first line of contents becomes info firstlinelen = strbuf_strchr(&b->string_content, '\n', 0); @@ -215,9 +216,9 @@ static void finalize(cmark_doc_parser *parser, node_block* b, int line_number) strbuf_unescape(&b->as.code.info); break; - case BLOCK_LIST: // determine tight/loose status + case NODE_LIST: // determine tight/loose status b->as.list.tight = true; // tight by default - item = b->children; + item = b->first_child; while (item) { // check for non-final non-empty list item ending with blank line: @@ -227,7 +228,7 @@ static void finalize(cmark_doc_parser *parser, node_block* b, int line_number) } // recurse into children of list item, to see if there are // spaces between them: - subitem = item->children; + subitem = item->first_child; while (subitem) { if (ends_with_blank_line(subitem) && (item->next || subitem->next)) { @@ -249,27 +250,27 @@ static void finalize(cmark_doc_parser *parser, node_block* b, int line_number) } } -// Add a node_block as child of another. Return pointer to child. -static node_block* add_child(cmark_doc_parser *parser, node_block* parent, - cmark_block_tag block_type, int start_line, int start_column) +// Add a cmark_node as child of another. Return pointer to child. +static cmark_node* add_child(cmark_doc_parser *parser, cmark_node* parent, + cmark_node_type block_type, int start_line, int start_column) { assert(parent); - // if 'parent' isn't the kind of node_block that can accept this child, - // then back up til we hit a node_block that can. - while (!can_contain(parent->tag, block_type)) { + // if 'parent' isn't the kind of cmark_node that can accept this child, + // then back up til we hit a cmark_node that can. + while (!can_contain(parent->type, block_type)) { finalize(parser, parent, start_line); parent = parent->parent; } - node_block* child = make_block(block_type, start_line, start_column); + cmark_node* child = make_block(block_type, start_line, start_column); child->parent = parent; if (parent->last_child) { parent->last_child->next = child; child->prev = parent->last_child; } else { - parent->children = child; + parent->first_child = child; child->prev = NULL; } parent->last_child = child; @@ -279,21 +280,21 @@ static node_block* add_child(cmark_doc_parser *parser, node_block* parent, typedef struct BlockStack { struct BlockStack *previous; - node_block *next_sibling; + cmark_node *next_sibling; } block_stack; -// Walk through node_block and all children, recursively, parsing +// Walk through cmark_node and all children, recursively, parsing // string content into inline content where appropriate. -static void process_inlines(node_block* cur, reference_map *refmap) +static void process_inlines(cmark_node* cur, reference_map *refmap) { block_stack* stack = NULL; block_stack* newstack = NULL; while (cur != NULL) { - switch (cur->tag) { - case BLOCK_PARAGRAPH: - case BLOCK_ATX_HEADER: - case BLOCK_SETEXT_HEADER: + switch (cur->type) { + case NODE_PARAGRAPH: + case NODE_ATX_HEADER: + case NODE_SETEXT_HEADER: cur->inline_content = parse_inlines(&cur->string_content, refmap); break; @@ -301,13 +302,13 @@ static void process_inlines(node_block* cur, reference_map *refmap) break; } - if (cur->children) { + if (cur->first_child) { newstack = (block_stack*)malloc(sizeof(block_stack)); if (newstack == NULL) return; newstack->previous = stack; stack = newstack; stack->next_sibling = cur->next; - cur = cur->children; + cur = cur->first_child; } else { cur = cur->next; } @@ -329,11 +330,11 @@ static void process_inlines(node_block* cur, reference_map *refmap) // Attempts to parse a list item marker (bullet or enumerated). // On success, returns length of the marker, and populates // data with the details. On failure, returns 0. -static int parse_list_marker(chunk *input, int pos, struct ListData ** dataptr) +static int parse_list_marker(chunk *input, int pos, cmark_list **dataptr) { unsigned char c; int startpos; - struct ListData * data; + cmark_list *data; startpos = pos; c = peek_at(input, pos); @@ -343,7 +344,7 @@ static int parse_list_marker(chunk *input, int pos, struct ListData ** dataptr) if (!isspace(peek_at(input, pos))) { return 0; } - data = (struct ListData *)calloc(1, sizeof(*data)); + data = (cmark_list *)calloc(1, sizeof(*data)); if(data == NULL) { return 0; } else { @@ -368,7 +369,7 @@ static int parse_list_marker(chunk *input, int pos, struct ListData ** dataptr) if (!isspace(peek_at(input, pos))) { return 0; } - data = (struct ListData *)calloc(1, sizeof(*data)); + data = (cmark_list *)calloc(1, sizeof(*data)); if(data == NULL) { return 0; } else { @@ -392,7 +393,7 @@ static int parse_list_marker(chunk *input, int pos, struct ListData ** dataptr) } // Return 1 if list item belongs in list, else 0. -static int lists_match(struct ListData *list_data, struct ListData *item_data) +static int lists_match(cmark_list *list_data, cmark_list *item_data) { return (list_data->list_type == item_data->list_type && list_data->delimiter == item_data->delimiter && @@ -400,7 +401,7 @@ static int lists_match(struct ListData *list_data, struct ListData *item_data) list_data->bullet_char == item_data->bullet_char); } -static node_block *finalize_document(cmark_doc_parser *parser) +static cmark_node *finalize_document(cmark_doc_parser *parser) { while (parser->current != parser->root) { finalize(parser, parser->current, parser->line_number); @@ -413,12 +414,12 @@ static node_block *finalize_document(cmark_doc_parser *parser) return parser->root; } -extern node_block *cmark_parse_file(FILE *f) +extern cmark_node *cmark_parse_file(FILE *f) { unsigned char buffer[4096]; cmark_doc_parser *parser = cmark_new_doc_parser(); size_t offset; - node_block *document; + cmark_node *document; while (fgets((char *)buffer, sizeof(buffer), f)) { offset = strlen((char *)buffer); @@ -430,13 +431,13 @@ extern node_block *cmark_parse_file(FILE *f) return document; } -extern node_block *cmark_parse_document(const unsigned char *buffer, size_t len) +extern cmark_node *cmark_parse_document(const unsigned char *buffer, size_t len) { int linenum = 1; const unsigned char *end = buffer + len; size_t offset; cmark_doc_parser *parser = cmark_new_doc_parser(); - node_block *document; + cmark_node *document; while (buffer < end) { const unsigned char *eol = (unsigned char *)memchr(buffer, '\n', end - buffer); @@ -472,15 +473,15 @@ static void chop_trailing_hashtags(chunk *ch) void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, size_t bytes) { - node_block* last_matched_container; + cmark_node* last_matched_container; int offset = 0; int matched = 0; int lev = 0; int i; - struct ListData * data = NULL; + cmark_list *data = NULL; bool all_matched = true; - node_block* container; - node_block* cur = parser->current; + cmark_node* container; + cmark_node* cur = parser->current; bool blank = false; int first_nonspace; int indent; @@ -501,8 +502,8 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, parser->line_number++; - // for each containing node_block, try to parse the associated line start. - // bail out on failure: container will point to the last matching node_block. + // for each containing cmark_node, try to parse the associated line start. + // bail out on failure: container will point to the last matching cmark_node. while (container->last_child && container->last_child->open) { container = container->last_child; @@ -515,7 +516,7 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, indent = first_nonspace - offset; blank = peek_at(&input, first_nonspace) == '\n'; - if (container->tag == BLOCK_BQUOTE) { + if (container->type == NODE_BQUOTE) { matched = indent <= 3 && peek_at(&input, first_nonspace) == '>'; if (matched) { offset = first_nonspace + 1; @@ -525,7 +526,7 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, all_matched = false; } - } else if (container->tag == BLOCK_LIST_ITEM) { + } else if (container->type == NODE_LIST_ITEM) { if (indent >= container->as.list.marker_offset + container->as.list.padding) { @@ -537,7 +538,7 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, all_matched = false; } - } else if (container->tag == BLOCK_INDENTED_CODE) { + } else if (container->type == NODE_INDENTED_CODE) { if (indent >= CODE_INDENT) { offset += CODE_INDENT; @@ -547,13 +548,13 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, all_matched = false; } - } else if (container->tag == BLOCK_ATX_HEADER || - container->tag == BLOCK_SETEXT_HEADER) { + } else if (container->type == NODE_ATX_HEADER || + container->type == NODE_SETEXT_HEADER) { // a header can never contain more than one line all_matched = false; - } else if (container->tag == BLOCK_FENCED_CODE) { + } else if (container->type == NODE_FENCED_CODE) { // skip optional spaces of fence offset i = container->as.code.fence_offset; @@ -562,13 +563,13 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, i--; } - } else if (container->tag == BLOCK_HTML) { + } else if (container->type == NODE_HTML) { if (blank) { all_matched = false; } - } else if (container->tag == BLOCK_PARAGRAPH) { + } else if (container->type == NODE_PARAGRAPH) { if (blank) { container->last_line_blank = true; @@ -578,7 +579,7 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, } if (!all_matched) { - container = container->parent; // back up to last matching node_block + container = container->parent; // back up to last matching cmark_node break; } } @@ -590,9 +591,9 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, break_out_of_lists(parser, &container, parser->line_number); } - // unless last matched container is code node_block, try new container starts: - while (container->tag != BLOCK_FENCED_CODE && container->tag != BLOCK_INDENTED_CODE && - container->tag != BLOCK_HTML) { + // unless last matched container is code cmark_node, try new container starts: + while (container->type != NODE_FENCED_CODE && container->type != NODE_INDENTED_CODE && + container->type != NODE_HTML) { first_nonspace = offset; while (peek_at(&input, first_nonspace) == ' ') @@ -602,9 +603,9 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, blank = peek_at(&input, first_nonspace) == '\n'; if (indent >= CODE_INDENT) { - if (cur->tag != BLOCK_PARAGRAPH && !blank) { + if (cur->type != NODE_PARAGRAPH && !blank) { offset += CODE_INDENT; - container = add_child(parser, container, BLOCK_INDENTED_CODE, parser->line_number, offset + 1); + container = add_child(parser, container, NODE_INDENTED_CODE, parser->line_number, offset + 1); } else { // indent > 4 in lazy line break; } @@ -615,12 +616,12 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, // optional following character if (peek_at(&input, offset) == ' ') offset++; - container = add_child(parser, container, BLOCK_BQUOTE, parser->line_number, offset + 1); + container = add_child(parser, container, NODE_BQUOTE, parser->line_number, offset + 1); } else if ((matched = scan_atx_header_start(&input, first_nonspace))) { offset = first_nonspace + matched; - container = add_child(parser, container, BLOCK_ATX_HEADER, parser->line_number, offset + 1); + container = add_child(parser, container, NODE_ATX_HEADER, parser->line_number, offset + 1); int hashpos = chunk_strchr(&input, '#', first_nonspace); int level = 0; @@ -633,7 +634,7 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, } else if ((matched = scan_open_code_fence(&input, first_nonspace))) { - container = add_child(parser, container, BLOCK_FENCED_CODE, parser->line_number, first_nonspace + 1); + container = add_child(parser, container, NODE_FENCED_CODE, parser->line_number, first_nonspace + 1); container->as.code.fence_char = peek_at(&input, first_nonspace); container->as.code.fence_length = matched; container->as.code.fence_offset = first_nonspace - offset; @@ -641,24 +642,24 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, } else if ((matched = scan_html_block_tag(&input, first_nonspace))) { - container = add_child(parser, container, BLOCK_HTML, parser->line_number, first_nonspace + 1); + container = add_child(parser, container, NODE_HTML, parser->line_number, first_nonspace + 1); // note, we don't adjust offset because the tag is part of the text - } else if (container->tag == BLOCK_PARAGRAPH && + } else if (container->type == NODE_PARAGRAPH && (lev = scan_setext_header_line(&input, first_nonspace)) && // check that there is only one line in the paragraph: strbuf_strrchr(&container->string_content, '\n', strbuf_len(&container->string_content) - 2) < 0) { - container->tag = BLOCK_SETEXT_HEADER; + container->type = NODE_SETEXT_HEADER; container->as.header.level = lev; offset = input.len - 1; - } else if (!(container->tag == BLOCK_PARAGRAPH && !all_matched) && + } else if (!(container->type == NODE_PARAGRAPH && !all_matched) && (matched = scan_hrule(&input, first_nonspace))) { // it's only now that we know the line is not part of a setext header: - container = add_child(parser, container, BLOCK_HRULE, parser->line_number, first_nonspace + 1); + container = add_child(parser, container, NODE_HRULE, parser->line_number, first_nonspace + 1); finalize(parser, container, parser->line_number); container = container->parent; offset = input.len - 1; @@ -687,16 +688,16 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, data->marker_offset = indent; - if (container->tag != BLOCK_LIST || + if (container->type != NODE_LIST || !lists_match(&container->as.list, data)) { - container = add_child(parser, container, BLOCK_LIST, parser->line_number, + container = add_child(parser, container, NODE_LIST, parser->line_number, first_nonspace + 1); memcpy(&container->as.list, data, sizeof(*data)); } // add the list item - container = add_child(parser, container, BLOCK_LIST_ITEM, parser->line_number, + container = add_child(parser, container, NODE_LIST_ITEM, parser->line_number, first_nonspace + 1); /* TODO: static */ memcpy(&container->as.list, data, sizeof(*data)); @@ -705,7 +706,7 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, break; } - if (accepts_lines(container->tag)) { + if (accepts_lines(container->type)) { // if it's a line container, it can't contain other containers break; } @@ -721,18 +722,18 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, indent = first_nonspace - offset; blank = peek_at(&input, first_nonspace) == '\n'; - // node_block quote lines are never blank as they start with > + // cmark_node quote lines are never blank as they start with > // and we don't count blanks in fenced code for purposes of tight/loose // lists or breaking out of lists. we also don't set last_line_blank // on an empty list item. container->last_line_blank = (blank && - container->tag != BLOCK_BQUOTE && - container->tag != BLOCK_FENCED_CODE && - !(container->tag == BLOCK_LIST_ITEM && - container->children == NULL && + container->type != NODE_BQUOTE && + container->type != NODE_FENCED_CODE && + !(container->type == NODE_LIST_ITEM && + container->first_child == NULL && container->start_line == parser->line_number)); - node_block *cont = container; + cmark_node *cont = container; while (cont->parent) { cont->parent->last_line_blank = false; cont = cont->parent; @@ -741,7 +742,7 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, if (cur != last_matched_container && container == last_matched_container && !blank && - cur->tag == BLOCK_PARAGRAPH && + cur->type == NODE_PARAGRAPH && strbuf_len(&cur->string_content) > 0) { add_line(cur, &input, offset); @@ -755,11 +756,11 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, assert(cur != NULL); } - if (container->tag == BLOCK_INDENTED_CODE) { + if (container->type == NODE_INDENTED_CODE) { add_line(container, &input, offset); - } else if (container->tag == BLOCK_FENCED_CODE) { + } else if (container->type == NODE_FENCED_CODE) { matched = 0; if (indent <= 3 && @@ -777,7 +778,7 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, add_line(container, &input, offset); } - } else if (container->tag == BLOCK_HTML) { + } else if (container->type == NODE_HTML) { add_line(container, &input, offset); @@ -785,21 +786,21 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, // ??? do nothing - } else if (container->tag == BLOCK_ATX_HEADER) { + } else if (container->type == NODE_ATX_HEADER) { chop_trailing_hashtags(&input); add_line(container, &input, first_nonspace); finalize(parser, container, parser->line_number); container = container->parent; - } else if (accepts_lines(container->tag)) { + } else if (accepts_lines(container->type)) { add_line(container, &input, first_nonspace); - } else if (container->tag != BLOCK_HRULE && container->tag != BLOCK_SETEXT_HEADER) { + } else if (container->type != NODE_HRULE && container->type != NODE_SETEXT_HEADER) { // create paragraph container for line - container = add_child(parser, container, BLOCK_PARAGRAPH, parser->line_number, first_nonspace + 1); + container = add_child(parser, container, NODE_PARAGRAPH, parser->line_number, first_nonspace + 1); add_line(container, &input, first_nonspace); } else { @@ -812,7 +813,7 @@ void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, } -node_block *cmark_finish(cmark_doc_parser *parser) +cmark_node *cmark_finish(cmark_doc_parser *parser) { finalize_document(parser); strbuf_free(parser->curline); diff --git a/src/cmark.c b/src/cmark.c index 106abbf..328be9d 100644 --- a/src/cmark.c +++ b/src/cmark.c @@ -1,6 +1,7 @@ #include <stdlib.h> #include <assert.h> #include <stdio.h> +#include "node.h" #include "references.h" #include "html/houdini.h" #include "cmark.h" @@ -29,18 +30,6 @@ cmark_node_block *cmark_block_children(cmark_node_block *current) return current->children; } -void cmark_block_delete(cmark_node_block *current) -{ - if (current->prev) { - current->prev->next = current->next; - } - if (current->next) { - current->next->prev = current->prev; - } - current->next = NULL; - cmark_free_blocks(current); -} - void cmark_block_insert_before(cmark_node_block *new, cmark_node_block *current) { // Find last node in new: @@ -75,7 +64,7 @@ void cmark_block_insert_after(cmark_node_block *current, cmark_node_block *new) unsigned char *cmark_markdown_to_html(unsigned char *text, int len) { - node_block *blocks; + cmark_node *blocks; unsigned char *result; blocks = cmark_parse_document(text, len); @@ -156,19 +145,19 @@ unsigned char *cmark_clean_autolink(chunk *url, int is_email) } // Free a node_block list and any children. -void cmark_free_blocks(cmark_node_block *e) +void cmark_free_blocks(cmark_node *e) { - cmark_node_block * next; + cmark_node *next; while (e != NULL) { cmark_free_inlines(e->inline_content); strbuf_free(&e->string_content); - if (e->tag == CMARK_BLOCK_FENCED_CODE) { + if (e->type == NODE_FENCED_CODE) { strbuf_free(&e->as.code.info); } if (e->last_child) { // Splice children into list e->last_child->next = e->next; - e->next = e->children; + e->next = e->first_child; } next = e->next; free(e); diff --git a/src/cmark.h b/src/cmark.h index faa0cc0..147090a 100644 --- a/src/cmark.h +++ b/src/cmark.h @@ -47,6 +47,7 @@ typedef enum { CMARK_BLOCK_REFERENCE_DEF } cmark_block_tag; +typedef struct cmark_node cmark_node; typedef struct cmark_node_inl cmark_node_inl; typedef struct cmark_node_block cmark_node_block; typedef struct cmark_doc_parser cmark_doc_parser; @@ -58,31 +59,28 @@ CMARK_EXPORT void cmark_free_doc_parser(cmark_doc_parser *parser); CMARK_EXPORT -cmark_node_block *cmark_finish(cmark_doc_parser *parser); +cmark_node *cmark_finish(cmark_doc_parser *parser); CMARK_EXPORT void cmark_process_line(cmark_doc_parser *parser, const unsigned char *buffer, size_t bytes); CMARK_EXPORT -cmark_node_block *cmark_finish(cmark_doc_parser *parser); +cmark_node *cmark_parse_document(const unsigned char *buffer, size_t len); CMARK_EXPORT -cmark_node_block *cmark_parse_document(const unsigned char *buffer, size_t len); +cmark_node *cmark_parse_file(FILE *f); CMARK_EXPORT -cmark_node_block *cmark_parse_file(FILE *f); +void cmark_debug_print(cmark_node *root); CMARK_EXPORT -void cmark_debug_print(cmark_node_block *root); - -CMARK_EXPORT -unsigned char *cmark_render_html(cmark_node_block *root); +unsigned char *cmark_render_html(cmark_node *root); CMARK_EXPORT unsigned char *cmark_markdown_to_html(unsigned char *text, int len); CMARK_EXPORT -void cmark_free_blocks(cmark_node_block *e); +void cmark_free_blocks(cmark_node *e); CMARK_EXPORT void cmark_free_inlines(cmark_node_inl* e); @@ -100,9 +98,6 @@ CMARK_EXPORT cmark_node_block *cmark_block_children(cmark_node_block *current); CMARK_EXPORT -void cmark_block_delete(cmark_node_block *current); - -CMARK_EXPORT void cmark_block_insert_before(cmark_node_block *new, cmark_node_block *current); CMARK_EXPORT diff --git a/src/html/html.c b/src/html/html.c index 1969490..3749af6 100644 --- a/src/html/html.c +++ b/src/html/html.c @@ -5,6 +5,7 @@ #include "config.h" #include "cmark.h" +#include "node.h" #include "buffer.h" #include "ast.h" #include "debug.h" @@ -15,7 +16,7 @@ typedef struct RenderStack { char* literal; union { node_inl *inl; - node_block *block; + cmark_node *block; } next_sibling; bool tight; bool trim; @@ -49,7 +50,7 @@ static render_stack* push_inline(render_stack* rstack, } static render_stack* push_block(render_stack* rstack, - node_block* block, + cmark_node* block, char* literal, bool tight, bool trim) @@ -80,7 +81,7 @@ static render_stack* pop_render_stack(render_stack* rstack) return rstack; } -// Functions to convert node_block and inline lists to HTML strings. +// Functions to convert cmark_node and inline lists to HTML strings. static void escape_html(strbuf *dest, const unsigned char *source, int length) { @@ -246,23 +247,23 @@ static void inlines_to_html(strbuf *html, node_inl* ils) free_render_stack(rstack); } -// Convert a node_block list to HTML. Returns 0 on success, and sets result. -static void blocks_to_html(strbuf *html, node_block *b) +// Convert a cmark_node list to HTML. Returns 0 on success, and sets result. +static void blocks_to_html(strbuf *html, cmark_node *b) { - struct ListData *data; + cmark_list *data; render_stack* rstack = NULL; bool visit_children = false; bool tight = false; while(b != NULL) { visit_children = false; - switch(b->tag) { - case BLOCK_DOCUMENT: + switch(b->type) { + case NODE_DOCUMENT: rstack = push_block(rstack, b->next, "", false, false); visit_children = true; break; - case BLOCK_PARAGRAPH: + case NODE_PARAGRAPH: if (tight) { inlines_to_html(html, b->inline_content); } else { @@ -273,7 +274,7 @@ static void blocks_to_html(strbuf *html, node_block *b) } break; - case BLOCK_BQUOTE: + case NODE_BQUOTE: cr(html); strbuf_puts(html, "<blockquote>\n"); rstack = push_block(rstack, b->next, "</blockquote>\n", tight, false); @@ -281,14 +282,14 @@ static void blocks_to_html(strbuf *html, node_block *b) visit_children = true; break; - case BLOCK_LIST_ITEM: + case NODE_LIST_ITEM: cr(html); strbuf_puts(html, "<li>"); rstack = push_block(rstack, b->next, "</li>\n", tight, true); visit_children = true; break; - case BLOCK_LIST: + case NODE_LIST: // make sure a list starts at the beginning of the line: cr(html); data = &(b->as.list); @@ -308,21 +309,21 @@ static void blocks_to_html(strbuf *html, node_block *b) visit_children = true; break; - case BLOCK_ATX_HEADER: - case BLOCK_SETEXT_HEADER: + case NODE_ATX_HEADER: + case NODE_SETEXT_HEADER: cr(html); strbuf_printf(html, "<h%d>", b->as.header.level); inlines_to_html(html, b->inline_content); strbuf_printf(html, "</h%d>\n", b->as.header.level); break; - case BLOCK_INDENTED_CODE: - case BLOCK_FENCED_CODE: + case NODE_INDENTED_CODE: + case NODE_FENCED_CODE: cr(html); strbuf_puts(html, "<pre><code"); - if (b->tag == BLOCK_FENCED_CODE) { + if (b->type == NODE_FENCED_CODE) { strbuf *info = &b->as.code.info; if (strbuf_len(info) > 0) { @@ -341,22 +342,22 @@ static void blocks_to_html(strbuf *html, node_block *b) strbuf_puts(html, "</code></pre>\n"); break; - case BLOCK_HTML: + case NODE_HTML: strbuf_put(html, b->string_content.ptr, b->string_content.size); break; - case BLOCK_HRULE: + case NODE_HRULE: strbuf_puts(html, "<hr />\n"); break; - case BLOCK_REFERENCE_DEF: + case NODE_REFERENCE_DEF: break; default: assert(false); } if (visit_children) { - b = b->children; + b = b->first_child; } else { b = b->next; } @@ -374,7 +375,7 @@ static void blocks_to_html(strbuf *html, node_block *b) free_render_stack(rstack); } -unsigned char *cmark_render_html(node_block *root) +unsigned char *cmark_render_html(cmark_node *root) { unsigned char *result; strbuf html = GH_BUF_INIT; @@ -15,7 +15,7 @@ void print_usage() printf(" --version Print version\n"); } -static void print_document(node_block *document, bool ast) +static void print_document(cmark_node *document, bool ast) { unsigned char *result; if (ast) { @@ -36,7 +36,7 @@ int main(int argc, char *argv[]) unsigned char buffer[4096]; cmark_doc_parser *parser; size_t offset; - node_block *document; + cmark_node *document; parser = cmark_new_doc_parser(); files = (int *)malloc(argc * sizeof(*files)); @@ -86,6 +86,9 @@ struct cmark_node { bool open; bool last_line_blank; + // Temp + cmark_node_inl *inline_content; + cmark_strbuf string_content; union { @@ -96,8 +99,6 @@ struct cmark_node { } as; }; -typedef struct cmark_node cmark_node; - CMARK_EXPORT cmark_node_type cmark_node_get_type(cmark_node *node); @@ -135,6 +136,31 @@ cmark_node_prepend_child(cmark_node *node, cmark_node *child); CMARK_EXPORT int cmark_node_append_child(cmark_node *node, cmark_node *child); +#define NODE_DOCUMENT CMARK_NODE_DOCUMENT +#define NODE_BQUOTE CMARK_NODE_BQUOTE +#define NODE_LIST CMARK_NODE_LIST +#define NODE_LIST_ITEM CMARK_NODE_LIST_ITEM +#define NODE_FENCED_CODE CMARK_NODE_FENCED_CODE +#define NODE_INDENTED_CODE CMARK_NODE_INDENTED_CODE +#define NODE_HTML CMARK_NODE_HTML +#define NODE_PARAGRAPH CMARK_NODE_PARAGRAPH +#define NODE_ATX_HEADER CMARK_NODE_ATX_HEADER +#define NODE_SETEXT_HEADER CMARK_NODE_SETEXT_HEADER +#define NODE_HRULE CMARK_NODE_HRULE +#define NODE_REFERENCE_DEF CMARK_NODE_REFERENCE_DEF + +#define NODE_STRING CMARK_NODE_STRING +#define NODE_SOFTBREAK CMARK_NODE_SOFTBREAK +#define NODE_LINEBREAK CMARK_NODE_LINEBREAK +#define NODE_INLINE_CODE CMARK_NODE_INLINE_CODE +#define NODE_INLINE_HTML CMARK_NODE_INLINE_HTML +#define NODE_EMPH CMARK_NODE_EMPH +#define NODE_STRONG CMARK_NODE_STRONG +#define NODE_LINK CMARK_NODE_LINK +#define NODE_IMAGE CMARK_NODE_IMAGE + +#define NODE_LINK_LABEL CMARK_NODE_LINK_LABEL + #ifdef __cplusplus } #endif diff --git a/src/print.c b/src/print.c index 28a173e..ab19ab7 100644 --- a/src/print.c +++ b/src/print.c @@ -3,6 +3,7 @@ #include <string.h> #include "ast.h" #include "cmark.h" +#include "node.h" #include "debug.h" static void print_str(const unsigned char *s, int len) @@ -91,11 +92,11 @@ static void print_inlines(node_inl* ils, int indent) } } -// Functions to pretty-print inline and node_block lists, for debugging. +// Functions to pretty-print inline and cmark_node lists, for debugging. // Prettyprint an inline list, for debugging. -static void print_blocks(node_block* b, int indent) +static void print_blocks(cmark_node* b, int indent) { - struct ListData *data; + cmark_list *data; int i; while(b != NULL) { @@ -103,20 +104,20 @@ static void print_blocks(node_block* b, int indent) putchar(' '); } - switch(b->tag) { - case BLOCK_DOCUMENT: + switch(b->type) { + case NODE_DOCUMENT: printf("document\n"); - print_blocks(b->children, indent + 2); + print_blocks(b->first_child, indent + 2); break; - case BLOCK_BQUOTE: + case NODE_BQUOTE: printf("block_quote\n"); - print_blocks(b->children, indent + 2); + print_blocks(b->first_child, indent + 2); break; - case BLOCK_LIST_ITEM: + case NODE_LIST_ITEM: printf("list_item\n"); - print_blocks(b->children, indent + 2); + print_blocks(b->first_child, indent + 2); break; - case BLOCK_LIST: + case NODE_LIST: data = &(b->as.list); if (data->list_type == CMARK_ORDERED_LIST) { printf("list (type=ordered tight=%s start=%d delim=%s)\n", @@ -128,29 +129,29 @@ static void print_blocks(node_block* b, int indent) (data->tight ? "true" : "false"), data->bullet_char); } - print_blocks(b->children, indent + 2); + print_blocks(b->first_child, indent + 2); break; - case BLOCK_ATX_HEADER: + case NODE_ATX_HEADER: printf("atx_header (level=%d)\n", b->as.header.level); print_inlines(b->inline_content, indent + 2); break; - case BLOCK_SETEXT_HEADER: + case NODE_SETEXT_HEADER: printf("setext_header (level=%d)\n", b->as.header.level); print_inlines(b->inline_content, indent + 2); break; - case BLOCK_PARAGRAPH: + case NODE_PARAGRAPH: printf("paragraph\n"); print_inlines(b->inline_content, indent + 2); break; - case BLOCK_HRULE: + case NODE_HRULE: printf("hrule\n"); break; - case BLOCK_INDENTED_CODE: + case NODE_INDENTED_CODE: printf("indented_code "); print_str(b->string_content.ptr, -1); putchar('\n'); break; - case BLOCK_FENCED_CODE: + case NODE_FENCED_CODE: printf("fenced_code length=%d info=", b->as.code.fence_length); print_str(b->as.code.info.ptr, -1); @@ -158,23 +159,23 @@ static void print_blocks(node_block* b, int indent) print_str(b->string_content.ptr, -1); putchar('\n'); break; - case BLOCK_HTML: + case NODE_HTML: printf("html_block "); print_str(b->string_content.ptr, -1); putchar('\n'); break; - case BLOCK_REFERENCE_DEF: + case NODE_REFERENCE_DEF: printf("reference_def\n"); break; default: - printf("# NOT IMPLEMENTED (%d)\n", b->tag); + printf("# NOT IMPLEMENTED (%d)\n", b->type); break; } b = b->next; } } -void cmark_debug_print(node_block *root) +void cmark_debug_print(cmark_node *root) { print_blocks(root, 0); } |