Beispiel #1
0
char *cmark_render_xml(cmark_node *root, long options)
{
	char *result;
	cmark_strbuf xml = GH_BUF_INIT;
	cmark_event_type ev_type;
	cmark_node *cur;
	struct render_state state = { &xml, 0 };

	if (options & CMARK_OPT_NORMALIZE) {
		cmark_consolidate_text_nodes(root);
	}

	cmark_iter *iter = cmark_iter_new(root);

	cmark_strbuf_puts(state.xml,
	                  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
	cmark_strbuf_puts(state.xml,
	                  "<!DOCTYPE CommonMark SYSTEM \"CommonMark.dtd\">\n");
	while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
		cur = cmark_iter_get_node(iter);
		S_render_node(cur, ev_type, &state, options);
	}
	result = (char *)cmark_strbuf_detach(&xml);

	cmark_iter_free(iter);
	cmark_strbuf_free(&xml);
	return result;
}
static cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser, cmark_node *root) {
  cmark_iter *iter;
  cmark_event_type ev;
  cmark_node *node;
  bool in_link = false;

  cmark_consolidate_text_nodes(root);
  iter = cmark_iter_new(root);

  while ((ev = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
    node = cmark_iter_get_node(iter);
    if (in_link) {
      if (ev == CMARK_EVENT_EXIT && node->type == CMARK_NODE_LINK) {
        in_link = false;
      }
      continue;
    }

    if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_LINK) {
      in_link = true;
      continue;
    }

    if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_TEXT) {
      postprocess_text(parser, node, 0);
    }
  }

  cmark_iter_free(iter);

  return root;
}
Beispiel #3
0
static bool is_autolink(cmark_node *node) {
  cmark_chunk *title;
  cmark_chunk *url;
  cmark_node *link_text;
  char *realurl;
  int realurllen;

  if (node->type != CMARK_NODE_LINK) {
    return false;
  }

  url = &node->as.link.url;
  if (url->len == 0 || scan_scheme(url, 0) == 0) {
    return false;
  }

  title = &node->as.link.title;
  // if it has a title, we can't treat it as an autolink:
  if (title->len > 0) {
    return false;
  }

  link_text = node->first_child;
  cmark_consolidate_text_nodes(link_text);
  realurl = (char *)url->data;
  realurllen = url->len;
  if (strncmp(realurl, "mailto:", 7) == 0) {
    realurl += 7;
    realurllen -= 7;
  }
  return (realurllen == link_text->as.literal.len &&
          strncmp(realurl, (char *)link_text->as.literal.data,
                  link_text->as.literal.len) == 0);
}
Beispiel #4
0
static link_type get_link_type(cmark_node *node) {
  size_t title_len, url_len;
  cmark_node *link_text;
  char *realurl;
  int realurllen;
  bool isemail = false;

  if (node->type != CMARK_NODE_LINK) {
    return NO_LINK;
  }

  const char *url = cmark_node_get_url(node);
  cmark_chunk url_chunk = cmark_chunk_literal(url);

  if (url && *url == '#') {
    return INTERNAL_LINK;
  }

  url_len = strlen(url);
  if (url_len == 0 || scan_scheme(&url_chunk, 0) == 0) {
    return NO_LINK;
  }

  const char *title = cmark_node_get_title(node);
  title_len = strlen(title);
  // if it has a title, we can't treat it as an autolink:
  if (title_len == 0) {

    link_text = node->first_child;
    cmark_consolidate_text_nodes(link_text);

    if (!link_text)
      return NO_LINK;

    realurl = (char *)url;
    realurllen = (int)url_len;
    if (strncmp(realurl, "mailto:", 7) == 0) {
      realurl += 7;
      realurllen -= 7;
      isemail = true;
    }
    if (realurllen == link_text->as.literal.len &&
        strncmp(realurl, (char *)link_text->as.literal.data,
                link_text->as.literal.len) == 0) {
      if (isemail) {
        return EMAIL_AUTOLINK;
      } else {
        return URL_AUTOLINK;
      }
    }
  }

  return NORMAL_LINK;
}
Beispiel #5
0
cmark_node *cmark_parser_finish(cmark_parser *parser) {
  if (parser->linebuf->size) {
    S_process_line(parser, parser->linebuf->ptr, parser->linebuf->size);
    cmark_strbuf_clear(parser->linebuf);
  }

  finalize_document(parser);

  if (parser->options & CMARK_OPT_NORMALIZE) {
    cmark_consolidate_text_nodes(parser->root);
  }

  cmark_strbuf_free(parser->curline);

#if CMARK_DEBUG_NODES
  if (cmark_node_check(parser->root, stderr)) {
    abort();
  }
#endif
  return parser->root;
}