aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig1
-rw-r--r--src/blocks.c68
-rw-r--r--src/html/html.c448
-rw-r--r--src/inlines.c238
-rw-r--r--src/references.c42
5 files changed, 399 insertions, 398 deletions
diff --git a/.editorconfig b/.editorconfig
index f0f2032..946396e 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -15,3 +15,4 @@ indent_size = 2
[{*.c,Makefile}]
trim_trailing_whitespace = true
indent_style = tab
+indent_size = 8
diff --git a/src/blocks.c b/src/blocks.c
index d925ced..b30bae3 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -20,14 +20,14 @@ static node_block* make_block(int tag, int start_line, int start_column)
node_block* e;
e = calloc(1, sizeof(*e));
- if(e != NULL) {
- e->tag = tag;
- e->open = true;
- e->start_line = start_line;
- e->start_column = start_column;
- e->end_line = start_line;
- strbuf_init(&e->string_content, 32);
- }
+ if(e != NULL) {
+ e->tag = tag;
+ e->open = true;
+ e->start_line = start_line;
+ e->start_column = start_column;
+ e->end_line = start_line;
+ strbuf_init(&e->string_content, 32);
+ }
return e;
}
@@ -266,9 +266,9 @@ void cmark_free_nodes(node_block *e)
reference_map_free(e->as.document.refmap);
}
if (e->last_child) {
- // Splice children into list
- e->last_child->next = e->next;
- e->next = e->children;
+ // Splice children into list
+ e->last_child->next = e->next;
+ e->next = e->children;
}
next = e->next;
free(e);
@@ -316,16 +316,16 @@ static int parse_list_marker(chunk *input, int pos, struct ListData ** dataptr)
return 0;
}
data = calloc(1, sizeof(*data));
- if(data == NULL) {
- return 0;
- } else {
- data->marker_offset = 0; // will be adjusted later
- data->list_type = bullet;
- data->bullet_char = c;
- data->start = 1;
- data->delimiter = period;
- data->tight = false;
- }
+ if(data == NULL) {
+ return 0;
+ } else {
+ data->marker_offset = 0; // will be adjusted later
+ data->list_type = bullet;
+ data->bullet_char = c;
+ data->start = 1;
+ data->delimiter = period;
+ data->tight = false;
+ }
} else if (isdigit(c)) {
int start = 0;
@@ -341,16 +341,16 @@ static int parse_list_marker(chunk *input, int pos, struct ListData ** dataptr)
return 0;
}
data = calloc(1, sizeof(*data));
- if(data == NULL) {
- return 0;
- } else {
- data->marker_offset = 0; // will be adjusted later
- data->list_type = ordered;
- data->bullet_char = 0;
- data->start = start;
- data->delimiter = (c == '.' ? period : parens);
- data->tight = false;
- }
+ if(data == NULL) {
+ return 0;
+ } else {
+ data->marker_offset = 0; // will be adjusted later
+ data->list_type = ordered;
+ data->bullet_char = 0;
+ data->start = start;
+ data->delimiter = (c == '.' ? period : parens);
+ data->tight = false;
+ }
} else {
return 0;
}
@@ -443,8 +443,8 @@ static void chop_trailing_hashtags(chunk *ch)
// Check for a be a space before the final #s:
if (n != orig_n && n >= 0 && peek_at(ch, n) == ' ') {
- ch->len = n;
- chunk_rtrim(ch);
+ ch->len = n;
+ chunk_rtrim(ch);
}
}
@@ -467,7 +467,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
// Add a newline to the end if not present:
if (line->ptr[line->size - 1] != '\n') {
- strbuf_putc(line, '\n');
+ strbuf_putc(line, '\n');
}
input.data = line->ptr;
input.len = line->size;
diff --git a/src/html/html.c b/src/html/html.c
index 9b3a995..404a946 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -9,38 +9,38 @@
#include "html/houdini.h"
typedef struct RenderStack {
- struct RenderStack *previous;
- char* literal;
- union {
- node_inl *inl;
- node_block *block;
- } next_sibling;
- bool tight;
+ struct RenderStack *previous;
+ char* literal;
+ union {
+ node_inl *inl;
+ node_block *block;
+ } next_sibling;
+ bool tight;
} render_stack;
static void free_render_stack(render_stack * rstack)
{
- render_stack * tempstack;
- while (rstack) {
- tempstack = rstack;
- rstack = rstack->previous;
- free(tempstack);
- }
+ render_stack * tempstack;
+ while (rstack) {
+ tempstack = rstack;
+ rstack = rstack->previous;
+ free(tempstack);
+ }
}
static render_stack* push_inline(render_stack* rstack,
node_inl* inl,
char* literal)
{
- render_stack* newstack;
- newstack = (render_stack*)malloc(sizeof(render_stack));
- if (newstack == NULL) {
- return NULL;
- }
- newstack->previous = rstack;
- newstack->next_sibling.inl = inl;
- newstack->literal = literal;
- return newstack;
+ render_stack* newstack;
+ newstack = (render_stack*)malloc(sizeof(render_stack));
+ if (newstack == NULL) {
+ return NULL;
+ }
+ newstack->previous = rstack;
+ newstack->next_sibling.inl = inl;
+ newstack->literal = literal;
+ return newstack;
}
static render_stack* push_block(render_stack* rstack,
@@ -48,29 +48,29 @@ static render_stack* push_block(render_stack* rstack,
char* literal,
bool tight)
{
- render_stack* newstack;
- newstack = (render_stack*)malloc(sizeof(render_stack));
- if (newstack == NULL) {
- return NULL;
- }
- newstack->previous = rstack;
- newstack->next_sibling.block = block;
- newstack->literal = literal;
- newstack->tight = tight;
- return newstack;
+ render_stack* newstack;
+ newstack = (render_stack*)malloc(sizeof(render_stack));
+ if (newstack == NULL) {
+ return NULL;
+ }
+ newstack->previous = rstack;
+ newstack->next_sibling.block = block;
+ newstack->literal = literal;
+ newstack->tight = tight;
+ return newstack;
}
static render_stack* pop_render_stack(render_stack* rstack)
{
- render_stack* top = rstack;
-
- if (rstack == NULL) {
- return NULL;
- }
- rstack = rstack->previous;
- top->previous = NULL;
- free_render_stack(top);
- return rstack;
+ render_stack* top = rstack;
+
+ if (rstack == NULL) {
+ return NULL;
+ }
+ rstack = rstack->previous;
+ top->previous = NULL;
+ free_render_stack(top);
+ return rstack;
}
// Functions to convert node_block and inline lists to HTML strings.
@@ -106,38 +106,38 @@ static void inlines_to_plain_html(strbuf *html, node_inl* ils)
while(ils != NULL) {
children = NULL;
switch(ils->tag) {
- case INL_STRING:
- case INL_CODE:
- case INL_RAW_HTML:
- escape_html(html, ils->content.literal.data, ils->content.literal.len);
- break;
-
- case INL_LINEBREAK:
- case INL_SOFTBREAK:
- strbuf_putc(html, '\n');
- break;
-
- case INL_LINK:
- case INL_IMAGE:
- children = ils->content.inlines;
- rstack = push_inline(rstack, ils->next, "");
- break;
-
- case INL_STRONG:
- case INL_EMPH:
- children = ils->content.inlines;
- rstack = push_inline(rstack, ils->next, "");
- break;
+ case INL_STRING:
+ case INL_CODE:
+ case INL_RAW_HTML:
+ escape_html(html, ils->content.literal.data, ils->content.literal.len);
+ break;
+
+ case INL_LINEBREAK:
+ case INL_SOFTBREAK:
+ strbuf_putc(html, '\n');
+ break;
+
+ case INL_LINK:
+ case INL_IMAGE:
+ children = ils->content.inlines;
+ rstack = push_inline(rstack, ils->next, "");
+ break;
+
+ case INL_STRONG:
+ case INL_EMPH:
+ children = ils->content.inlines;
+ rstack = push_inline(rstack, ils->next, "");
+ break;
}
if (children) {
- ils = children;
+ ils = children;
} else {
- ils = ils->next;
+ ils = ils->next;
}
while (ils == NULL && rstack != NULL) {
- strbuf_puts(html, rstack->literal);
- ils = rstack->next_sibling.inl;
- rstack = pop_render_stack(rstack);
+ strbuf_puts(html, rstack->literal);
+ ils = rstack->next_sibling.inl;
+ rstack = pop_render_stack(rstack);
}
}
@@ -154,82 +154,82 @@ static void inlines_to_html(strbuf *html, node_inl* ils)
while(ils != NULL) {
children = NULL;
switch(ils->tag) {
- case INL_STRING:
- escape_html(html, ils->content.literal.data, ils->content.literal.len);
- break;
-
- case INL_LINEBREAK:
- strbuf_puts(html, "<br />\n");
- break;
-
- case INL_SOFTBREAK:
- strbuf_putc(html, '\n');
- break;
-
- case INL_CODE:
- strbuf_puts(html, "<code>");
- escape_html(html, ils->content.literal.data, ils->content.literal.len);
- strbuf_puts(html, "</code>");
- break;
-
- case INL_RAW_HTML:
- strbuf_put(html,
- ils->content.literal.data,
- ils->content.literal.len);
- break;
-
- case INL_LINK:
- strbuf_puts(html, "<a href=\"");
- if (ils->content.linkable.url)
- escape_href(html, ils->content.linkable.url, -1);
-
- if (ils->content.linkable.title) {
- strbuf_puts(html, "\" title=\"");
- escape_html(html, ils->content.linkable.title, -1);
- }
-
- strbuf_puts(html, "\">");
- children = ils->content.inlines;
- rstack = push_inline(rstack, ils->next, "</a>");
- break;
-
- case INL_IMAGE:
- strbuf_puts(html, "<img src=\"");
- if (ils->content.linkable.url)
- escape_href(html, ils->content.linkable.url, -1);
-
- strbuf_puts(html, "\" alt=\"");
- inlines_to_plain_html(html, ils->content.inlines);
-
- if (ils->content.linkable.title) {
- strbuf_puts(html, "\" title=\"");
- escape_html(html, ils->content.linkable.title, -1);
- }
-
- strbuf_puts(html, "\"/>");
- break;
-
- case INL_STRONG:
- strbuf_puts(html, "<strong>");
- children = ils->content.inlines;
- rstack = push_inline(rstack, ils->next, "</strong>");
- break;
-
- case INL_EMPH:
- strbuf_puts(html, "<em>");
- children = ils->content.inlines;
- rstack = push_inline(rstack, ils->next, "</em>");
- break;
+ case INL_STRING:
+ escape_html(html, ils->content.literal.data, ils->content.literal.len);
+ break;
+
+ case INL_LINEBREAK:
+ strbuf_puts(html, "<br />\n");
+ break;
+
+ case INL_SOFTBREAK:
+ strbuf_putc(html, '\n');
+ break;
+
+ case INL_CODE:
+ strbuf_puts(html, "<code>");
+ escape_html(html, ils->content.literal.data, ils->content.literal.len);
+ strbuf_puts(html, "</code>");
+ break;
+
+ case INL_RAW_HTML:
+ strbuf_put(html,
+ ils->content.literal.data,
+ ils->content.literal.len);
+ break;
+
+ case INL_LINK:
+ strbuf_puts(html, "<a href=\"");
+ if (ils->content.linkable.url)
+ escape_href(html, ils->content.linkable.url, -1);
+
+ if (ils->content.linkable.title) {
+ strbuf_puts(html, "\" title=\"");
+ escape_html(html, ils->content.linkable.title, -1);
+ }
+
+ strbuf_puts(html, "\">");
+ children = ils->content.inlines;
+ rstack = push_inline(rstack, ils->next, "</a>");
+ break;
+
+ case INL_IMAGE:
+ strbuf_puts(html, "<img src=\"");
+ if (ils->content.linkable.url)
+ escape_href(html, ils->content.linkable.url, -1);
+
+ strbuf_puts(html, "\" alt=\"");
+ inlines_to_plain_html(html, ils->content.inlines);
+
+ if (ils->content.linkable.title) {
+ strbuf_puts(html, "\" title=\"");
+ escape_html(html, ils->content.linkable.title, -1);
+ }
+
+ strbuf_puts(html, "\"/>");
+ break;
+
+ case INL_STRONG:
+ strbuf_puts(html, "<strong>");
+ children = ils->content.inlines;
+ rstack = push_inline(rstack, ils->next, "</strong>");
+ break;
+
+ case INL_EMPH:
+ strbuf_puts(html, "<em>");
+ children = ils->content.inlines;
+ rstack = push_inline(rstack, ils->next, "</em>");
+ break;
}
if (children) {
- ils = children;
+ ils = children;
} else {
- ils = ils->next;
+ ils = ils->next;
}
while (ils == NULL && rstack != NULL) {
- strbuf_puts(html, rstack->literal);
- ils = rstack->next_sibling.inl;
- rstack = pop_render_stack(rstack);
+ strbuf_puts(html, rstack->literal);
+ ils = rstack->next_sibling.inl;
+ rstack = pop_render_stack(rstack);
}
}
@@ -243,100 +243,100 @@ static void blocks_to_html(strbuf *html, node_block *b, bool tight)
while(b != NULL) {
switch(b->tag) {
- case BLOCK_DOCUMENT:
- blocks_to_html(html, b->children, false);
- break;
-
- case BLOCK_PARAGRAPH:
- if (tight) {
- inlines_to_html(html, b->inline_content);
- } else {
- cr(html);
- strbuf_puts(html, "<p>");
- inlines_to_html(html, b->inline_content);
- strbuf_puts(html, "</p>\n");
- }
- break;
-
- case BLOCK_BQUOTE:
- cr(html);
- strbuf_puts(html, "<blockquote>\n");
- blocks_to_html(html, b->children, false);
- strbuf_puts(html, "</blockquote>\n");
- break;
-
- case BLOCK_LIST_ITEM:
- cr(html);
- strbuf_puts(html, "<li>");
- blocks_to_html(html, b->children, tight);
- strbuf_trim(html); /* TODO: rtrim */
- strbuf_puts(html, "</li>\n");
- break;
-
- case BLOCK_LIST:
- // make sure a list starts at the beginning of the line:
- cr(html);
- data = &(b->as.list);
-
- if (data->start > 1) {
- strbuf_printf(html, "<%s start=\"%d\">\n",
- data->list_type == bullet ? "ul" : "ol",
- data->start);
- } else {
- strbuf_puts(html, data->list_type == bullet ? "<ul>\n" : "<ol>\n");
- }
-
- blocks_to_html(html, b->children, data->tight);
- strbuf_puts(html, data->list_type == bullet ? "</ul>" : "</ol>");
- strbuf_putc(html, '\n');
- break;
+ case BLOCK_DOCUMENT:
+ blocks_to_html(html, b->children, false);
+ break;
- case BLOCK_ATX_HEADER:
- case BLOCK_SETEXT_HEADER:
- cr(html);
- strbuf_printf(html, "<h%d>", b->as.header.level);
+ case BLOCK_PARAGRAPH:
+ if (tight) {
inlines_to_html(html, b->inline_content);
- strbuf_printf(html, "</h%d>\n", b->as.header.level);
- break;
-
- case BLOCK_INDENTED_CODE:
- case BLOCK_FENCED_CODE:
+ } else {
cr(html);
-
- strbuf_puts(html, "<pre><code");
-
- if (b->tag == BLOCK_FENCED_CODE) {
- strbuf *info = &b->as.code.info;
-
- if (strbuf_len(info) > 0) {
- int first_tag = strbuf_strchr(info, ' ', 0);
- if (first_tag < 0)
- first_tag = strbuf_len(info);
-
- strbuf_puts(html, " class=\"language-");
- escape_html(html, info->ptr, first_tag);
- strbuf_putc(html, '"');
- }
+ strbuf_puts(html, "<p>");
+ inlines_to_html(html, b->inline_content);
+ strbuf_puts(html, "</p>\n");
+ }
+ break;
+
+ case BLOCK_BQUOTE:
+ cr(html);
+ strbuf_puts(html, "<blockquote>\n");
+ blocks_to_html(html, b->children, false);
+ strbuf_puts(html, "</blockquote>\n");
+ break;
+
+ case BLOCK_LIST_ITEM:
+ cr(html);
+ strbuf_puts(html, "<li>");
+ blocks_to_html(html, b->children, tight);
+ strbuf_trim(html); /* TODO: rtrim */
+ strbuf_puts(html, "</li>\n");
+ break;
+
+ case BLOCK_LIST:
+ // make sure a list starts at the beginning of the line:
+ cr(html);
+ data = &(b->as.list);
+
+ if (data->start > 1) {
+ strbuf_printf(html, "<%s start=\"%d\">\n",
+ data->list_type == bullet ? "ul" : "ol",
+ data->start);
+ } else {
+ strbuf_puts(html, data->list_type == bullet ? "<ul>\n" : "<ol>\n");
+ }
+
+ blocks_to_html(html, b->children, data->tight);
+ strbuf_puts(html, data->list_type == bullet ? "</ul>" : "</ol>");
+ strbuf_putc(html, '\n');
+ break;
+
+ case BLOCK_ATX_HEADER:
+ case BLOCK_SETEXT_HEADER:
+ cr(html);
+ strbuf_printf(html, "<h%d>", b->as.header.level);
+ inlines_to_html(html, b->inline_content);
+ strbuf_printf(html, "</h%d>\n", b->as.header.level);
+ break;
+
+ case BLOCK_INDENTED_CODE:
+ case BLOCK_FENCED_CODE:
+ cr(html);
+
+ strbuf_puts(html, "<pre><code");
+
+ if (b->tag == BLOCK_FENCED_CODE) {
+ strbuf *info = &b->as.code.info;
+
+ if (strbuf_len(info) > 0) {
+ int first_tag = strbuf_strchr(info, ' ', 0);
+ if (first_tag < 0)
+ first_tag = strbuf_len(info);
+
+ strbuf_puts(html, " class=\"language-");
+ escape_html(html, info->ptr, first_tag);
+ strbuf_putc(html, '"');
}
+ }
- strbuf_putc(html, '>');
- escape_html(html, b->string_content.ptr, b->string_content.size);
- strbuf_puts(html, "</code></pre>\n");
- break;
+ strbuf_putc(html, '>');
+ escape_html(html, b->string_content.ptr, b->string_content.size);
+ strbuf_puts(html, "</code></pre>\n");
+ break;
- case BLOCK_HTML:
- strbuf_put(html, b->string_content.ptr, b->string_content.size);
- break;
+ case BLOCK_HTML:
+ strbuf_put(html, b->string_content.ptr, b->string_content.size);
+ break;
- case BLOCK_HRULE:
- strbuf_puts(html, "<hr />\n");
- break;
+ case BLOCK_HRULE:
+ strbuf_puts(html, "<hr />\n");
+ break;
- case BLOCK_REFERENCE_DEF:
- break;
+ case BLOCK_REFERENCE_DEF:
+ break;
- default:
- assert(false);
+ default:
+ assert(false);
}
b = b->next;
diff --git a/src/inlines.c b/src/inlines.c
index 0bdc829..d205d60 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -42,9 +42,9 @@ static unsigned char *bufdup(const unsigned char *buf)
if (buf) {
int len = strlen((char *)buf);
new = calloc(len + 1, sizeof(*new));
- if(new != NULL) {
- memcpy(new, buf, len + 1);
- }
+ if(new != NULL) {
+ memcpy(new, buf, len + 1);
+ }
}
return new;
@@ -53,13 +53,13 @@ static unsigned char *bufdup(const unsigned char *buf)
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;
- }
+ 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;
}
@@ -82,11 +82,11 @@ inline static node_inl* make_link(node_inl* label, chunk url, chunk title)
inline static 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;
- }
+ if(e != NULL) {
+ e->tag = t;
+ e->content.inlines = contents;
+ e->next = NULL;
+ }
return e;
}
@@ -94,11 +94,11 @@ inline static node_inl* make_inlines(int t, node_inl* contents)
inline static 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;
- }
+ if(e != NULL) {
+ e->tag = t;
+ e->content.literal = s;
+ e->next = NULL;
+ }
return e;
}
@@ -106,10 +106,10 @@ inline static node_inl* make_literal(int t, chunk s)
inline static node_inl* make_simple(int t)
{
node_inl* e = calloc(1, sizeof(*e));
- if(e != NULL) {
- e->tag = t;
- e->next = NULL;
- }
+ if(e != NULL) {
+ e->tag = t;
+ e->next = NULL;
+ }
return e;
}
@@ -126,14 +126,14 @@ inline static node_inl* make_simple(int t)
void splice_into_list(node_inl* e, node_inl* children) {
node_inl * tmp;
if (children) {
- tmp = children;
- // Find last child
- while (tmp->next) {
- tmp = tmp->next;
- }
- // Splice children into list
- tmp->next = e->next;
- e->next = children;
+ tmp = children;
+ // Find last child
+ while (tmp->next) {
+ tmp = tmp->next;
+ }
+ // Splice children into list
+ tmp->next = e->next;
+ e->next = children;
}
return ;
}
@@ -328,13 +328,13 @@ static int scan_delims(subject* subj, unsigned char c, bool * can_open, bool * c
static void free_openers(subject* subj, inline_stack* istack)
{
- inline_stack * tempstack;
- while (subj->emphasis_openers != istack) {
- tempstack = subj->emphasis_openers;
- subj->emphasis_openers = subj->emphasis_openers->previous;
- subj->emphasis_nestlevel--;
- free(tempstack);
- }
+ inline_stack * tempstack;
+ while (subj->emphasis_openers != istack) {
+ tempstack = subj->emphasis_openers;
+ subj->emphasis_openers = subj->emphasis_openers->previous;
+ subj->emphasis_nestlevel--;
+ free(tempstack);
+ }
}
// Parse strong/emph or a fallback.
@@ -353,83 +353,83 @@ static node_inl* handle_strong_emph(subject* subj, unsigned char c, node_inl **l
numdelims = scan_delims(subj, c, &can_open, &can_close);
if (can_close)
- {
- // walk the stack and find a matching opener, if there is one
- istack = subj->emphasis_openers;
- while (true)
{
- if (istack == NULL)
- goto cannotClose;
-
- if (istack->delim_char == c)
- break;
-
- istack = istack->previous;
- }
-
- // calculate the actual number of delimeters used from this closer
- openerDelims = istack->delim_count;
- if (numdelims < 3 || openerDelims < 3) {
- useDelims = numdelims <= openerDelims ? numdelims : openerDelims;
- } else { // (numdelims >= 3 && openerDelims >= 3)
- useDelims = numdelims % 2 == 0 ? 2 : 1;
- }
-
- if (istack->delim_count == useDelims)
- {
- // the opener is completely used up - remove the stack entry and reuse the inline element
- inl = istack->first_inline;
- inl->tag = useDelims == 1 ? INL_EMPH : INL_STRONG;
- chunk_free(&inl->content.literal);
- inl->content.inlines = inl->next;
- inl->next = NULL;
-
- // remove this opener and all later ones from stack:
- free_openers(subj, istack->previous);
- *last = inl;
- }
- else
- {
- // the opener will only partially be used - stack entry remains (truncated) and a new inline is added.
- inl = istack->first_inline;
- istack->delim_count -= useDelims;
- inl->content.literal.len = istack->delim_count;
-
- emph = useDelims == 1 ? make_emph(inl->next) : make_strong(inl->next);
- inl->next = emph;
-
- // remove all later openers from stack:
- free_openers(subj, istack);
-
- *last = emph;
- }
+ // walk the stack and find a matching opener, if there is one
+ istack = subj->emphasis_openers;
+ while (true)
+ {
+ if (istack == NULL)
+ goto cannotClose;
+
+ if (istack->delim_char == c)
+ break;
+
+ istack = istack->previous;
+ }
+
+ // calculate the actual number of delimeters used from this closer
+ openerDelims = istack->delim_count;
+ if (numdelims < 3 || openerDelims < 3) {
+ useDelims = numdelims <= openerDelims ? numdelims : openerDelims;
+ } else { // (numdelims >= 3 && openerDelims >= 3)
+ useDelims = numdelims % 2 == 0 ? 2 : 1;
+ }
- // if the closer was not fully used, move back a char or two and try again.
- if (useDelims < numdelims)
- {
- subj->pos = subj->pos - numdelims + useDelims;
- return NULL;
+ if (istack->delim_count == useDelims)
+ {
+ // the opener is completely used up - remove the stack entry and reuse the inline element
+ inl = istack->first_inline;
+ inl->tag = useDelims == 1 ? INL_EMPH : INL_STRONG;
+ chunk_free(&inl->content.literal);
+ inl->content.inlines = inl->next;
+ inl->next = NULL;
+
+ // remove this opener and all later ones from stack:
+ free_openers(subj, istack->previous);
+ *last = inl;
+ }
+ else
+ {
+ // the opener will only partially be used - stack entry remains (truncated) and a new inline is added.
+ inl = istack->first_inline;
+ istack->delim_count -= useDelims;
+ inl->content.literal.len = istack->delim_count;
+
+ emph = useDelims == 1 ? make_emph(inl->next) : make_strong(inl->next);
+ inl->next = emph;
+
+ // remove all later openers from stack:
+ free_openers(subj, istack);
+
+ *last = emph;
+ }
+
+ // if the closer was not fully used, move back a char or two and try again.
+ if (useDelims < numdelims)
+ {
+ subj->pos = subj->pos - numdelims + useDelims;
+ return NULL;
+ }
+
+ return NULL; // make_str(chunk_literal(""));
}
- return NULL; // make_str(chunk_literal(""));
- }
-
-cannotClose:
+ cannotClose:
inl_text = make_str(chunk_dup(&subj->input, subj->pos - numdelims, numdelims));
if (can_open)
- {
- istack = (inline_stack*)malloc(sizeof(inline_stack));
- if (istack == NULL) {
- return NULL;
- }
- istack->delim_count = numdelims;
- istack->delim_char = c;
- istack->first_inline = inl_text;
- istack->previous = subj->emphasis_openers;
- subj->emphasis_openers = istack;
- subj->emphasis_nestlevel++;
- }
+ {
+ istack = (inline_stack*)malloc(sizeof(inline_stack));
+ if (istack == NULL) {
+ return NULL;
+ }
+ istack->delim_count = numdelims;
+ istack->delim_char = c;
+ istack->first_inline = inl_text;
+ istack->previous = subj->emphasis_openers;
+ subj->emphasis_openers = istack;
+ subj->emphasis_nestlevel++;
+ }
return inl_text;
}
@@ -462,7 +462,7 @@ static node_inl* handle_entity(subject* subj)
len = houdini_unescape_ent(&ent,
subj->input.data + subj->pos,
subj->input.len - subj->pos
- );
+ );
if (len == 0)
return make_str(chunk_literal("&"));
@@ -562,9 +562,9 @@ static node_inl* handle_pointy_brace(subject* subj)
subj->pos += matchlen;
return make_autolink(
- make_str_with_entities(&contents),
- contents, 0
- );
+ make_str_with_entities(&contents),
+ contents, 0
+ );
}
// next try to match an email autolink
@@ -574,9 +574,9 @@ static node_inl* handle_pointy_brace(subject* subj)
subj->pos += matchlen;
return make_autolink(
- make_str_with_entities(&contents),
- contents, 1
- );
+ make_str_with_entities(&contents),
+ contents, 1
+ );
}
// finally, try to match an html tag
@@ -778,9 +778,9 @@ extern node_inl* parse_inlines_while(subject* subj, int (*f)(subject*))
node_inl** last = &result;
node_inl* first = NULL;
while ((*f)(subj) && parse_inline(subj, last)) {
- if (!first) {
- first = *last;
- }
+ if (!first) {
+ first = *last;
+ }
}
inline_stack* istack = subj->emphasis_openers;
diff --git a/src/references.c b/src/references.c
index 04b9025..5ba4b24 100644
--- a/src/references.c
+++ b/src/references.c
@@ -16,12 +16,12 @@ refhash(const unsigned char *link_ref)
static void reference_free(reference *ref)
{
- if(ref != NULL) {
- free(ref->label);
- free(ref->url);
- free(ref->title);
- free(ref);
- }
+ if(ref != NULL) {
+ free(ref->label);
+ free(ref->url);
+ free(ref->title);
+ free(ref);
+ }
}
// normalize reference: collapse internal whitespace to single space,
@@ -33,8 +33,8 @@ static unsigned char *normalize_reference(chunk *ref)
strbuf normalized = GH_BUF_INIT;
unsigned char *result;
- if(ref == NULL)
- return NULL;
+ if(ref == NULL)
+ return NULL;
if (ref->len == 0)
return NULL;
@@ -50,7 +50,7 @@ static unsigned char *normalize_reference(chunk *ref)
free(result);
return NULL;
}
-
+
return result;
}
@@ -81,15 +81,15 @@ extern void reference_create(reference_map *map, chunk *label, chunk *url, chunk
return;
ref = calloc(1, sizeof(*ref));
- if(ref != NULL) {
- ref->label = reflabel;
- ref->hash = refhash(ref->label);
- ref->url = clean_url(url);
- ref->title = clean_title(title);
- ref->next = NULL;
-
- add_reference(map, ref);
- }
+ if(ref != NULL) {
+ ref->label = reflabel;
+ ref->hash = refhash(ref->label);
+ ref->url = clean_url(url);
+ ref->title = clean_title(title);
+ ref->next = NULL;
+
+ add_reference(map, ref);
+ }
}
// Returns reference if refmap contains a reference with matching
@@ -125,8 +125,8 @@ void reference_map_free(reference_map *map)
{
unsigned int i;
- if(map == NULL)
- return;
+ if(map == NULL)
+ return;
for (i = 0; i < REFMAP_SIZE; ++i) {
reference *ref = map->table[i];
@@ -144,5 +144,5 @@ void reference_map_free(reference_map *map)
reference_map *reference_map_new(void)
{
- return calloc(1, sizeof(reference_map));
+ return calloc(1, sizeof(reference_map));
}