36PLUGIN_SET_INFO(
_(
"Export"),
_(
"Exports the current file into different formats."), VERSION,
37 _(
"The Geany developer team"))
43#define ROTATE_RGB(color) \
44 (((color) & 0xFF0000) >> 16) + ((color) & 0x00FF00) + (((color) & 0x0000FF) << 16)
45#define TEMPLATE_HTML "\
46<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\
47 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n\
48<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n\
51 <title>{export_filename}</title>\n\
52 <meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />\n\
53 <meta name=\"generator\" content=\"Geany " VERSION "\" />\n\
54 <meta name=\"date\" content=\"{export_date}\" />\n\
55 <style type=\"text/css\">\n\
67#define TEMPLATE_LATEX "\
68% {export_filename} (LaTeX code generated by Geany " VERSION " on {export_date})\n\
69\\documentclass[a4paper]{article}\n\
70\\usepackage[a4paper,margin=2cm]{geometry}\n\
71\\usepackage[utf8]{inputenc}\n\
72\\usepackage[T1]{fontenc}\n\
74\\setlength{\\parindent}{0em}\n\
75\\setlength{\\parskip}{2ex plus1ex minus0.5ex}\n\
80\\setlength{\\fboxrule}{0pt}\n\
81\\setlength{\\fboxsep}{0pt}\n\
103 gboolean use_zoom, gboolean insert_line_numbers);
113 gboolean use_zoom, gboolean insert_line_numbers);
115 gboolean use_zoom, gboolean insert_line_numbers);
122 gdouble rf = (rgb_colour % 256) / 256.0;
123 gdouble gf = ((rgb_colour & - 16711936) / 256) / 256.0;
124 gdouble bf = ((rgb_colour & 0xff0000) / 65536) / 256.0;
125 gint r = (gint) (rf * 10 + 0.5);
126 gint g = (gint) (gf * 10 + 0.5);
127 gint b = (gint) (bf * 10 + 0.5);
129 return g_strdup_printf(
"%d.%d, %d.%d, %d.%d", r / 10, r % 10, g / 10, g % 10, b / 10, b % 10);
141 buf[i] = (style % 26) +
'a';
152 gboolean show_zoom_level_checkbox)
158 g_return_if_fail(extension !=
NULL);
161 g_return_if_fail(doc !=
NULL);
168 dialog = gtk_file_chooser_dialog_new(
_(
"Export File"), GTK_WINDOW(
geany->main_widgets->window),
169 GTK_FILE_CHOOSER_ACTION_SAVE,
NULL,
NULL);
170 gtk_window_set_modal(GTK_WINDOW(
dialog), TRUE);
171 gtk_window_set_destroy_with_parent(GTK_WINDOW(
dialog), TRUE);
172 gtk_window_set_skip_taskbar_hint(GTK_WINDOW(
dialog), TRUE);
173 gtk_window_set_type_hint(GTK_WINDOW(
dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
174 gtk_widget_set_name(
dialog,
"GeanyExportDialog");
176 gtk_dialog_add_buttons(GTK_DIALOG(
dialog),
177 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
178 gtk_dialog_set_default_response(GTK_DIALOG(
dialog), GTK_RESPONSE_ACCEPT);
181 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
182 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(
dialog), vbox);
184 GtkWidget *check_line_numbers;
186 check_line_numbers = gtk_check_button_new_with_mnemonic(
_(
"_Insert line numbers"));
187 gtk_widget_set_tooltip_text(check_line_numbers,
188 _(
"Insert line numbers before each line in the exported document"));
189 gtk_box_pack_start(GTK_BOX(vbox), check_line_numbers, FALSE, FALSE, 0);
194 if (show_zoom_level_checkbox)
196 GtkWidget *check_zoom_level;
198 check_zoom_level = gtk_check_button_new_with_mnemonic(
_(
"_Use current zoom level"));
199 gtk_widget_set_tooltip_text(check_zoom_level,
200 _(
"Renders the font size of the document together with the current zoom level"));
201 gtk_box_pack_start(GTK_BOX(vbox), check_zoom_level, FALSE, FALSE, 0);
208 g_signal_connect(
dialog,
"delete-event", G_CALLBACK(gtk_widget_hide_on_delete),
NULL);
211 gtk_window_set_transient_for(GTK_WINDOW(
dialog), GTK_WINDOW(
geany->main_widgets->window));
214 gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(
dialog));
217 gchar *base_name = g_path_get_basename(doc->
file_name);
219 gchar *locale_filename;
220 gchar *locale_dirname;
221 const gchar *suffix =
"";
223 if (g_str_has_suffix(doc->
file_name, extension))
226 file_name = g_strconcat(base_name, suffix, extension,
NULL);
228 locale_dirname = g_path_get_dirname(locale_filename);
232 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(
dialog), locale_dirname);
233 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(
dialog), file_name);
234 g_free(locale_dirname);
235 g_free(locale_filename);
241 const gchar *default_open_path =
geany->prefs->default_open_path;
244 gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(
dialog));
245 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(
dialog), fname);
248 if (!
EMPTY(default_open_path) && g_path_is_absolute(default_open_path))
251 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(
dialog), locale_path);
256 gtk_dialog_run(GTK_DIALOG(
dialog));
278 ui_set_statusbar(TRUE,
_(
"Document successfully exported as '%s'."), utf8_filename);
281 utf8_filename, g_strerror(error_nr));
283 g_free(utf8_filename);
294 format =
"%Y-%m-%dT%H:%M:%S%z";
296 format =
"%Y-%m-%dT%H:%M:%S";
309 if (response == GTK_RESPONSE_ACCEPT && exi !=
NULL)
311 gchar *new_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(
dialog));
312 gchar *utf8_filename;
313 gboolean insert_line_numbers;
314 gboolean use_zoom_level = FALSE;
318 use_zoom_level = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
321 insert_line_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
327 if (g_file_test(new_filename, G_FILE_TEST_EXISTS))
330 _(
"The file '%s' already exists. Do you want to overwrite it?"),
331 utf8_filename) == FALSE)
335 exi->
export_func(exi->
doc, new_filename, use_zoom_level, insert_line_numbers);
337 g_free(utf8_filename);
338 g_free(new_filename);
341 gtk_widget_destroy(GTK_WIDGET(
dialog));
349 while ((line_number /= 10) != 0)
363 gboolean use_zoom, gboolean insert_line_numbers)
367 gint i, doc_len, style = -1, old_style = 0, column = 0;
368 gint k, line_number, line_number_width, line_number_max_width = 0, pad;
369 gchar c, c_next, *tmp, *date;
372 gboolean block_open = FALSE;
387 if (insert_line_numbers)
391 body = g_string_new(
"");
393 for (i = 0; i < doc_len; i++)
400 if (insert_line_numbers && column == 0)
405 pad = line_number_max_width - line_number_width;
406 for (k = 0; k < pad; k++)
408 g_string_append(body,
" ");
410 g_string_append_printf(body,
"%d ", line_number);
413 if (style != old_style || ! block_open)
416 styles[style][
USED] = 1;
419 g_string_append(body,
"}\n");
424 g_string_append_printf(body,
"\\style%s{",
get_tex_style(style));
434 if (c ==
'\r' && c_next ==
'\n')
439 g_string_append(body,
"}");
442 g_string_append(body,
" \\\\\n");
449 gint tab_stop = tab_width - (column % tab_width);
451 column += tab_stop - 1;
452 g_string_append_printf(body,
"\\hspace*{%dem}", tab_stop);
459 g_string_append(body,
"{\\hspace*{1em}}");
463 g_string_append_c(body,
' ');
474 g_string_append_printf(body,
"\\%c", c);
479 g_string_append(body,
"\\symbol{92}");
484 g_string_append(body,
"\\symbol{126}");
489 g_string_append(body,
"\\symbol{94}");
497 g_string_append_c(body, c);
499 g_string_append(body,
"\\/");
503 default: g_string_append_c(body, c);
509 g_string_append(body,
"}\n");
517 cmds = g_string_new(
"");
522 g_string_append_printf(cmds,
525 g_string_append(cmds,
"\\textbf{");
527 g_string_append(cmds,
"\\textit{");
530 g_string_append_printf(cmds,
"\\textcolor[rgb]{%s}{", tmp);
533 g_string_append_printf(cmds,
"\\fcolorbox[rgb]{0, 0, 0}{%s}{", tmp);
534 g_string_append(cmds,
"#1}}");
538 g_string_append_c(cmds,
'}');
540 g_string_append_c(cmds,
'}');
541 g_string_append(cmds,
"}}\n");
555 g_string_free(body, TRUE);
556 g_string_free(cmds, TRUE);
557 g_string_free(latex, TRUE);
563 gboolean use_zoom, gboolean insert_line_numbers)
567 gint i, doc_len, style = -1, old_style = 0, column = 0;
568 gint k, line_number, line_number_width, line_number_max_width = 0, pad;
569 gchar c, c_next, *date, *doc_filename;
572 gboolean span_open = FALSE;
573 const gchar *font_name;
575 PangoFontDescription *font_desc;
591 font_desc = pango_font_description_from_string(
geany->interface_prefs->editor_font);
592 font_name = pango_font_description_get_family(font_desc);
599 if (insert_line_numbers)
603 body = g_string_new(
"");
605 for (i = 0; i < doc_len; i++)
613 if (insert_line_numbers && column == 0)
618 pad = line_number_max_width - line_number_width;
619 for (k = 0; k < pad; k++)
621 g_string_append(body,
" ");
623 g_string_append_printf(body,
"%d ", line_number);
626 if ((style != old_style || ! span_open) && ! isspace(c))
629 styles[style][
USED] = 1;
632 g_string_append(body,
"</span>");
636 g_string_append_printf(body,
"<span class=\"style_%d\">", style);
646 if (c ==
'\r' && c_next ==
'\n')
651 g_string_append(body,
"</span>");
654 g_string_append(body,
"<br />\n");
662 gint tab_stop = tab_width - (column % tab_width);
664 column += tab_stop - 1;
665 for (j = 0; j < tab_stop; j++)
667 g_string_append(body,
" ");
673 g_string_append(body,
" ");
678 g_string_append(body,
"<");
683 g_string_append(body,
">");
688 g_string_append(body,
"&");
691 default: g_string_append_c(body, c);
697 g_string_append(body,
"</span>");
702 css = g_string_new(
"");
703 g_string_append_printf(css,
704 "\tbody\n\t{\n\t\tfont-family: %s, monospace;\n\t\tfont-size: %dpt;\n\t}\n",
705 font_name, font_size);
711 g_string_append_printf(css,
712 "\t.style_%d\n\t{\n\t\tcolor: #%06x;\n\t\tbackground-color: #%06x;\n%s%s\t}\n",
713 i, styles[i][
FORE], styles[i][
BACK],
714 (styles[i][
BOLD]) ?
"\t\tfont-weight: bold;\n" :
"",
715 (styles[i][
ITALIC]) ?
"\t\tfont-style: italic;\n" :
"");
720 doc_filename = g_markup_escape_text(
DOC_FILENAME(doc), -1);
730 pango_font_description_free(font_desc);
731 g_string_free(body, TRUE);
732 g_string_free(css, TRUE);
733 g_string_free(html, TRUE);
734 g_free(doc_filename);
741 GtkWidget *menu_export;
742 GtkWidget *menu_export_menu;
743 GtkWidget *menu_create_html;
744 GtkWidget *menu_create_latex;
746 menu_export = gtk_image_menu_item_new_with_mnemonic(
_(
"_Export"));
749 menu_export_menu = gtk_menu_new ();
750 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_export), menu_export_menu);
753 menu_create_html = gtk_menu_item_new_with_mnemonic(
_(
"As _HTML..."));
759 menu_create_latex = gtk_menu_item_new_with_mnemonic(
_(
"As _LaTeX..."));
762 g_signal_connect(menu_create_latex,
"activate",
sptr_t scintilla_send_message(ScintillaObject *sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam)
#define SCI_STYLEGETITALIC
gboolean dialogs_show_question(const gchar *text,...)
Shows a question message box with text and Yes/No buttons.
GeanyDocument * document_get_current(void)
Finds the current document.
#define DOC_FILENAME(doc)
Returns the filename of the document passed or GEANY_STRING_UNTITLED (e.g.
static gint get_line_numbers_arity(gint line_number)
static void on_menu_create_html_activate(GtkMenuItem *menuitem, gpointer user_data)
static void write_html_file(GeanyDocument *doc, const gchar *filename, gboolean use_zoom, gboolean insert_line_numbers)
static void create_file_save_as_dialog(const gchar *extension, ExportFunc func, gboolean show_zoom_level_checkbox)
static gchar * get_date(gint type)
void plugin_cleanup(void)
Called before unloading the plugin.
#define ROTATE_RGB(color)
static void on_file_save_dialog_response(GtkDialog *dialog, gint response, gpointer user_data)
static gchar * get_tex_style(gint style)
static GtkWidget * main_menu_item
static gint get_line_number_width(GeanyDocument *doc)
void plugin_init(GeanyData *data)
Called after loading the plugin.
static void write_latex_file(GeanyDocument *doc, const gchar *filename, gboolean use_zoom, gboolean insert_line_numbers)
static void on_menu_create_latex_activate(GtkMenuItem *menuitem, gpointer user_data)
void(* ExportFunc)(GeanyDocument *doc, const gchar *filename, gboolean use_zoom, gboolean insert_line_numbers)
static void write_data(const gchar *filename, const gchar *data)
static gchar * get_tex_rgb(gint rgb_colour)
#define GEANY_STRING_UNTITLED
Single include for plugins.
#define GEANY_API_VERSION
The Application Programming Interface (API) version, incremented whenever any plugin data types are m...
#define PLUGIN_SET_INFO(p_name, p_description, p_version, p_author)
Sets the plugin name and some other basic information about a plugin.
#define PLUGIN_VERSION_CHECK(api_required)
Defines a function to check the plugin is safe to load.
#define geany
Simple macro for geany_data that reduces typing.
gint sci_get_line_count(ScintillaObject *sci)
Gets the total number of lines.
gint sci_get_style_at(ScintillaObject *sci, gint position)
Gets style ID at position.
gint sci_get_length(ScintillaObject *sci)
Gets the length of all text.
gint sci_get_tab_width(ScintillaObject *sci)
Gets display tab width (this is not indent width, see GeanyIndentPrefs).
gchar sci_get_char_at(ScintillaObject *sci, gint pos)
Gets a character.
gint sci_get_line_from_position(ScintillaObject *sci, gint position)
Gets the line number from position.
gtk_container_add(GTK_CONTAINER(dialog->vbox), check_button)
ui_hookup_widget(dialog, check_button, "check_handle")
gtk_widget_show_all(dialog)
gboolean have_zoom_level_checkbox
This contains pointers to global variables owned by Geany for plugins to use.
Structure for representing an open tab with all its properties.
gchar * file_name
The UTF-8 encoded file name.
GeanyEditor * editor
The editor associated with the document.
Editor-owned fields for each document.
ScintillaObject * sci
The Scintilla editor GtkWidget.
void ui_add_document_sensitive(GtkWidget *widget)
Adds a widget to the list of widgets that should be set sensitive/insensitive when some documents are...
void ui_set_statusbar(gboolean log, const gchar *format,...)
Displays text on the statusbar.
GtkWidget * ui_lookup_widget(GtkWidget *widget, const gchar *widget_name)
Returns a widget from a name in a component, usually created by Glade.
gint utils_write_file(const gchar *filename, const gchar *text)
Writes text into a file named filename.
guint utils_string_replace_all(GString *haystack, const gchar *needle, const gchar *replace)
Replaces all occurrences of needle in haystack with replace.
gchar * utils_get_utf8_from_locale(const gchar *locale_text)
Converts the given string (in locale encoding) into UTF-8 encoding.
gchar * utils_get_date_time(const gchar *format, time_t *time_to_use)
Retrieves a formatted date/time string from strftime().
gchar * utils_get_locale_from_utf8(const gchar *utf8_text)
Converts the given UTF-8 encoded string into locale encoding.
#define EMPTY(ptr)
Returns TRUE if ptr is NULL or *ptr is FALSE.