From 87b644ecd8f207e71b83be4f5cc52dbf4a34d9be Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Thu, 20 Mar 2025 21:38:39 +0100 Subject: [PATCH] implement serialization of md image tags --- application/gtk-text.c | 47 +++++++++++++++++++++++++++++++++++++++--- application/gtk-text.h | 7 ++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/application/gtk-text.c b/application/gtk-text.c index f95ab26..fba2344 100644 --- a/application/gtk-text.c +++ b/application/gtk-text.c @@ -36,6 +36,8 @@ #include #include +#include + #include #include @@ -261,7 +263,11 @@ static gboolean editor_attach_file(NoteEditor *editor, const char *path) { return FALSE; // TODO } -static void editor_attach_image(NoteEditor *editor, GdkPixbuf *pixbuf) { +void md_serialize_image(EmbeddedWidget *em, CxBuffer *out) { + cx_bprintf(out, "![image](%s)", em->name); +} + +static void editor_attach_image(NoteEditor *editor, GdkPixbuf *pixbuf, char *attachment_path) { GtkTextView *textview = GTK_TEXT_VIEW(editor->textview); GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview); @@ -284,10 +290,16 @@ static void editor_attach_image(NoteEditor *editor, GdkPixbuf *pixbuf) { EmbeddedWidget *em = malloc(sizeof(EmbeddedWidget)); em->widget = image; em->anchor = anchor; - em->restore = NULL; + em->name = attachment_path ? strdup(util_resource_name(attachment_path)) : NULL; + em->path = attachment_path; + em->data1 = pixbuf; + em->data2 = NULL; + em->serialize = md_serialize_image; g_object_ref(image); g_object_ref(anchor); + g_object_set_data(G_OBJECT(anchor), "em", em); + BufferEmbeddedObjects *embedded_objects = g_object_get_data(G_OBJECT(buffer), "embedded"); cxListAdd(embedded_objects->objects, em); } @@ -337,6 +349,8 @@ static gboolean editor_drop_cb( double y, NoteEditor *editor) { + char *attachment_path = NULL; + gboolean success = TRUE; GdkPixbuf *pixbuf = NULL; if(G_VALUE_HOLDS(value, G_TYPE_FILE)) { @@ -353,6 +367,7 @@ static gboolean editor_drop_cb( g_free(scheme); char *path = g_file_get_path(file); + attachment_path = strdup(path); printf("dnd file: %s\n", path); if(path_is_image_file(cx_str(path))) { @@ -375,7 +390,9 @@ static gboolean editor_drop_cb( } if(pixbuf && success) { - editor_attach_image(editor, pixbuf); + editor_attach_image(editor, pixbuf, attachment_path); + } else { + free(attachment_path); } return success; @@ -700,11 +717,35 @@ cxmutstr editor_get_markdown(UiText *text, const CxAllocator *a) { CxMap *prev_tags = cxHashMapCreateSimple(CX_STORE_POINTERS); + GtkTextChildAnchor *anchor = NULL; + GtkTextIter start; GtkTextIter iter; gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); start = iter; while(gtk_text_iter_forward_to_tag_toggle(&iter, NULL)) { + if(anchor) { + EmbeddedWidget *em = g_object_get_data(G_OBJECT(anchor), "em"); + if(em) { + em->serialize(em, &out); + } + anchor = NULL; + } + + // check for anchors + GtkTextIter a = start; + while(!gtk_text_iter_equal(&a, &iter)) { + anchor = gtk_text_iter_get_child_anchor(&a); + gtk_text_iter_forward_char(&a); + if(anchor) { + iter = a; + break; + } + } + if(!anchor) { + anchor = gtk_text_iter_get_child_anchor(&iter); + } + gchar *text = gtk_text_buffer_get_text(buffer, &start, &iter, TRUE); GSList *tags = gtk_text_iter_get_tags(&start); diff --git a/application/gtk-text.h b/application/gtk-text.h index 97f30dd..c9f9bc2 100644 --- a/application/gtk-text.h +++ b/application/gtk-text.h @@ -30,6 +30,7 @@ #define GTK_TEXT_H #include "editor.h" +#include #ifdef __cplusplus extern "C" { @@ -56,9 +57,13 @@ typedef struct BufferEmbeddedObjects { typedef struct EmbeddedWidget EmbeddedWidget; struct EmbeddedWidget { - void (*restore)(NoteEditor *, EmbeddedWidget *); GtkWidget *widget; GtkTextChildAnchor *anchor; + char *name; + char *path; + void *data1; + void *data2; + void (*serialize)(EmbeddedWidget *e, CxBuffer *out); }; typedef void (*set_style_cb)(MDActiveStyles *style, GtkTextTag *tag); -- 2.43.5