static void md_node_add_child(MDNode *node, MDNode *child) {
cx_linked_list_add((void**)&node->children_begin, (void**)&node->children_end, -1, offsetof(MDNode, next), child);
+ child->parent = node;
}
// create a node and add it to the current paragraph node tree
} else {
md_node_add_child(current, node);
}
+
} else {
data->p_current->content = node;
}
static int md_leave_span(MD_SPANTYPE type, void* detail, void* userdata) {
MDParserData *data = userdata;
size_t len = cxListSize(data->text_stack);
+ MDNode *current = get_current_textnode(data);
MDNode *elm = NULL;
+
+ if(current->text.ptr) {
+ // last node was a text node
+ // there is no leave event for text nodes, so we have to handle it here
+ // and remove it from the stack
+ cxListRemove(data->text_stack, len-1);
+ len--; // len is always > 1 here
+ }
+
if(len > 1) {
cxListRemoveAndGet(data->text_stack, len-1, &elm);
} else {
if(current->parent) {
current->parent->children_end = textnode;
}
+ textstack_update_last_element(data->text_stack, textnode);
} else {
md_node_add_child(current, textnode);
+ cxListAdd(data->text_stack, textnode);
}
+
} else {
// root node
data->p_current->content = textnode;
cxListAdd(data->text_stack, textnode);
}
-
+
return 0;
}
case 6: return EDITOR_STYLE_HEADING6;
}
}
+ case MD_BLOCK_QUOTE: return EDITOR_STYLE_QUOTE;
case MD_BLOCK_CODE: return EDITOR_STYLE_CODE_BLOCK;
default: return EDITOR_STYLE_PARAGRAPH;
}
MDNode *t0;
MDNode *t1;
MDNode *t2;
+ MDNode *t3;
CX_TEST_DO {
doc = parse_markdown(CX_STR("test **bold** end"));
CX_TEST_ASSERT(t1->type == MD_SPAN_STRONG);
CX_TEST_ASSERT(!cx_strcmp(mdnode_get_text(t1), CX_STR("bold end")));
mddoc_free(doc);
+
+ doc = parse_markdown(CX_STR("hello `code` hello *emphasis*"));
+ CX_TEST_ASSERT(doc);
+ CX_TEST_ASSERT(doc->content);
+ p0 = doc->content;
+ CX_TEST_ASSERT(p0->type == MD_BLOCK_P);
+ t0 = p0->content;
+ CX_TEST_ASSERT(t0->text.ptr);
+ CX_TEST_ASSERT(!cx_strcmp(cx_strcast(t0->text), CX_STR("hello ")));
+ t1 = t0->next;
+ CX_TEST_ASSERT(t1);
+ CX_TEST_ASSERT(t1->type == MD_SPAN_CODE);
+ CX_TEST_ASSERT(!cx_strcmp(mdnode_get_text(t1), CX_STR("code")));
+ t2 = t1->next;
+ CX_TEST_ASSERT(t2);
+ CX_TEST_ASSERT(t2->text.ptr);
+ CX_TEST_ASSERT(!cx_strcmp(cx_strcast(t2->text), CX_STR(" hello ")));
+ t3 = t2->next;
+ CX_TEST_ASSERT(t3);
+ CX_TEST_ASSERT(t3->type == MD_SPAN_EM);
+ CX_TEST_ASSERT(!cx_strcmp(mdnode_get_text(t3), CX_STR("emphasis")));
+
+ doc = parse_markdown(CX_STR("test *begin __bold__ text* end"));
+ CX_TEST_ASSERT(doc);
+ CX_TEST_ASSERT(doc->content);
+ p0 = doc->content;
+ CX_TEST_ASSERT(p0->type == MD_BLOCK_P);
+ t0 = p0->content;
+ CX_TEST_ASSERT(t0);
+ CX_TEST_ASSERT(t0->text.ptr);
+ CX_TEST_ASSERT(!cx_strcmp(cx_strcast(t0->text), CX_STR("test ")));
+ t1 = t0->next;
+ CX_TEST_ASSERT(t1);
+ CX_TEST_ASSERT(!t1->text.ptr);
+ CX_TEST_ASSERT(t1->type == MD_SPAN_EM);
+ t2 = t1->next;
+ CX_TEST_ASSERT(t2);
+ CX_TEST_ASSERT(t2->text.ptr);
+ CX_TEST_ASSERT(!cx_strcmp(cx_strcast(t2->text), CX_STR(" end")));
+ MDNode *em_t0 = t1->children_begin;
+ CX_TEST_ASSERT(em_t0);
+ CX_TEST_ASSERT(em_t0->text.ptr);
+ CX_TEST_ASSERT(!cx_strcmp(cx_strcast(em_t0->text), CX_STR("begin ")));
+ MDNode *em_t1 = em_t0->next;
+ CX_TEST_ASSERT(em_t1);
+ CX_TEST_ASSERT(em_t1->type == MD_SPAN_STRONG);
+ CX_TEST_ASSERT(!cx_strcmp(mdnode_get_text(em_t1), CX_STR("bold")));
+ MDNode *em_t2 = em_t1->next;
+ CX_TEST_ASSERT(em_t2);
+ CX_TEST_ASSERT(!em_t2->next);
+ CX_TEST_ASSERT(em_t2->text.ptr);
+ CX_TEST_ASSERT(!cx_strcmp(cx_strcast(em_t2->text), CX_STR(" text")));
}
}