diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ast.c | 120 | ||||
| -rw-r--r-- | src/ast.h | 37 | ||||
| -rw-r--r-- | src/inlines.c | 130 | ||||
| -rw-r--r-- | src/inlines.h | 6 | 
4 files changed, 158 insertions, 135 deletions
| @@ -3,17 +3,18 @@  #include "buffer.h"  #include "ast.h"  #include "references.h" +#include "html/houdini.h"  // Free a node_block list and any children. -void cmark_free_blocks(node_block *e) +void cmark_free_blocks(cmark_node_block *e)  { -	node_block * next; +	cmark_node_block * next;  	while (e != NULL) { -		free_inlines(e->inline_content); +		cmark_free_inlines(e->inline_content);  		strbuf_free(&e->string_content); -		if (e->tag == BLOCK_FENCED_CODE) { +		if (e->tag == CMARK_BLOCK_FENCED_CODE) {  			strbuf_free(&e->as.code.info); -		} else if (e->tag == BLOCK_DOCUMENT) { +		} else if (e->tag == CMARK_BLOCK_DOCUMENT) {  			reference_map_free(e->as.document.refmap);  		}  		if (e->last_child) { @@ -28,8 +29,8 @@ void cmark_free_blocks(node_block *e)  }  // Utility function used by free_inlines -static void splice_into_list(node_inl* e, node_inl* children) { -	node_inl * tmp; +static void splice_into_list(cmark_node_inl* e, node_inl* children) { +	cmark_node_inl * tmp;  	if (children) {  		tmp = children;  		// Find last child @@ -45,28 +46,28 @@ static void splice_into_list(node_inl* e, node_inl* children) {  // Free an inline list.  Avoid recursion to prevent stack overflows  // on deeply nested structures. -extern void free_inlines(node_inl* e) +void cmark_free_inlines(cmark_node_inl* e)  {  	node_inl * next;  	while (e != NULL) {  		switch (e->tag){ -		case INL_STRING: -		case INL_RAW_HTML: -		case INL_CODE: -			chunk_free(&e->content.literal); +		case CMARK_INL_STRING: +		case CMARK_INL_RAW_HTML: +		case CMARK_INL_CODE: +			cmark_chunk_free(&e->content.literal);  			break; -		case INL_LINEBREAK: -		case INL_SOFTBREAK: +		case CMARK_INL_LINEBREAK: +		case CMARK_INL_SOFTBREAK:  			break; -		case INL_LINK: -		case INL_IMAGE: +		case CMARK_INL_LINK: +		case CMARK_INL_IMAGE:  			free(e->content.linkable.url);  			free(e->content.linkable.title);  			splice_into_list(e, e->content.linkable.label);  			break; -		case INL_EMPH: -		case INL_STRONG: +		case CMARK_INL_EMPH: +		case CMARK_INL_STRONG:  		        splice_into_list(e, e->content.inlines);  			break;  		default: @@ -79,3 +80,86 @@ extern void free_inlines(node_inl* e)  		e = next;  	}  } + +inline cmark_node_inl *cmark_make_link(cmark_node_inl *label, unsigned char *url, unsigned char *title) +{ +	cmark_node_inl* e = calloc(1, sizeof(*e)); +	if(e != NULL) { +		e->tag = CMARK_INL_LINK; +		e->content.linkable.label = label; +		e->content.linkable.url   = url; +		e->content.linkable.title = title; +		e->next = NULL; +	} +	return e; +} + +unsigned char *clean_autolink(chunk *url, int is_email) +{ +	strbuf buf = GH_BUF_INIT; + +	chunk_trim(url); + +	if (url->len == 0) +		return NULL; + +	if (is_email) +		strbuf_puts(&buf, "mailto:"); + +	houdini_unescape_html_f(&buf, url->data, url->len); +	return strbuf_detach(&buf); +} + +cmark_node_inl* cmark_make_autolink(cmark_node_inl* label, chunk url, int is_email) +{ +	return cmark_make_link(label, clean_autolink(&url, is_email), NULL); +} + +inline cmark_node_inl* cmark_make_inlines(int t, cmark_node_inl* contents) +{ +	cmark_node_inl * e = calloc(1, sizeof(*e)); +	if(e != NULL) { +		e->tag = t; +		e->content.inlines = contents; +		e->next = NULL; +	} +	return e; +} + +// Create an inline with a literal string value. +inline cmark_node_inl* cmark_make_literal(int t, cmark_chunk s) +{ +	cmark_node_inl * e = calloc(1, sizeof(*e)); +	if(e != NULL) { +		e->tag = t; +		e->content.literal = s; +		e->next = NULL; +	} +	return e; +} + +// Create an inline with no value. +inline cmark_node_inl* cmark_make_simple(int t) +{ +	cmark_node_inl* e = calloc(1, sizeof(*e)); +	if(e != NULL) { +		e->tag = t; +		e->next = NULL; +	} +	return e; +} + +// Append inline list b to the end of inline list a. +// Return pointer to head of new list. +inline cmark_node_inl* cmark_append_inlines(cmark_node_inl* a, cmark_node_inl* b) +{ +	if (a == NULL) {  // NULL acts like an empty list +		return b; +	} +	cmark_node_inl* cur = a; +	while (cur->next) { +		cur = cur->next; +	} +	cur->next = b; +	return a; +} @@ -102,7 +102,27 @@ struct cmark_node_block {  typedef struct cmark_node_block cmark_node_block;  void cmark_free_blocks(cmark_node_block *e); -void cmark_free_inlines(cmark_node_inl *e); +void cmark_free_inlines(cmark_node_inl* e); +void cmark_free_simple(cmark_node_inl *e); +cmark_node_inl* cmark_append_inlines(cmark_node_inl* a, cmark_node_inl* b); + +cmark_node_inl *cmark_make_link(cmark_node_inl *label, unsigned char *url, unsigned char *title); +cmark_node_inl* cmark_make_autolink(cmark_node_inl* label, cmark_chunk url, int is_email); + +cmark_node_inl* cmark_make_inlines(int t, cmark_node_inl* contents); +cmark_node_inl* cmark_make_literal(int t, cmark_chunk s); +cmark_node_inl* cmark_make_simple(int t); + +// Macros for creating various kinds of simple. +#define cmark_make_str(s) cmark_make_literal(INL_STRING, s) +#define cmark_make_code(s) cmark_make_literal(INL_CODE, s) +#define cmark_make_raw_html(s) cmark_make_literal(INL_RAW_HTML, s) +#define cmark_make_linebreak() cmark_make_simple(INL_LINEBREAK) +#define cmark_make_softbreak() cmark_make_simple(INL_SOFTBREAK) +#define cmark_make_emph(contents) cmark_make_inlines(INL_EMPH, contents) +#define cmark_make_strong(contents) cmark_make_inlines(INL_STRONG, contents) + +  #ifndef CMARK_NO_SHORT_NAMES    #define node_inl                  cmark_node_inl @@ -130,8 +150,21 @@ void cmark_free_inlines(cmark_node_inl *e);    #define BLOCK_SETEXT_HEADER       CMARK_BLOCK_SETEXT_HEADER    #define BLOCK_HRULE               CMARK_BLOCK_HRULE    #define BLOCK_REFERENCE_DEF       CMARK_BLOCK_REFERENCE_DEF -  #define free_inlines              cmark_free_inlines +  #define free_simple               cmark_free_simple    #define free_blocks               cmark_free_blocks +  #define append_simple             cmark_append_simple +  #define make_link                 cmark_make_link +  #define make_autolink             cmark_make_autolink +  #define make_str                  cmark_make_str +  #define make_code                 cmark_make_code +  #define make_raw_html             cmark_make_raw_html +  #define make_linebreak            cmark_make_linebreak +  #define make_softbreak            cmark_make_softbreak +  #define make_emph                 cmark_make_emph +  #define make_strong               cmark_make_strong +  #define make_simple              cmark_make_simple +  #define make_simple              cmark_make_simple +  #define make_simple              cmark_make_simple  #endif  #endif diff --git a/src/inlines.c b/src/inlines.c index 5b7b8ea..78ebaf4 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -8,6 +8,7 @@  #include "html/houdini.h"  #include "utf8.h"  #include "scanners.h" +#include "ast.h"  #include "inlines.h" @@ -50,82 +51,6 @@ static unsigned char *bufdup(const unsigned char *buf)  	return new;  } -static inline node_inl *make_link_(node_inl *label, unsigned char *url, unsigned char *title) -{ -	node_inl* e = calloc(1, sizeof(*e)); -	if(e != NULL) { -		e->tag = INL_LINK; -		e->content.linkable.label = label; -		e->content.linkable.url   = url; -		e->content.linkable.title = title; -		e->next = NULL; -	} -	return e; -} - -static inline node_inl* make_autolink(node_inl* label, chunk url, int is_email) -{ -	return make_link_(label, clean_autolink(&url, is_email), NULL); -} - -static inline node_inl* make_inlines(int t, node_inl* contents) -{ -	node_inl * e = calloc(1, sizeof(*e)); -	if(e != NULL) { -		e->tag = t; -		e->content.inlines = contents; -		e->next = NULL; -	} -	return e; -} - -// Create an inline with a literal string value. -static inline node_inl* make_literal(int t, chunk s) -{ -	node_inl * e = calloc(1, sizeof(*e)); -	if(e != NULL) { -		e->tag = t; -		e->content.literal = s; -		e->next = NULL; -	} -	return e; -} - -// Create an inline with no value. -static inline node_inl* make_simple(int t) -{ -	node_inl* e = calloc(1, sizeof(*e)); -	if(e != NULL) { -		e->tag = t; -		e->next = NULL; -	} -	return e; -} - -// Macros for creating various kinds of inlines. -#define make_str(s) make_literal(INL_STRING, s) -#define make_code(s) make_literal(INL_CODE, s) -#define make_raw_html(s) make_literal(INL_RAW_HTML, s) -#define make_linebreak() make_simple(INL_LINEBREAK) -#define make_softbreak() make_simple(INL_SOFTBREAK) -#define make_emph(contents) make_inlines(INL_EMPH, contents) -#define make_strong(contents) make_inlines(INL_STRONG, contents) - -// Append inline list b to the end of inline list a. -// Return pointer to head of new list. -static inline node_inl* append_inlines(node_inl* a, node_inl* b) -{ -	if (a == NULL) {  // NULL acts like an empty list -		return b; -	} -	node_inl* cur = a; -	while (cur->next) { -		cur = cur->next; -	} -	cur->next = b; -	return a; -} -  static void subject_from_buf(subject *e, strbuf *buffer, reference_map *refmap)  {  	e->input.data = buffer->ptr; @@ -402,7 +327,7 @@ static void process_emphasis(subject *subj, delimiter_stack *stack_bottom)  					tmp = closer->first_inline;  					emph->next = tmp->next;  					tmp->next = NULL; -					free_inlines(tmp); +					cmark_free_inlines(tmp);  					// remove closer from stack  					tempstack = closer->next;  					remove_delimiter(subj, closer); @@ -492,45 +417,28 @@ unsigned char *clean_url(chunk *url)  	return strbuf_detach(&buf);  } -unsigned char *clean_autolink(chunk *url, int is_email) -{ -	strbuf buf = GH_BUF_INIT; - -	chunk_trim(url); - -	if (url->len == 0) -		return NULL; - -	if (is_email) -		strbuf_puts(&buf, "mailto:"); - -	houdini_unescape_html_f(&buf, url->data, url->len); -	return strbuf_detach(&buf); -} - -// Clean a title: remove surrounding quotes and remove \ that escape punctuation.  unsigned char *clean_title(chunk *title)  { -	strbuf buf = GH_BUF_INIT; -	unsigned char first, last; +       strbuf buf = GH_BUF_INIT; +       unsigned char first, last; -	if (title->len == 0) -		return NULL; +       if (title->len == 0) +               return NULL; -	first = title->data[0]; -	last = title->data[title->len - 1]; +       first = title->data[0]; +       last = title->data[title->len - 1]; -	// remove surrounding quotes if any: -	if ((first == '\'' && last == '\'') || -	    (first == '(' && last == ')') || -	    (first == '"' && last == '"')) { -		houdini_unescape_html_f(&buf, title->data + 1, title->len - 2); -	} else { -		houdini_unescape_html_f(&buf, title->data, title->len); -	} +       // remove surrounding quotes if any: +       if ((first == '\'' && last == '\'') || +           (first == '(' && last == ')') || +           (first == '"' && last == '"')) { +               houdini_unescape_html_f(&buf, title->data + 1, title->len - 2); +       } else { +               houdini_unescape_html_f(&buf, title->data, title->len); +       } -	strbuf_unescape(&buf); -	return strbuf_detach(&buf); +       strbuf_unescape(&buf); +       return strbuf_detach(&buf);  }  // Parse an autolink or HTML tag. @@ -880,7 +788,7 @@ static int parse_inline(subject* subj, node_inl ** last)  	if (*last == NULL) {  		*last = new;  	} else if (new) { -		append_inlines(*last, new); +		cmark_append_inlines(*last, new);  		*last = new;  	} diff --git a/src/inlines.h b/src/inlines.h index fa61c8a..57daea2 100644 --- a/src/inlines.h +++ b/src/inlines.h @@ -2,7 +2,6 @@  #define _INLINES_H_  unsigned char *cmark_clean_url(cmark_chunk *url); -unsigned char *cmark_clean_autolink(cmark_chunk *url, int is_email);  unsigned char *cmark_clean_title(cmark_chunk *title);  cmark_node_inl* cmark_parse_inlines(cmark_strbuf *input, cmark_reference_map *refmap); @@ -10,11 +9,10 @@ cmark_node_inl* cmark_parse_inlines(cmark_strbuf *input, cmark_reference_map *re  int cmark_parse_reference_inline(cmark_strbuf *input, cmark_reference_map *refmap);  #ifndef CMARK_NO_SHORT_NAMES -  #define clean_url                 cmark_clean_url -  #define clean_autolink            cmark_clean_autolink -  #define clean_title               cmark_clean_title    #define parse_inlines             cmark_parse_inlines    #define parse_reference_inline    cmark_parse_reference_inline +  #define clean_url                 cmark_clean_url +  #define clean_title               cmark_clean_title  #endif  #endif | 
