[geany/geany-plugins] 6e3de1: Markdown: Allow exporting Markdown as HTML (#502)

Matthew Brush git-noreply at geany.org
Sun Nov 13 17:21:22 UTC 2016


Branch:      refs/heads/master
Author:      Matthew Brush <mbrush at codebrainz.ca>
Committer:   Frank Lanitz <frank at frank.uvena.de>
Date:        Sun, 13 Nov 2016 17:21:22 UTC
Commit:      6e3de19fbadfcc36147b88bbf964d3c3a62f9b07
             https://github.com/geany/geany-plugins/commit/6e3de19fbadfcc36147b88bbf964d3c3a62f9b07

Log Message:
-----------
Markdown: Allow exporting Markdown as HTML (#502)

* Markdown: Allow exporting Markdown as HTML

Add a Tools menu item "Export Markdown as HTML" to allow saving of the
rendered HTML to disk instead of just the live preview.

Closes #497

* Markdown: improve Export to HTML feature

* Use the document's filename as the basis for the new HTML filename.
* Properly setup the initial directory and suggested filename in the
  file chooser.
* Re-run the file chooser after showing error message if saving fails.


Modified Paths:
--------------
    markdown/src/plugin.c
    markdown/src/viewer.c
    markdown/src/viewer.h

Modified: markdown/src/plugin.c
91 lines changed, 91 insertions(+), 0 deletions(-)
===================================================================
@@ -48,13 +48,15 @@ PLUGIN_SET_TRANSLATABLE_INFO(LOCALEDIR, GETTEXT_PACKAGE,
 /* Global data */
 static MarkdownViewer *g_viewer = NULL;
 static GtkWidget *g_scrolled_win = NULL;
+static GtkWidget *g_export_html = NULL;
 
 /* Forward declarations */
 static void update_markdown_viewer(MarkdownViewer *viewer);
 static gboolean on_editor_notify(GObject *obj, GeanyEditor *editor, SCNotification *notif, MarkdownViewer *viewer);
 static void on_document_signal(GObject *obj, GeanyDocument *doc, MarkdownViewer *viewer);
 static void on_document_filetype_set(GObject *obj, GeanyDocument *doc, GeanyFiletype *ft_old, MarkdownViewer *viewer);
 static void on_view_pos_notify(GObject *obj, GParamSpec *pspec, MarkdownViewer *viewer);
+static void on_export_as_html_activate(GtkMenuItem *item, MarkdownViewer *viewer);
 
 /* Main plugin entry point on plugin load. */
 void plugin_init(GeanyData *data)
@@ -97,6 +99,11 @@ void plugin_init(GeanyData *data)
 
   g_signal_connect(conf, "notify::view-pos", G_CALLBACK(on_view_pos_notify), viewer);
 
+  g_export_html = gtk_menu_item_new_with_label(_("Export Markdown as HTML..."));
+  gtk_menu_shell_append(GTK_MENU_SHELL(data->main_widgets->tools_menu), g_export_html);
+  g_signal_connect(g_export_html, "activate", G_CALLBACK(on_export_as_html_activate), viewer);
+  gtk_widget_show(g_export_html);
+
 #define MD_PSC(sig, cb) \
   plugin_signal_connect(geany_plugin, NULL, (sig), TRUE, G_CALLBACK(cb), viewer)
   /* Geany takes care of disconnecting these for us when the plugin is unloaded,
@@ -119,6 +126,7 @@ void plugin_init(GeanyData *data)
 /* Cleanup resources on plugin unload. */
 void plugin_cleanup(void)
 {
+  gtk_widget_destroy(g_export_html);
   gtk_widget_destroy(g_scrolled_win);
 }
 
@@ -162,9 +170,11 @@ update_markdown_viewer(MarkdownViewer *viewer)
     gchar *text;
     text = (gchar*) scintilla_send_message(doc->editor->sci, SCI_GETCHARACTERPOINTER, 0, 0);
     markdown_viewer_set_markdown(viewer, text, doc->encoding);
+    gtk_widget_set_sensitive(g_export_html, TRUE);
   } else {
     markdown_viewer_set_markdown(viewer,
       _("The current document does not have a Markdown filetype."), "UTF-8");
+    gtk_widget_set_sensitive(g_export_html, FALSE);
   }
 
   markdown_viewer_queue_update(viewer);
@@ -240,3 +250,84 @@ on_view_pos_notify(GObject *obj, GParamSpec *pspec, MarkdownViewer *viewer)
 
   update_markdown_viewer(viewer);
 }
+
+static gchar *replace_extension(const gchar *utf8_fn, const gchar *new_ext)
+{
+  gchar *fn_noext, *new_fn, *dot;
+  fn_noext = g_filename_from_utf8(utf8_fn, -1, NULL, NULL, NULL);
+  dot = strrchr(fn_noext, '.');
+  if (dot != NULL) {
+    *dot = '\0';
+  }
+  new_fn = g_strconcat(fn_noext, new_ext, NULL);
+  g_free(fn_noext);
+  return new_fn;
+}
+
+static void on_export_as_html_activate(GtkMenuItem *item, MarkdownViewer *viewer)
+{
+  GtkWidget *dialog;
+  GtkFileFilter *filter;
+  gchar *fn;
+  GeanyDocument *doc;
+  gboolean saved = FALSE;
+
+  doc = document_get_current();
+  g_return_if_fail(DOC_VALID(doc));
+
+  dialog = gtk_file_chooser_dialog_new(_("Save HTML File As"),
+    GTK_WINDOW(geany_data->main_widgets->window), GTK_FILE_CHOOSER_ACTION_SAVE,
+    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+    GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+    NULL);
+  gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
+
+  fn = replace_extension(DOC_FILENAME(doc), ".html");
+  if (g_file_test(fn, G_FILE_TEST_EXISTS)) {
+    /* If the file exists, GtkFileChooser will change to the correct
+     * directory and show the base name as a suggestion. */
+    gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), fn);
+  } else {
+    /* If the file doesn't exist, change the directory and give a suggested
+     * name for the file, since GtkFileChooser won't do it. */
+    gchar *dn = g_path_get_dirname(fn);
+    gchar *bn = g_path_get_basename(fn);
+    gchar *utf8_name;
+    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dn);
+    g_free(dn);
+    utf8_name = g_filename_to_utf8(bn, -1, NULL, NULL, NULL);
+    gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), utf8_name);
+    g_free(bn);
+    g_free(utf8_name);
+  }
+  g_free(fn);
+
+  filter = gtk_file_filter_new();
+  gtk_file_filter_set_name(filter, _("HTML Files"));
+  gtk_file_filter_add_mime_type(filter, "text/html");
+  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
+
+  filter = gtk_file_filter_new();
+  gtk_file_filter_set_name(filter, _("All Files"));
+  gtk_file_filter_add_pattern(filter, "*");
+  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
+
+  while (!saved &&
+         gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+    gchar *html = markdown_viewer_get_html(viewer);
+    GError *error = NULL;
+    fn = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+    if (! g_file_set_contents(fn, html, -1, &error)) {
+      dialogs_show_msgbox(GTK_MESSAGE_ERROR,
+        _("Failed to export Markdown HTML to file '%s': %s"),
+        fn, error->message);
+      g_error_free(error);
+    } else {
+      saved = TRUE;
+    }
+    g_free(fn);
+    g_free(html);
+  }
+
+  gtk_widget_destroy(dialog);
+}


Modified: markdown/src/viewer.c
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -309,7 +309,7 @@ on_webview_load_status_notify(WebKitWebView *view, GParamSpec *pspec,
   }
 }
 
-static gchar *
+gchar *
 markdown_viewer_get_html(MarkdownViewer *self)
 {
   gchar *md_as_html, *html = NULL;


Modified: markdown/src/viewer.h
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -56,6 +56,7 @@ GtkWidget *markdown_viewer_new(MarkdownConfig *conf);
 void markdown_viewer_set_markdown(MarkdownViewer *self, const gchar *text,
   const gchar *encoding);
 void markdown_viewer_queue_update(MarkdownViewer *self);
+gchar *markdown_viewer_get_html(MarkdownViewer *self);
 
 G_END_DECLS
 



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Plugins-Commits mailing list