Branch: refs/heads/master Author: Matthew Brush mbrush@codebrainz.ca Committer: Frank Lanitz frank@frank.uvena.de Date: Sun, 13 Nov 2016 17:21:22 UTC Commit: 6e3de19fbadfcc36147b88bbf964d3c3a62f9b07 https://github.com/geany/geany-plugins/commit/6e3de19fbadfcc36147b88bbf964d3...
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).
plugins-commits@lists.geany.org