From: Olaf Wintermann Date: Sat, 26 Apr 2025 11:36:44 +0000 (+0200) Subject: implement loading of MD lists in the text view X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=75b2ae0d5307728afcc374dc4c545713f18277b6;p=note.git implement loading of MD lists in the text view --- diff --git a/application/editor.c b/application/editor.c index 89370cf..b83da33 100644 --- a/application/editor.c +++ b/application/editor.c @@ -338,6 +338,31 @@ static void linearize_mdnodes(CxBuffer *buf, CxList *sections, MDNode *n, int de if(n->text.ptr) { cxBufferWrite(n->text.ptr, 1, n->text.length, buf); + } else if(n->type0 == MD_BLOCK_LI) { + // bullet point + MDDocStyleSection sec; + sec.pos = buf->pos; + sec.length = MDDocStyleSection_LIST; + sec.style = EDITOR_STYLE_LIST0; + sec.link = NULL; + cxListAdd(sections, &sec); + + size_t start_pos = buf->pos; + + MDNode *c = n->children_begin; + depth++; + while(c) { + linearize_mdnodes(buf, sections, c, depth); + c = c->next; + } + + sec.pos = start_pos; + sec.length = buf->pos - start_pos; + sec.style = EDITOR_STYLE_LIST0; + sec.link = NULL; + cxListAdd(sections, &sec); + + cxBufferPut(buf, '\n'); } else if(n->type == MD_SPAN_IMG) { MDDocStyleSection sec; sec.pos = buf->pos; @@ -379,7 +404,7 @@ static const char* paragraph_style(MDPara *p) { } case MD_BLOCK_QUOTE: return EDITOR_STYLE_QUOTE; case MD_BLOCK_CODE: return EDITOR_STYLE_CODE_BLOCK; - case MD_BLOCK_UL: return EDITOR_STYLE_LIST0; + case MD_BLOCK_UL: return EDITOR_STYLE_PARAGRAPH; default: return EDITOR_STYLE_PARAGRAPH; } } diff --git a/application/editor.h b/application/editor.h index 954c947..5d0e988 100644 --- a/application/editor.h +++ b/application/editor.h @@ -54,6 +54,7 @@ extern "C" { #define EDITOR_STYLE_LINK "link" #define MDDocStyleSection_IMAGE -1 +#define MDDocStyleSection_LIST -2 #define MD_MAX_DEPTH 50 diff --git a/application/gtk-text.c b/application/gtk-text.c index 27a0818..d22ec96 100644 --- a/application/gtk-text.c +++ b/application/gtk-text.c @@ -843,7 +843,7 @@ void editor_apply_styles(Resource *note, UIWIDGET textview, UiText *text, CxList CxIterator i = cxListIterator(styles); cx_foreach(MDDocStyleSection*, sec, i) { - if(sec->length == MDDocStyleSection_IMAGE) { + if(sec->length <= MDDocStyleSection_IMAGE) { // don't insert attachments now, because it would mess up the indices // insert in reverse order cxListInsert(insert_attachments, 0, sec); @@ -870,13 +870,17 @@ void editor_apply_styles(Resource *note, UIWIDGET textview, UiText *text, CxList i = cxListIterator(insert_attachments); cx_foreach(MDDocStyleSection *, sec, i) { - Attachment *attachment = note_get_attachment(note, sec->link); - if(attachment && attachment->ui->img->value) { - GtkTextIter iter; - gtk_text_buffer_get_iter_at_offset(buffer, &iter, sec->pos); - editor_insert_image(editor, attachment, &iter); - } else { - // TODO: what do we do in this case? + GtkTextIter iter; + gtk_text_buffer_get_iter_at_offset(buffer, &iter, sec->pos); + if(sec->length == MDDocStyleSection_IMAGE) { + Attachment *attachment = note_get_attachment(note, sec->link); + if(attachment && attachment->ui->img->value) { + editor_insert_image(editor, attachment, &iter); + } else { + // TODO: what do we do in this case? + } + } else if(sec->length == MDDocStyleSection_LIST) { + editor_insert_list_element(editor, &iter, 0); } } @@ -1210,16 +1214,9 @@ static void md_serialize_list(EmbeddedWidget *em, CxBuffer *out) { cxBufferPutString(out, " - "); } -void editor_insert_list(UiText *text, UiBool ordered) { - GtkTextBuffer *buffer = text->data1; - NoteEditor *editor = g_object_get_data(text->obj, "editor"); +void editor_insert_list_element(NoteEditor *editor, GtkTextIter *iter, int type) { GtkTextView *textview = GTK_TEXT_VIEW(editor->textview); - - GtkTextMark *cursor = gtk_text_buffer_get_insert(buffer); - if(!cursor) { - fprintf(stderr, "Error: no insert mark\n"); - return; - } + GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview); PangoContext *context = gtk_widget_get_pango_context(editor->textview); PangoFontMetrics *metrics = pango_context_get_metrics(context, NULL, NULL); @@ -1235,17 +1232,14 @@ void editor_insert_list(UiText *text, UiBool ordered) { gtk_widget_set_margin_bottom(widget, -descent); gtk_widget_set_margin_start(widget, -40); - GtkTextIter iter; - gtk_text_buffer_get_iter_at_mark(buffer, &iter, cursor); - GtkTextMark *start_mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, TRUE); + GtkTextMark *start_mark = gtk_text_buffer_create_mark(buffer, NULL, iter, TRUE); - GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(buffer, &iter); + GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(buffer, iter); gtk_text_view_add_child_at_anchor(textview, widget, anchor); - // iter is updated to new position GtkTextIter start; gtk_text_buffer_get_iter_at_mark(buffer, &start, start_mark); - gtk_text_buffer_apply_tag_by_name(buffer, EDITOR_STYLE_LIST0, &start, &iter); + gtk_text_buffer_apply_tag_by_name(buffer, EDITOR_STYLE_LIST0, &start, iter); gtk_text_buffer_delete_mark(buffer, start_mark); // remember widget/anchor @@ -1265,3 +1259,19 @@ void editor_insert_list(UiText *text, UiBool ordered) { BufferEmbeddedObjects *embedded_objects = g_object_get_data(G_OBJECT(buffer), "embedded"); cxListAdd(embedded_objects->objects, em); } + +void editor_insert_list(UiText *text, UiBool ordered) { + GtkTextBuffer *buffer = text->data1; + NoteEditor *editor = g_object_get_data(text->obj, "editor"); + + GtkTextMark *cursor = gtk_text_buffer_get_insert(buffer); + if(!cursor) { + fprintf(stderr, "Error: no insert mark\n"); + return; + } + + GtkTextIter iter; + gtk_text_buffer_get_iter_at_mark(buffer, &iter, cursor); + + editor_insert_list_element(editor, &iter, 0); +} diff --git a/application/gtk-text.h b/application/gtk-text.h index 1bed17a..22cd1be 100644 --- a/application/gtk-text.h +++ b/application/gtk-text.h @@ -78,6 +78,8 @@ void editor_try_follow_link(NoteEditor *editor, GtkTextIter *pos); void editor_update_embedded_widgets(NoteEditor *editor); +void editor_insert_list_element(NoteEditor *editor, GtkTextIter *iter, int type); + void init_textbuf(GtkTextBuffer *buf); void init_tagtable(GtkTextTagTable *table);