int cmark_node_set_literal(cmark_node *node, const char *content) { if (node == NULL) { return 0; } switch (node->type) { case NODE_HTML: case NODE_TEXT: case NODE_INLINE_HTML: case NODE_CODE: cmark_chunk_set_cstr(&node->as.literal, content); return 1; case NODE_CODE_BLOCK: cmark_chunk_set_cstr(&node->as.code.literal, content); return 1; default: break; } return 0; }
int cmark_node_set_fence_info(cmark_node *node, const char *info) { if (node == NULL) { return 0; } if (node->type == CMARK_NODE_CODE_BLOCK) { cmark_chunk_set_cstr(NODE_MEM(node), &node->as.code.info, info); return 1; } else { return 0; } }
int cmark_node_set_on_exit(cmark_node *node, const char *on_exit) { if (node == NULL) { return 0; } switch (node->type) { case CMARK_NODE_CUSTOM_INLINE: case CMARK_NODE_CUSTOM_BLOCK: cmark_chunk_set_cstr(NODE_MEM(node), &node->as.custom.on_exit, on_exit); return 1; default: break; } return 0; }
int cmark_node_set_title(cmark_node *node, const char *title) { if (node == NULL) { return 0; } switch (node->type) { case CMARK_NODE_LINK: case CMARK_NODE_IMAGE: cmark_chunk_set_cstr(NODE_MEM(node), &node->as.link.title, title); return 1; default: break; } return 0; }
int cmark_node_set_string_content(cmark_node *node, const char *content) { switch (node->type) { case NODE_INDENTED_CODE: case NODE_FENCED_CODE: case NODE_HTML: cmark_strbuf_sets(&node->string_content, content); return 1; case NODE_STRING: case NODE_INLINE_HTML: case NODE_INLINE_CODE: cmark_chunk_set_cstr(&node->as.literal, content); return 1; default: break; } return 0; }
static void S_out(cmark_renderer *renderer, cmark_node *node, const char *source, bool wrap, cmark_escaping escape) { int length = (int)strlen(source); unsigned char nextc; int32_t c; int i = 0; int last_nonspace; int len; cmark_chunk remainder = cmark_chunk_literal(""); int k = renderer->buffer->size - 1; cmark_syntax_extension *ext = NULL; cmark_node *n = node; while (n && !ext) { ext = n->extension; if (!ext) n = n->parent; } if (ext && !ext->commonmark_escape_func) ext = NULL; wrap = wrap && !renderer->no_linebreaks; if (renderer->in_tight_list_item && renderer->need_cr > 1) { renderer->need_cr = 1; } while (renderer->need_cr) { if (k < 0 || renderer->buffer->ptr[k] == '\n') { k -= 1; } else { cmark_strbuf_putc(renderer->buffer, '\n'); if (renderer->need_cr > 1) { cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr, renderer->prefix->size); } } renderer->column = 0; renderer->begin_line = true; renderer->begin_content = true; renderer->need_cr -= 1; } while (i < length) { if (renderer->begin_line) { cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr, renderer->prefix->size); // note: this assumes prefix is ascii: renderer->column = renderer->prefix->size; } len = cmark_utf8proc_iterate((const uint8_t *)source + i, length - i, &c); if (len == -1) { // error condition return; // return without rendering rest of string } if (ext && ext->commonmark_escape_func(ext, node, c)) cmark_strbuf_putc(renderer->buffer, '\\'); nextc = source[i + len]; if (c == 32 && wrap) { if (!renderer->begin_line) { last_nonspace = renderer->buffer->size; cmark_strbuf_putc(renderer->buffer, ' '); renderer->column += 1; renderer->begin_line = false; renderer->begin_content = false; // skip following spaces while (source[i + 1] == ' ') { i++; } // We don't allow breaks that make a digit the first character // because this causes problems with commonmark output. if (!cmark_isdigit(source[i + 1])) { renderer->last_breakable = last_nonspace; } } } else if (c == 10) { cmark_strbuf_putc(renderer->buffer, '\n'); renderer->column = 0; renderer->begin_line = true; renderer->begin_content = true; renderer->last_breakable = 0; } else if (escape == LITERAL) { cmark_render_code_point(renderer, c); renderer->begin_line = false; // we don't set 'begin_content' to false til we've // finished parsing a digit. Reason: in commonmark // we need to escape a potential list marker after // a digit: renderer->begin_content = renderer->begin_content && cmark_isdigit((char)c) == 1; } else { (renderer->outc)(renderer, node, escape, c, nextc); renderer->begin_line = false; renderer->begin_content = renderer->begin_content && cmark_isdigit((char)c) == 1; } // If adding the character went beyond width, look for an // earlier place where the line could be broken: if (renderer->width > 0 && renderer->column > renderer->width && !renderer->begin_line && renderer->last_breakable > 0) { // copy from last_breakable to remainder cmark_chunk_set_cstr(renderer->mem, &remainder, (char *)renderer->buffer->ptr + renderer->last_breakable + 1); // truncate at last_breakable cmark_strbuf_truncate(renderer->buffer, renderer->last_breakable); // add newline, prefix, and remainder cmark_strbuf_putc(renderer->buffer, '\n'); cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr, renderer->prefix->size); cmark_strbuf_put(renderer->buffer, remainder.data, remainder.len); renderer->column = renderer->prefix->size + remainder.len; cmark_chunk_free(renderer->mem, &remainder); renderer->last_breakable = 0; renderer->begin_line = false; renderer->begin_content = false; } i += len; } }
static void S_out(cmark_renderer *renderer, const char *source, bool wrap, cmark_escaping escape) { int length = cmark_strbuf_safe_strlen(source); unsigned char nextc; int32_t c; int i = 0; int len; cmark_chunk remainder = cmark_chunk_literal(""); int k = renderer->buffer->size - 1; wrap = wrap && !renderer->no_wrap; if (renderer->in_tight_list_item && renderer->need_cr > 1) { renderer->need_cr = 1; } while (renderer->need_cr) { if (k < 0 || renderer->buffer->ptr[k] == '\n') { k -= 1; } else { cmark_strbuf_putc(renderer->buffer, '\n'); if (renderer->need_cr > 1) { cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr, renderer->prefix->size); } } renderer->column = 0; renderer->begin_line = true; renderer->need_cr -= 1; } while (i < length) { if (renderer->begin_line) { cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr, renderer->prefix->size); // note: this assumes prefix is ascii: renderer->column = renderer->prefix->size; } len = utf8proc_iterate((const uint8_t *)source + i, length - i, &c); if (len == -1) { // error condition return; // return without rendering rest of string } nextc = source[i + len]; if (c == 32 && wrap) { if (!renderer->begin_line) { cmark_strbuf_putc(renderer->buffer, ' '); renderer->column += 1; renderer->begin_line = false; renderer->last_breakable = renderer->buffer->size - 1; // skip following spaces while (source[i + 1] == ' ') { i++; } } } else if (c == 10) { cmark_strbuf_putc(renderer->buffer, '\n'); renderer->column = 0; renderer->begin_line = true; renderer->last_breakable = 0; } else if (escape == LITERAL) { cmark_render_code_point(renderer, c); renderer->begin_line = false; } else { (renderer->outc)(renderer, escape, c, nextc); renderer->begin_line = false; } // If adding the character went beyond width, look for an // earlier place where the line could be broken: if (renderer->width > 0 && renderer->column > renderer->width && !renderer->begin_line && renderer->last_breakable > 0) { // copy from last_breakable to remainder cmark_chunk_set_cstr(&remainder, (char *) renderer->buffer->ptr + renderer->last_breakable + 1); // truncate at last_breakable cmark_strbuf_truncate(renderer->buffer, renderer->last_breakable); // add newline, prefix, and remainder cmark_strbuf_putc(renderer->buffer, '\n'); cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr, renderer->prefix->size); cmark_strbuf_put(renderer->buffer, remainder.data, remainder.len); renderer->column = renderer->prefix->size + remainder.len; cmark_chunk_free(&remainder); renderer->last_breakable = 0; renderer->begin_line = false; } i += len; } }