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")));
     }
 }