#include "gtk-text.h"
#include "editor.h"
+#include <cx/buffer.h>
+#include <cx/hash_map.h>
+
+static CxMap *markdown_tags;
+
+void editor_global_init() {
+ markdown_tags = cxHashMapCreateSimple(sizeof(MDTag));
+
+ cxMapPut(markdown_tags, EDITOR_STYLE_PARAGRAPH, &((MDTag){NULL, NULL}));
+ cxMapPut(markdown_tags, EDITOR_STYLE_HEADING1, &((MDTag){"# ", NULL}));
+ cxMapPut(markdown_tags, EDITOR_STYLE_HEADING2, &((MDTag){"## ", NULL}));
+ cxMapPut(markdown_tags, EDITOR_STYLE_HEADING3, &((MDTag){"### ", NULL}));
+ cxMapPut(markdown_tags, EDITOR_STYLE_HEADING4, &((MDTag){"#### ", NULL}));
+ cxMapPut(markdown_tags, EDITOR_STYLE_HEADING5, &((MDTag){"##### ", NULL}));
+ cxMapPut(markdown_tags, EDITOR_STYLE_HEADING6, &((MDTag){"###### ", NULL}));
+ cxMapPut(markdown_tags, EDITOR_STYLE_STRONG, &((MDTag){"**", "**"}));
+}
+
+
void editor_init_textview(UIWIDGET textview) {
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD_CHAR);
}
}
}
+
+
+static CxMap* tags2map(GSList *tags) {
+ CxMap *map = cxHashMapCreateSimple(CX_STORE_POINTERS);
+ while(tags) {
+ GtkTextTag *t = tags->data;
+ GValue name_value = G_VALUE_INIT;
+ g_object_get_property(G_OBJECT(t), "name", &name_value);
+ const char *name = g_value_get_string(&name_value);
+ if(name) {
+ cxMapPut(map, name, t);
+ }
+ tags = tags->next;
+ }
+ return map;
+}
+
+static CxMap* map_clone(CxMap *map) {
+ CxMap *newmap = cxHashMapCreateSimple(CX_STORE_POINTERS);
+ CxMapIterator i = cxMapIterator(map);
+ cx_foreach(CxMapEntry *, entry, i) {
+ cxMapPut(newmap, *entry->key, entry->value);
+ }
+ return newmap;
+}
+
+static void map_subtract(CxMap *map, CxMap *sub) {
+ CxMapIterator i = cxMapIterator(sub);
+ cx_foreach(CxMapEntry *, entry, i) {
+ cxMapRemove(map, *entry->key);
+ }
+}
+
+cxmutstr editor_get_markdown(UiText *text, const CxAllocator *a) {
+ char *str = ui_get(text);
+
+
+ CxBuffer out;
+ cxBufferInit(&out, NULL, 1024, a, CX_BUFFER_AUTO_EXTEND);
+
+ GtkTextBuffer *buffer = text->data1;
+
+ CxMap *prev_tags = cxHashMapCreateSimple(CX_STORE_POINTERS);
+
+ 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)) {
+ gchar *text = gtk_text_buffer_get_text(buffer, &start, &iter, TRUE);
+
+ GSList *tags = gtk_text_iter_get_tags(&start);
+ CxMap *begin_tags = tags2map(tags);
+ g_slist_free(tags);
+
+ // subtract prev_tags from begin_tags to get a map of all new tags
+ CxMap *new_tags = map_clone(begin_tags);
+ CxMap *begin_tags2 = map_clone(begin_tags);
+ map_subtract(new_tags, prev_tags);
+ cxMapFree(prev_tags);
+ prev_tags = begin_tags;
+
+ // check all new tags and add tag prefix code
+ CxMapIterator i = cxMapIterator(new_tags);
+ cx_foreach(CxMapEntry *, entry, i) {
+ MDTag *t = cxMapGet(markdown_tags, *entry->key);
+ if(t && t->begin) {
+ cxBufferPutString(&out, t->begin);
+ }
+ }
+ cxMapFree(new_tags);
+
+ // add content
+ printf("range: {%s}\n\n", text);
+ cxBufferPutString(&out, text);
+
+ // get all tags that ended here
+ tags = gtk_text_iter_get_tags(&iter);
+ CxMap *end_tags = tags2map(tags);
+ g_slist_free(tags);
+
+ // check end tags and add tag suffix
+ map_subtract(begin_tags2, end_tags);
+ i = cxMapIterator(begin_tags2);
+ cx_foreach(CxMapEntry *, entry, i) {
+ MDTag *t = cxMapGet(markdown_tags, *entry->key);
+ if(t && t->end) {
+ cxBufferPutString(&out, t->end);
+ }
+ }
+ cxMapFree(begin_tags2);
+ cxMapFree(end_tags);
+
+ g_free(text);
+ start = iter;
+ }
+
+
+ cxBufferTerminate(&out);
+
+ printf("new markdown doc: \n\n%s\n\n", out.space);
+
+ cxmutstr ret = cx_mutstrn(out.space, out.size);
+ return ret;
+}