aboutsummaryrefslogtreecommitdiff
path: root/config/markdown_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'config/markdown_plugin.c')
-rw-r--r--config/markdown_plugin.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/config/markdown_plugin.c b/config/markdown_plugin.c
new file mode 100644
index 0000000..ded0e1c
--- /dev/null
+++ b/config/markdown_plugin.c
@@ -0,0 +1,126 @@
+#include "ecex.h"
+
+#define MD_TEXT_TITLE 1
+
+typedef struct md_state {
+ ecex_t *ed;
+} md_state_t;
+
+static int md_render(ecex_t *ed, buffer_t *buffer, ecex_draw_context_t *ctx, void *userdata) {
+ md_state_t *state = (md_state_t *)userdata;
+ int draw_count;
+ int line_count;
+ int scroll;
+ int y;
+ int h;
+ int line_h;
+ int in_code = 0;
+ int i;
+
+ if (!ed || !buffer || !ctx || !state) return 0;
+
+ draw_count = ecex_var_i32(ed, state, "draw_count", 0) + 1;
+ ecex_var_i32_set_scalar(ed, state, "draw_count", draw_count);
+ if (draw_count <= 2 || (draw_count % 120) == 0) {
+ ecex_log_int("markdown_plugin_draw: count=", draw_count);
+ }
+
+ line_count = ecex_buffer_line_count_i(buffer);
+ ecex_log_int("markdown_plugin_draw: line_count=", line_count);
+ if (line_count < 0) line_count = 0;
+
+ ecex_text_set_buffer_title(ed, state, MD_TEXT_TITLE, buffer);
+ ecex_draw_markdown_canvas_auto_i(ctx, state, MD_TEXT_TITLE);
+
+ y = ecex_markdown_body_y_i(ctx);
+ h = ecex_draw_context_height_i(ctx);
+ line_h = ecex_draw_context_line_height_i(ctx);
+ scroll = ecex_buffer_scroll_line(buffer);
+ if (scroll < 0) scroll = 0;
+ if (scroll > line_count) scroll = line_count;
+
+ for (i = scroll; i < line_count && y < h - line_h; ++i) {
+ int packed;
+ int advance;
+ if (i < scroll + 4) ecex_log_int("markdown_plugin_draw: host line=", i);
+ packed = ecex_markdown_draw_line_from_buffer_i(ctx, state, buffer, i, y, in_code);
+ in_code = (packed & 0x10000) ? 1 : 0;
+ advance = packed & 0xffff;
+ if (advance <= 0) advance = line_h;
+ y += advance;
+ }
+
+ return 0;
+}
+
+static void md_free_state(void *userdata) {
+ md_state_t *state = (md_state_t *)userdata;
+ ecex_t *ed;
+ if (!state) return;
+ ed = state->ed;
+ ecex_text_free_owner(ed, state);
+ ecex_var_free_owner(ed, state);
+ ecex_object_free(ed, state);
+}
+
+static int md_view_buffer(ecex_t *ed, buffer_t *buffer) {
+ md_state_t *state;
+ if (!ed || !buffer) return -1;
+ if (ecex_buffer_has_renderer(buffer)) ecex_buffer_clear_renderer(buffer);
+
+ state = (md_state_t *)ecex_object_calloc(ed, 1, sizeof(*state));
+ if (!state) return -1;
+ state->ed = ed;
+
+ if (ecex_buffer_set_renderer(buffer, md_render, state, md_free_state, ECEX_RENDER_REPLACE_CONTENT) != 0) {
+ ecex_object_free(ed, state);
+ return -1;
+ }
+ ecex_buffer_set_major_mode_by_name(ed, buffer, "markdown-mode");
+ return 0;
+}
+
+static int md_file_handler(ecex_t *ed, buffer_t *buffer) {
+ if (!buffer) return -1;
+ if (ecex_buffer_has_renderer(buffer)) return 0;
+ return md_view_buffer(ed, buffer);
+}
+
+static int cmd_markdown_view(ecex_t *ed) {
+ return md_view_buffer(ed, ecex_current_buffer(ed));
+}
+
+static int cmd_markdown_source(ecex_t *ed) {
+ buffer_t *buffer = ecex_current_buffer(ed);
+ if (!buffer) return -1;
+ if (ecex_buffer_has_renderer(buffer)) ecex_buffer_clear_renderer(buffer);
+ ecex_buffer_set_major_mode_by_name(ed, buffer, "markdown-mode");
+ return 0;
+}
+
+static int cmd_markdown_toggle(ecex_t *ed) {
+ buffer_t *buffer = ecex_current_buffer(ed);
+ if (!buffer) return -1;
+ if (ecex_buffer_has_renderer(buffer)) return cmd_markdown_source(ed);
+ return md_view_buffer(ed, buffer);
+}
+
+int ecex_markdown_plugin(ecex_t *ed) {
+ ECEX_CONFIG_MODE("markdown-mode");
+ ECEX_CONFIG_COMMAND("markdown-view", cmd_markdown_view);
+ ECEX_CONFIG_COMMAND("markdown-source", cmd_markdown_source);
+ ECEX_CONFIG_COMMAND("markdown-toggle", cmd_markdown_toggle);
+ ECEX_CONFIG_MODE_BIND("markdown-mode", "C-c C-c", "markdown-toggle");
+ ECEX_CONFIG_MODE_BIND("markdown-mode", "C-c C-s", "markdown-source");
+ ecex_register_file_handler(ed, ".md", md_file_handler);
+ ecex_register_file_handler(ed, ".markdown", md_file_handler);
+ ecex_register_file_handler(ed, ".mdown", md_file_handler);
+ ecex_register_file_handler(ed, ".mkd", md_file_handler);
+ return 0;
+}
+
+#ifndef ECEX_NO_STANDALONE_CONFIG
+ECEX_CONFIG_BEGIN
+ ECEX_CONFIG_INCLUDE(ecex_markdown_plugin);
+ECEX_CONFIG_END
+#endif