From d9400495a4b82856f0ed9757e69eaf6c2de2ef73 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Wed, 30 Apr 2025 20:20:14 +0200 Subject: [PATCH] implement ordered list elements --- application/editor.c | 10 +++++----- application/editor.h | 3 ++- application/gtk-text.c | 34 +++++++++++++++++++++++++++++----- application/gtk-text.h | 6 +++++- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/application/editor.c b/application/editor.c index 8c2fbf9..a1fedec 100644 --- a/application/editor.c +++ b/application/editor.c @@ -332,7 +332,7 @@ static const char* node_style(MDNode *n) { return NULL; } -static void linearize_mdnodes(CxBuffer *buf, CxList *sections, MDNode *n, int depth) { +static void linearize_mdnodes(CxBuffer *buf, CxList *sections, MDNode *n, int depth, MD_BLOCKTYPE parenttype) { if(depth >= MD_MAX_DEPTH) { return; } @@ -344,7 +344,7 @@ static void linearize_mdnodes(CxBuffer *buf, CxList *sections, MDNode *n, int de MDDocStyleSection sec; sec.pos = buf->pos; sec.length = MDDocStyleSection_LIST; - sec.style = EDITOR_STYLE_LIST0; + sec.style = parenttype == MD_BLOCK_UL ? EDITOR_STYLE_LIST0 : EDITOR_STYLE_ORDLIST0; sec.link = NULL; sec.num = n->num; sec.depth = depth; @@ -355,7 +355,7 @@ static void linearize_mdnodes(CxBuffer *buf, CxList *sections, MDNode *n, int de MDNode *c = n->children_begin; depth++; while(c) { - linearize_mdnodes(buf, sections, c, depth+1); + linearize_mdnodes(buf, sections, c, depth+1, MD_BLOCK_LI); c = c->next; } @@ -382,7 +382,7 @@ static void linearize_mdnodes(CxBuffer *buf, CxList *sections, MDNode *n, int de MDNode *c = n->children_begin; depth++; while(c) { - linearize_mdnodes(buf, sections, c, depth+1); + linearize_mdnodes(buf, sections, c, depth+1, 0); c = c->next; } @@ -422,7 +422,7 @@ static void linearize_paragraph(CxBuffer *buf, CxList *sections, MDPara *p) { MDNode *n = p->content; while(n) { - linearize_mdnodes(buf, sections, n, 0); + linearize_mdnodes(buf, sections, n, 0, p->type); n = n->next; } cxBufferPut(buf, '\n'); diff --git a/application/editor.h b/application/editor.h index b44e70c..41c03dd 100644 --- a/application/editor.h +++ b/application/editor.h @@ -47,7 +47,8 @@ extern "C" { #define EDITOR_STYLE_HEADING6 "heading6" #define EDITOR_STYLE_QUOTE "quote" #define EDITOR_STYLE_CODE_BLOCK "code_block" -#define EDITOR_STYLE_LIST0 "list0" +#define EDITOR_STYLE_LIST0 "ul0" +#define EDITOR_STYLE_ORDLIST0 "ol0" #define EDITOR_STYLE_EMPHASIS "emphasis" #define EDITOR_STYLE_STRONG "strong" #define EDITOR_STYLE_CODE "code" diff --git a/application/gtk-text.c b/application/gtk-text.c index 13667d3..6308980 100644 --- a/application/gtk-text.c +++ b/application/gtk-text.c @@ -827,6 +827,11 @@ void init_tagtable(GtkTextTagTable *table) { g_object_set(tag, "indent", -40, NULL); g_object_set_data(G_OBJECT(tag), "set_style", (void*)tagstyle_list0); gtk_text_tag_table_add(table, tag); + + tag = gtk_text_tag_new(EDITOR_STYLE_ORDLIST0); + g_object_set(tag, "indent", -40, NULL); + g_object_set_data(G_OBJECT(tag), "set_style", (void*)tagstyle_list0); + gtk_text_tag_table_add(table, tag); } /* @@ -880,7 +885,7 @@ void editor_apply_styles(Resource *note, UIWIDGET textview, UiText *text, CxList // TODO: what do we do in this case? } } else if(sec->length == MDDocStyleSection_LIST) { - editor_insert_list_element(editor, &iter, 0); + editor_insert_list_element(editor, &iter, sec->style, sec->num); } } @@ -1190,12 +1195,14 @@ static void draw_bulletlist( int height, gpointer data) { + ListElmWidget *elm = data; + GtkWidget *parent = gtk_widget_get_parent(GTK_WIDGET(area)); PangoContext *context = gtk_widget_get_pango_context(parent); PangoFontDescription *font = pango_context_get_font_description(context); PangoLayout *layout = pango_cairo_create_layout(cr); - pango_layout_set_text (layout, "•", -1); + pango_layout_set_text (layout, elm->str, -1); pango_layout_set_font_description (layout, font); int textwidth; @@ -1214,7 +1221,13 @@ static void md_serialize_list(EmbeddedWidget *em, CxBuffer *out) { cxBufferPutString(out, " - "); } -void editor_insert_list_element(NoteEditor *editor, GtkTextIter *iter, int type) { +static void destroy_listelm(gpointer data) { + ListElmWidget *elm = data; + free(elm->str); + free(elm); +} + +void editor_insert_list_element(NoteEditor *editor, GtkTextIter *iter, const char *style, int num) { GtkTextView *textview = GTK_TEXT_VIEW(editor->textview); GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview); @@ -1225,11 +1238,21 @@ void editor_insert_list_element(NoteEditor *editor, GtkTextIter *iter, int type) int descent = pango_font_metrics_get_descent(metrics) / PANGO_SCALE; int height = pango_font_metrics_get_height(metrics) / PANGO_SCALE; + ListElmWidget *elm = malloc(sizeof(ListElmWidget)); + if(!strcmp(style, EDITOR_STYLE_LIST0)) { + elm->str = strdup("•"); + } else { + char buf[32]; + snprintf(buf, 32, "%d", num); + elm->str = strdup(buf); + } + GtkWidget *widget = gtk_drawing_area_new(); // • - gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(widget), draw_bulletlist, NULL, NULL); + gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(widget), draw_bulletlist, elm, destroy_listelm); gtk_widget_set_size_request(widget, 40, height); //gtk_widget_add_css_class(widget, "ui_test"); gtk_widget_set_margin_bottom(widget, -descent); + g_object_set_data(G_OBJECT(widget), "listelm", elm); GtkTextMark *start_mark = gtk_text_buffer_create_mark(buffer, NULL, iter, TRUE); @@ -1272,5 +1295,6 @@ void editor_insert_list(UiText *text, UiBool ordered) { GtkTextIter iter; gtk_text_buffer_get_iter_at_mark(buffer, &iter, cursor); - editor_insert_list_element(editor, &iter, 0); + const char *style = ordered ? EDITOR_STYLE_ORDLIST0 : EDITOR_STYLE_LIST0; + editor_insert_list_element(editor, &iter, style, 0); } diff --git a/application/gtk-text.h b/application/gtk-text.h index 22cd1be..503c633 100644 --- a/application/gtk-text.h +++ b/application/gtk-text.h @@ -72,13 +72,17 @@ struct EmbeddedWidget { void (*serialize)(EmbeddedWidget *e, CxBuffer *out); }; +typedef struct ListElmWidget { + char *str; +} ListElmWidget; + typedef void (*set_style_cb)(MDActiveStyles *style, GtkTextTag *tag); 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 editor_insert_list_element(NoteEditor *editor, GtkTextIter *iter, const char *style, int num); void init_textbuf(GtkTextBuffer *buf); void init_tagtable(GtkTextTagTable *table); -- 2.43.5