summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/inlines.c165
1 files changed, 89 insertions, 76 deletions
diff --git a/src/inlines.c b/src/inlines.c
index 5a8024d..3403cb0 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -41,6 +41,9 @@ typedef struct Subject {
delimiter_stack *delimiters;
} subject;
+static delimiter_stack*
+S_insert_emph(subject *subj, delimiter_stack *opener, delimiter_stack *closer);
+
static int parse_inline(subject* subj, cmark_node * parent);
static void subject_from_buf(subject *e, strbuf *buffer,
@@ -361,9 +364,7 @@ static cmark_node* handle_strong_emph(subject* subj, unsigned char c)
static void process_emphasis(subject *subj, delimiter_stack *stack_bottom)
{
delimiter_stack *closer = subj->delimiters;
- delimiter_stack *opener, *tempstack, *nextstack;
- int use_delims;
- cmark_node *inl, *tmp, *emph;
+ delimiter_stack *opener;
// move back to first relevant delim.
while (closer != NULL && closer->previous != stack_bottom) {
@@ -384,79 +385,7 @@ static void process_emphasis(subject *subj, delimiter_stack *stack_bottom)
opener = opener->previous;
}
if (opener != NULL && opener != stack_bottom) {
- // calculate the actual number of delimeters used from this closer
- if (closer->delim_count < 3 || opener->delim_count < 3) {
- use_delims = closer->delim_count <= opener->delim_count ?
- closer->delim_count : opener->delim_count;
- } else { // closer and opener both have >= 3 delims
- use_delims = closer->delim_count % 2 == 0 ? 2 : 1;
- }
-
- inl = opener->first_inline;
-
- // remove used delimiters from stack elements and associated inlines.
- opener->delim_count -= use_delims;
- closer->delim_count -= use_delims;
- inl->as.literal.len = opener->delim_count;
- closer->first_inline->as.literal.len = closer->delim_count;
-
- // free delimiters between opener and closer
- tempstack = closer->previous;
- while (tempstack != NULL && tempstack != opener) {
- nextstack = tempstack->previous;
- remove_delimiter(subj, tempstack);
- tempstack = nextstack;
- }
-
- // create new emph or strong, and splice it in to our inlines
- // between the opener and closer
- emph = use_delims == 1 ? make_emph(inl->next) : make_strong(inl->next);
- emph->next = closer->first_inline;
- emph->prev = inl;
- emph->parent = inl->parent;
- inl->next = emph;
-
- // if opener has 0 delims, remove it and its associated inline
- if (opener->delim_count == 0) {
- // replace empty opener inline with emph
- chunk_free(&(inl->as.literal));
- inl->type = emph->type;
- inl->next = emph->next;
- inl->first_child = emph->first_child;
- free(emph);
- emph = inl;
- // remove opener from stack
- remove_delimiter(subj, opener);
- }
-
- // fix tree structure
- tmp = emph->first_child;
- tmp->prev = NULL;
- while (tmp->next != NULL && tmp->next != closer->first_inline) {
- tmp->parent = emph;
- tmp = tmp->next;
- }
- tmp->parent = emph;
- if (tmp->next) {
- tmp->next->prev = emph;
- }
- tmp->next = NULL;
- emph->last_child = tmp;
-
- // if closer has 0 delims, remove it and its associated inline
- if (closer->delim_count == 0) {
- // remove empty closer inline
- tmp = closer->first_inline;
- emph->next = tmp->next;
- if (tmp->next) {
- tmp->next->prev = emph;
- }
- cmark_node_free(tmp);
- // remove closer from stack
- tempstack = closer->next;
- remove_delimiter(subj, closer);
- closer = tempstack;
- }
+ closer = S_insert_emph(subj, opener, closer);
} else {
closer = closer->next;
}
@@ -470,6 +399,90 @@ static void process_emphasis(subject *subj, delimiter_stack *stack_bottom)
}
}
+static delimiter_stack*
+S_insert_emph(subject *subj, delimiter_stack *opener, delimiter_stack *closer)
+{
+ delimiter_stack *tempstack, *nextstack;
+ int use_delims;
+ cmark_node *inl, *tmp, *emph;
+
+ // calculate the actual number of delimeters used from this closer
+ if (closer->delim_count < 3 || opener->delim_count < 3) {
+ use_delims = closer->delim_count <= opener->delim_count ?
+ closer->delim_count : opener->delim_count;
+ } else { // closer and opener both have >= 3 delims
+ use_delims = closer->delim_count % 2 == 0 ? 2 : 1;
+ }
+
+ inl = opener->first_inline;
+
+ // remove used delimiters from stack elements and associated inlines.
+ opener->delim_count -= use_delims;
+ closer->delim_count -= use_delims;
+ inl->as.literal.len = opener->delim_count;
+ closer->first_inline->as.literal.len = closer->delim_count;
+
+ // free delimiters between opener and closer
+ tempstack = closer->previous;
+ while (tempstack != NULL && tempstack != opener) {
+ nextstack = tempstack->previous;
+ remove_delimiter(subj, tempstack);
+ tempstack = nextstack;
+ }
+
+ // create new emph or strong, and splice it in to our inlines
+ // between the opener and closer
+ emph = use_delims == 1 ? make_emph(inl->next) : make_strong(inl->next);
+ emph->next = closer->first_inline;
+ emph->prev = inl;
+ emph->parent = inl->parent;
+ inl->next = emph;
+
+ // if opener has 0 delims, remove it and its associated inline
+ if (opener->delim_count == 0) {
+ // replace empty opener inline with emph
+ chunk_free(&(inl->as.literal));
+ inl->type = emph->type;
+ inl->next = emph->next;
+ inl->first_child = emph->first_child;
+ free(emph);
+ emph = inl;
+ // remove opener from stack
+ remove_delimiter(subj, opener);
+ }
+
+ // fix tree structure
+ tmp = emph->first_child;
+ tmp->prev = NULL;
+ while (tmp->next != NULL && tmp->next != closer->first_inline) {
+ tmp->parent = emph;
+ tmp = tmp->next;
+ }
+ tmp->parent = emph;
+ if (tmp->next) {
+ tmp->next->prev = emph;
+ }
+ tmp->next = NULL;
+ emph->last_child = tmp;
+
+ // if closer has 0 delims, remove it and its associated inline
+ if (closer->delim_count == 0) {
+ // remove empty closer inline
+ tmp = closer->first_inline;
+ emph->next = tmp->next;
+ if (tmp->next) {
+ tmp->next->prev = emph;
+ }
+ cmark_node_free(tmp);
+ // remove closer from stack
+ tempstack = closer->next;
+ remove_delimiter(subj, closer);
+ closer = tempstack;
+ }
+
+ return closer;
+}
+
// Parse backslash-escape or just a backslash, returning an inline.
static cmark_node* handle_backslash(subject *subj)
{