Esempio n. 1
0
File: blocks.c Progetto: gcgft/cmark
cmark_parser *cmark_parser_new(int options) {
  cmark_parser *parser = (cmark_parser *)malloc(sizeof(cmark_parser));
  cmark_node *document = make_document();
  cmark_strbuf *line = (cmark_strbuf *)malloc(sizeof(cmark_strbuf));
  cmark_strbuf *buf = (cmark_strbuf *)malloc(sizeof(cmark_strbuf));
  cmark_strbuf_init(line, 256);
  cmark_strbuf_init(buf, 0);

  parser->refmap = cmark_reference_map_new();
  parser->root = document;
  parser->current = document;
  parser->line_number = 0;
  parser->offset = 0;
  parser->column = 0;
  parser->first_nonspace = 0;
  parser->first_nonspace_column = 0;
  parser->indent = 0;
  parser->blank = false;
  parser->curline = line;
  parser->last_line_length = 0;
  parser->linebuf = buf;
  parser->options = options;

  return parser;
}
Esempio n. 2
0
static void md_convert_hashes(cmark_iter *const iter) {
	for(;;) {
		cmark_event_type const event = cmark_iter_next(iter);
		if(CMARK_EVENT_DONE == event) break;
		if(CMARK_EVENT_EXIT != event) continue;
		cmark_node *const node = cmark_iter_get_node(iter);
		cmark_node_type const type = cmark_node_get_type(node);
		if(CMARK_NODE_LINK != type && CMARK_NODE_IMAGE != type) continue;

		char const *const URI = cmark_node_get_url(node);
		if(!URI) continue;
		if(0 != strncasecmp(URI, STR_LEN("hash:"))) continue;

		cmark_node *sup = superscript("#", HASH_INFO_MSG, URI);
		cmark_node_insert_after(node, sup);
		cmark_iter_reset(iter, sup, CMARK_EVENT_EXIT);

		char *escaped = QSEscape(URI, strlen(URI), true);
		size_t const elen = strlen(escaped);
		cmark_strbuf rel[1];
		char const qpfx[] = "/sources/";
		cmark_strbuf_init(&DEFAULT_MEM_ALLOCATOR, rel, sizeof(qpfx)-1+elen);
		cmark_strbuf_put(rel, (unsigned char const *)qpfx, sizeof(qpfx)-1);
		cmark_strbuf_put(rel, (unsigned char const *)escaped, elen);
		free(escaped); escaped = NULL;
		cmark_node_set_url(node, cmark_strbuf_cstr(rel));
		cmark_strbuf_free(rel);
	}
}
Esempio n. 3
0
// Create an inline with a literal string value.
static CMARK_INLINE cmark_node *make_literal(cmark_mem *mem, cmark_node_type t,
                                             cmark_chunk s) {
  cmark_node *e = (cmark_node *)mem->calloc(1, sizeof(*e));
  cmark_strbuf_init(mem, &e->content, 0);
  e->type = t;
  e->as.literal = s;
  return e;
}
Esempio n. 4
0
void cmark_strbuf_free(cmark_strbuf *buf) {
  if (!buf)
    return;

  if (buf->ptr != cmark_strbuf__initbuf)
    free(buf->ptr);

  cmark_strbuf_init(buf, 0);
}
Esempio n. 5
0
cmark_parser *cmark_parser_new()
{
	cmark_parser *parser = (cmark_parser*)malloc(sizeof(cmark_parser));
	cmark_node *document = make_document();
	cmark_strbuf *line = (cmark_strbuf*)malloc(sizeof(cmark_strbuf));
	cmark_strbuf *buf  = (cmark_strbuf*)malloc(sizeof(cmark_strbuf));
	cmark_strbuf_init(line, 256);
	cmark_strbuf_init(buf, 0);

	parser->refmap = cmark_reference_map_new();
	parser->root = document;
	parser->current = document;
	parser->line_number = 0;
	parser->curline = line;
	parser->linebuf = buf;

	return parser;
}
Esempio n. 6
0
unsigned char *cmark_strbuf_detach(cmark_strbuf *buf) {
  unsigned char *data = buf->ptr;

  if (buf->asize == 0) {
    /* return an empty string */
    return (unsigned char *)calloc(1, 1);
  }

  cmark_strbuf_init(buf, 0);
  return data;
}
Esempio n. 7
0
static cmark_node *www_match(cmark_parser *parser, cmark_node *parent,
                             cmark_inline_parser *inline_parser) {
  cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser);
  size_t max_rewind = cmark_inline_parser_get_offset(inline_parser);
  uint8_t *data = chunk->data + max_rewind;
  size_t size = chunk->len - max_rewind;
  int start = cmark_inline_parser_get_column(inline_parser);

  size_t link_end;

  if (max_rewind > 0 && strchr("*_~(", data[-1]) == NULL &&
      !cmark_isspace(data[-1]))
    return 0;

  if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0)
    return 0;

  link_end = check_domain(data, size, 0);

  if (link_end == 0)
    return NULL;

  while (link_end < size && !cmark_isspace(data[link_end]))
    link_end++;

  link_end = autolink_delim(data, link_end);

  if (link_end == 0)
    return NULL;

  cmark_inline_parser_set_offset(inline_parser, (int)(max_rewind + link_end));

  cmark_node *node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);

  cmark_strbuf buf;
  cmark_strbuf_init(parser->mem, &buf, 10);
  cmark_strbuf_puts(&buf, "http://");
  cmark_strbuf_put(&buf, data, (bufsize_t)link_end);
  node->as.link.url = cmark_chunk_buf_detach(&buf);

  cmark_node *text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);
  text->as.literal =
      cmark_chunk_dup(chunk, (bufsize_t)max_rewind, (bufsize_t)link_end);
  cmark_node_append_child(node, text);

  node->start_line = text->start_line =
    node->end_line = text->end_line =
    cmark_inline_parser_get_line(inline_parser);

  node->start_column = text->start_column = start - 1;
  node->end_column = text->end_column = cmark_inline_parser_get_column(inline_parser) - 1;

  return node;
}
Esempio n. 8
0
static cmark_node* make_block(cmark_node_type tag, int start_line, int start_column)
{
	cmark_node* e;

	e = (cmark_node *)calloc(1, sizeof(*e));
	if(e != NULL) {
		e->type = tag;
		e->open = true;
		e->start_line = start_line;
		e->start_column = start_column;
		e->end_line = start_line;
		cmark_strbuf_init(&e->string_content, 32);
	}

	return e;
}
Esempio n. 9
0
File: node.c Progetto: tin-pot/cmark
cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {
  cmark_node *node = (cmark_node *)mem->calloc(1, sizeof(*node));
  cmark_strbuf_init(mem, &node->content, 0);
  node->type = (uint16_t)type;

  switch (node->type) {
  case CMARK_NODE_HEADING:
    node->as.heading.level = 1;
    break;

  case CMARK_NODE_LIST: {
    cmark_list *list = &node->as.list;
    list->list_type = CMARK_BULLET_LIST;
    list->start = 1;
    list->tight = false;
    break;
  }

  default:
    break;
  }

  return node;
}
Esempio n. 10
0
static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset) {
  size_t link_end;
  uint8_t *data = text->as.literal.data,
    *at;
  size_t size = text->as.literal.len;
  int rewind, max_rewind,
      nb = 0, np = 0, ns = 0;

  if (offset < 0 || (size_t)offset >= size)
    return;

  data += offset;
  size -= offset;

  at = (uint8_t *)memchr(data, '@', size);
  if (!at)
    return;

  max_rewind = (int)(at - data);
  data += max_rewind;
  size -= max_rewind;

  for (rewind = 0; rewind < max_rewind; ++rewind) {
    uint8_t c = data[-rewind - 1];

    if (cmark_isalnum(c))
      continue;

    if (strchr(".+-_", c) != NULL)
      continue;

    if (c == '/')
      ns++;

    break;
  }

  if (rewind == 0 || ns > 0) {
    postprocess_text(parser, text, max_rewind + 1 + offset);
    return;
  }

  for (link_end = 0; link_end < size; ++link_end) {
    uint8_t c = data[link_end];

    if (cmark_isalnum(c))
      continue;

    if (c == '@')
      nb++;
    else if (c == '.' && link_end < size - 1 && cmark_isalnum(data[link_end + 1]))
      np++;
    else if (c != '-' && c != '_')
      break;
  }

  if (link_end < 2 || nb != 1 || np == 0 ||
      (!cmark_isalpha(data[link_end - 1]) && data[link_end - 1] != '.')) {
    postprocess_text(parser, text, max_rewind + 1 + offset);
    return;
  }

  link_end = autolink_delim(data, link_end);

  if (link_end == 0) {
    postprocess_text(parser, text, max_rewind + 1 + offset);
    return;
  }

  cmark_chunk_to_cstr(parser->mem, &text->as.literal);

  cmark_node *link_node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);
  cmark_strbuf buf;
  cmark_strbuf_init(parser->mem, &buf, 10);
  cmark_strbuf_puts(&buf, "mailto:");
  cmark_strbuf_put(&buf, data - rewind, (bufsize_t)(link_end + rewind));
  link_node->as.link.url = cmark_chunk_buf_detach(&buf);

  cmark_node *link_text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);
  cmark_chunk email = cmark_chunk_dup(
      &text->as.literal,
      offset + max_rewind - rewind,
      (bufsize_t)(link_end + rewind));
  cmark_chunk_to_cstr(parser->mem, &email);
  link_text->as.literal = email;
  cmark_node_append_child(link_node, link_text);

  cmark_node_insert_after(text, link_node);

  cmark_node *post = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);
  post->as.literal = cmark_chunk_dup(&text->as.literal,
    (bufsize_t)(offset + max_rewind + link_end),
    (bufsize_t)(size - link_end));
  cmark_chunk_to_cstr(parser->mem, &post->as.literal);

  cmark_node_insert_after(link_node, post);

  text->as.literal.len = offset + max_rewind - rewind;
  text->as.literal.data[text->as.literal.len] = 0;

  postprocess_text(parser, post, 0);
}
Esempio n. 11
0
// Create an inline with no value.
static CMARK_INLINE cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) {
  cmark_node *e = (cmark_node *)mem->calloc(1, sizeof(*e));
  cmark_strbuf_init(mem, &e->content, 0);
  e->type = t;
  return e;
}