static cmark_node *try_opening_code_block(cmark_syntax_extension *self, bool indented, cmark_parser *parser, cmark_node *parent, const char *input) { cmark_node *ret = NULL; cmark_bufsize_t matched = scan_open_gtkdoc_code_block(input, cmark_parser_get_first_nonspace(parser)); if (!indented && matched) { ret = cmark_parser_add_child(parser, parent, CMARK_NODE_CODE_BLOCK, cmark_parser_get_offset(parser)); cmark_node_set_syntax_extension(ret, self); cmark_node_set_fenced(ret, true, 2, cmark_parser_get_first_nonspace(parser) - cmark_parser_get_offset(parser), 0); cmark_parser_advance_offset(parser, input, matched, false); matched = scan_language_comment(input, matched); if (matched) { cmark_strbuf *lang = cmark_strbuf_new(32); cmark_strbuf_put(lang, (unsigned char *) input + 17, matched - 20); /* Will be transformed to fence info */ cmark_node_set_string_content(ret, cmark_strbuf_get(lang)); cmark_strbuf_free(lang); cmark_parser_advance_offset(parser, input, matched, false); } } return ret; }
static cmark_node *fixup_nodes(cmark_inline_parser *inline_parser, cmark_node *parent, int size) { int node_text_len; cmark_node *prev = NULL; cmark_node *tmp; int name_size = size; cmark_strbuf *name; for (prev = cmark_node_last_child(parent); prev; prev = cmark_node_previous(prev)) { if (cmark_node_get_type(prev) == CMARK_NODE_TEXT) { const char *text = cmark_node_get_literal(prev); node_text_len = strlen(text); size -= node_text_len; if (size <= 0) { if (size < 0) { char *split_text = my_strndup(text, size * -1); cmark_node *split = cmark_node_new(CMARK_NODE_TEXT); cmark_node_set_literal(split, split_text); free(split_text); split_text = my_strndup(text + (size * - 1), node_text_len - size); cmark_node_set_literal(prev, split_text); free(split_text); cmark_node_insert_before(prev, split); } break; } } else { return NULL; } } name = cmark_strbuf_new(name_size + 1); tmp = prev; while (tmp) { cmark_node *next = cmark_node_next(tmp); cmark_strbuf_puts(name, cmark_node_get_literal(tmp)); if (tmp != prev) cmark_node_free(tmp); tmp = next; } cmark_node_set_type(prev, CMARK_NODE_LINK); cmark_node_set_url(prev, cmark_strbuf_get(name)); cmark_strbuf_free(name); return prev; }
static cmark_node *symbol_link_match(cmark_syntax_extension *self, cmark_parser *parser, cmark_node *parent, cmark_inline_parser *inline_parser) { cmark_node *link = NULL; char *symbol_name = NULL; NamedLink *named_link = NULL; int start_offset = cmark_inline_parser_get_offset(inline_parser); ParsingContext context; context.parser = inline_parser; context.allow_dashes = 0; if (start_offset > 0) { char prev_char = cmark_inline_parser_peek_at( inline_parser, start_offset - 1); if (prev_char && prev_char != ' ' && prev_char != '\t' && prev_char != '\n') return NULL; } cmark_inline_parser_advance_offset(inline_parser); symbol_name = cmark_inline_parser_take_while(inline_parser, (CMarkInlinePredicate) is_valid_symbol_name, &context); if (!symbol_name) goto done; named_link = PRIV(self)->link_resolve_func(symbol_name); if (!named_link || !named_link->ref) { int actual_line, actual_col; translate_sourcepos(get_first_parent_block(parent), start_offset, &actual_line, &actual_col); cmark_strbuf *message = cmark_strbuf_new(0); cmark_strbuf_puts(message, "Trying to link to non-existing symbol ‘"); cmark_strbuf_puts(message, symbol_name); cmark_strbuf_puts(message, "’"); diagnose("gtk-doc-bad-link", cmark_strbuf_get(message), actual_line - 1, actual_col - 1); cmark_strbuf_free(message); link = cmark_node_new (CMARK_NODE_TEXT); cmark_node_set_literal (link, symbol_name); } else { link = cmark_node_new(CMARK_NODE_LINK); } cmark_node_set_url(link, symbol_name); done: free(symbol_name); free_named_link(named_link); return link; }
static cmark_node *fixup_nodes(cmark_syntax_extension *self, cmark_parser *parser, cmark_inline_parser *inline_parser, cmark_node *parent, int start_offset, int size) { int node_text_len; cmark_node *prev = NULL; cmark_node *tmp; int name_size = size; cmark_strbuf *name; NamedLink *named_link; for (prev = cmark_node_last_child(parent); prev; prev = cmark_node_previous(prev)) { if (cmark_node_get_type(prev) == CMARK_NODE_TEXT) { const char *text = cmark_node_get_literal(prev); node_text_len = strlen(text); size -= node_text_len; if (size <= 0) { if (size < 0) { char *split_text = my_strndup(text, size * -1); cmark_node *split = cmark_node_new(CMARK_NODE_TEXT); cmark_node_set_literal(split, split_text); free(split_text); split_text = my_strndup(text + (size * - 1), node_text_len - size); cmark_node_set_literal(prev, split_text); free(split_text); cmark_node_insert_before(prev, split); } break; } } else { return NULL; } } name = cmark_strbuf_new(name_size + 1); tmp = prev; while (tmp) { cmark_node *next = cmark_node_next(tmp); cmark_strbuf_puts(name, cmark_node_get_literal(tmp)); if (tmp != prev) cmark_node_free(tmp); tmp = next; } named_link = PRIV(self)->link_resolve_func(cmark_strbuf_get(name)); if (!named_link || !named_link->ref) { int actual_line, actual_col; translate_sourcepos(get_first_parent_block(parent), start_offset, &actual_line, &actual_col); cmark_strbuf *message = cmark_strbuf_new(0); cmark_strbuf_puts(message, "Trying to link to non-existing symbol ‘"); cmark_strbuf_puts(message, cmark_strbuf_get(name)); cmark_strbuf_puts(message, "’"); diagnose("gtk-doc-bad-link", cmark_strbuf_get(message), actual_line - 1, actual_col - 1); cmark_strbuf_free(message); cmark_node_set_literal(prev, cmark_strbuf_get(name)); cmark_strbuf_free(name); return prev; } free_named_link(named_link); cmark_node_set_type(prev, CMARK_NODE_LINK); cmark_node_set_url(prev, cmark_strbuf_get(name)); cmark_strbuf_free(name); return prev; }