From 8663b54cae296883452850f3baad6d4cbc92e220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Wed, 25 Jul 2012 11:29:22 +0200 Subject: Highlighting of text parts and source codes This adds 'Format as' submenu to the preview pane context menu. The submenu is available only for text/plain parts or parts with a source code (we support about 40 various types). Using the 'highlight' utility, the formatter processes the part and highlights the source code it contains. (discussion in bug #680026) --- modules/text-highlight/Makefile.am | 16 +- .../e-mail-display-popup-text-highlight.c | 370 ++++++++++++++ .../e-mail-display-popup-text-highlight.h | 30 ++ .../e-mail-formatter-text-highlight.c | 391 +++++++++++++++ .../e-mail-formatter-text-highlight.h | 30 ++ .../text-highlight/e-mail-parser-text-highlight.c | 159 +++++++ .../text-highlight/e-mail-parser-text-highlight.h | 30 ++ .../evolution-module-text-highlight.c | 7 +- modules/text-highlight/languages.c | 529 +++++++++++++++++++++ modules/text-highlight/languages.h | 39 ++ modules/text-highlight/text-highlight.c | 310 ------------ modules/text-highlight/text-highlight.h | 30 -- 12 files changed, 1594 insertions(+), 347 deletions(-) create mode 100644 modules/text-highlight/e-mail-display-popup-text-highlight.c create mode 100644 modules/text-highlight/e-mail-display-popup-text-highlight.h create mode 100644 modules/text-highlight/e-mail-formatter-text-highlight.c create mode 100644 modules/text-highlight/e-mail-formatter-text-highlight.h create mode 100644 modules/text-highlight/e-mail-parser-text-highlight.c create mode 100644 modules/text-highlight/e-mail-parser-text-highlight.h create mode 100644 modules/text-highlight/languages.c create mode 100644 modules/text-highlight/languages.h delete mode 100644 modules/text-highlight/text-highlight.c delete mode 100644 modules/text-highlight/text-highlight.h (limited to 'modules/text-highlight') diff --git a/modules/text-highlight/Makefile.am b/modules/text-highlight/Makefile.am index 9b27298474..8c7e639622 100644 --- a/modules/text-highlight/Makefile.am +++ b/modules/text-highlight/Makefile.am @@ -9,10 +9,16 @@ module_text_highlight_la_CPPFLAGS = \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) -module_text_highlight_la_SOURCES = \ - text-highlight.c \ - text-highlight.h \ - evolution-module-text-highlight.c +module_text_highlight_la_SOURCES = \ + e-mail-display-popup-text-highlight.c \ + e-mail-display-popup-text-highlight.h \ + e-mail-formatter-text-highlight.c \ + e-mail-formatter-text-highlight.h \ + e-mail-parser-text-highlight.c \ + e-mail-parser-text-highlight.h \ + evolution-module-text-highlight.c \ + languages.c \ + languages.h module_text_highlight_la_LIBADD = \ $(top_builddir)/e-util/libeutil.la \ @@ -21,7 +27,7 @@ module_text_highlight_la_LIBADD = \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) -module_text_highlight_la_LDFLAGS = \ +module_text_highlight_la_LDFLAGS = \ -avoid-version -module $(NO_UNDEFINED) -include $(top_srcdir)/git.mk diff --git a/modules/text-highlight/e-mail-display-popup-text-highlight.c b/modules/text-highlight/e-mail-display-popup-text-highlight.c new file mode 100644 index 0000000000..0adea1dac7 --- /dev/null +++ b/modules/text-highlight/e-mail-display-popup-text-highlight.c @@ -0,0 +1,370 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "e-mail-display-popup-text-highlight.h" +#include "mail/e-mail-display-popup-extension.h" +#include "mail/e-mail-display.h" +#include +#include +#include "mail/e-mail-browser.h" + +#include + +#include + +#include "languages.h" + +#define d(x) + +typedef struct _EMailDisplayPopupTextHighlight { + EExtension parent; + + GtkActionGroup *action_group; + + WebKitDOMDocument *document; +} EMailDisplayPopupTextHighlight; + +typedef struct _EMailDisplayPopupTextHighlightClass { + EExtensionClass parent_class; +} EMailDisplayPopupTextHighlightClass; + +#define E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), e_mail_display_popup_text_highlight_get_type(), EMailDisplayPopupTextHighlight)) + +GType e_mail_display_popup_text_highlight_get_type (void); +static void e_mail_display_popup_extension_interface_init (EMailDisplayPopupExtensionInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED ( + EMailDisplayPopupTextHighlight, + e_mail_display_popup_text_highlight, + E_TYPE_EXTENSION, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC ( + E_TYPE_MAIL_DISPLAY_POPUP_EXTENSION, + e_mail_display_popup_extension_interface_init)); + +static const gchar *ui = +"" +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +""; + +static const gchar *ui_reader = +"" +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +""; + +static GtkActionEntry entries[] = { + + { "format-as-menu", + NULL, + N_("_Format as..."), + NULL, + NULL, + NULL + }, + + { "format-as-other-menu", + NULL, + N_("_Other languages"), + NULL, + NULL, + NULL + } +}; + +static void +reformat (GtkAction *old, + GtkAction *action, + gpointer user_data) +{ + EMailDisplayPopupTextHighlight *th_extension; + WebKitDOMDocument *doc; + WebKitDOMDOMWindow *window; + WebKitDOMElement *frame_element; + SoupURI *soup_uri; + GHashTable *query; + gchar *uri; + + + th_extension = E_MAIL_DISPLAY_POPUP_TEXT_HIGHLIGHT (user_data); + doc = th_extension->document; + if (!doc) + return; + + uri = webkit_dom_document_get_document_uri (doc); + soup_uri = soup_uri_new (uri); + g_free (uri); + + if (!soup_uri) + return; + + if (!soup_uri->query) { + soup_uri_free (soup_uri); + return; + } + + query = soup_form_decode (soup_uri->query); + g_hash_table_replace ( + query, g_strdup ("__formatas"), (gpointer) gtk_action_get_name (action)); + + soup_uri_set_query_from_form (soup_uri, query); + g_hash_table_destroy (query); + + uri = soup_uri_to_string (soup_uri, FALSE); + soup_uri_free (soup_uri); + + /* Get frame's window and from the window the actual " + "", + e_color_to_value ((GdkColor *) + e_mail_formatter_get_color ( + formatter, E_MAIL_FORMATTER_COLOR_FRAME)), + e_color_to_value ((GdkColor *) + e_mail_formatter_get_color ( + formatter, E_MAIL_FORMATTER_COLOR_CONTENT)), + part->id, uri); + + camel_stream_write_string (stream, str, cancellable, NULL); + + g_free (str); + g_free (uri); + + } + + return TRUE; +} + +static const gchar * +emfe_text_highlight_get_display_name (EMailFormatterExtension *extension) +{ + return _("Text Highlight"); +} + +static const gchar * +emfe_text_highlight_get_description (EMailFormatterExtension *extension) +{ + return _("Syntax highlighting of mail parts"); +} + +static const gchar ** +emfe_text_highlight_mime_types (EMailExtension *extension) +{ + return get_mime_types (); +} + +static void +emfe_text_highlight_constructed (GObject *object) +{ + EExtensible *extensible; + EMailExtensionRegistry *reg; + + extensible = e_extension_get_extensible (E_EXTENSION (object)); + reg = E_MAIL_EXTENSION_REGISTRY (extensible); + + e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object)); +} + +static void +e_mail_formatter_text_highlight_init (EMailFormatterTextHighlight *object) +{ +} + +static void +e_mail_formatter_text_highlight_class_init (EMailFormatterTextHighlightClass *class) +{ + GObjectClass *object_class; + EExtensionClass *extension_class; + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = emfe_text_highlight_constructed; + + extension_class = E_EXTENSION_CLASS (class); + extension_class->extensible_type = E_TYPE_MAIL_FORMATTER_EXTENSION_REGISTRY; +} + +static void +e_mail_formatter_text_highlight_class_finalize (EMailFormatterTextHighlightClass *class) +{ +} + +void +e_mail_formatter_text_highlight_type_register (GTypeModule *type_module) +{ + e_mail_formatter_text_highlight_register_type (type_module); +} + +static void +e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface) +{ + iface->format = emfe_text_highlight_format; + iface->get_display_name = emfe_text_highlight_get_display_name; + iface->get_description = emfe_text_highlight_get_description; +} + +static void +e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface) +{ + iface->mime_types = emfe_text_highlight_mime_types; +} diff --git a/modules/text-highlight/e-mail-formatter-text-highlight.h b/modules/text-highlight/e-mail-formatter-text-highlight.h new file mode 100644 index 0000000000..af10da4c84 --- /dev/null +++ b/modules/text-highlight/e-mail-formatter-text-highlight.h @@ -0,0 +1,30 @@ +/* + * text-highlight.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#ifndef TEXT_HIGHLIGHT_H +#define TEXT_HIGHLIGHT_H + +#include + +G_BEGIN_DECLS + +void e_mail_formatter_text_highlight_type_register (GTypeModule *type_module); + +G_END_DECLS + +#endif /* TEXT_HIGHLIGHT_H */ diff --git a/modules/text-highlight/e-mail-parser-text-highlight.c b/modules/text-highlight/e-mail-parser-text-highlight.c new file mode 100644 index 0000000000..328e590f6d --- /dev/null +++ b/modules/text-highlight/e-mail-parser-text-highlight.c @@ -0,0 +1,159 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "e-mail-parser-text-highlight.h" +#include "languages.h" + +#include +#include +#include +#include + +#include + +#define d(x) + +typedef struct _EMailParserTextHighlight { + EExtension parent; +} EMailParserTextHighlight; + +typedef struct _EMailParserTextHighlightClass { + EExtensionClass parent_class; +} EMailParserTextHighlightClass; + +GType e_mail_parser_text_highlight_get_type (void); +static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface); +static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED ( + EMailParserTextHighlight, + e_mail_parser_text_highlight, + E_TYPE_EXTENSION, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC ( + E_TYPE_MAIL_EXTENSION, + e_mail_parser_mail_extension_interface_init) + G_IMPLEMENT_INTERFACE_DYNAMIC ( + E_TYPE_MAIL_PARSER_EXTENSION, + e_mail_parser_parser_extension_interface_init)); + +static GSList * +empe_text_highlight_parse (EMailParserExtension *extension, + EMailParser *parser, + CamelMimePart *part, + GString *part_id, + GCancellable *cancellable) +{ + GSList *parts; + gint len; + CamelContentType *ct; + + /* Prevent recursion */ + if (strstr (part_id->str, ".text-highlight") != NULL) { + return NULL; + } + + /* Don't parse text/html if it's not an attachment */ + ct = camel_mime_part_get_content_type (part); + if (camel_content_type_is (ct, "text", "html")) { + const CamelContentDisposition *disp; + + disp = camel_mime_part_get_content_disposition (part); + if (!disp || (g_strcmp0 (disp->disposition, "attachment") != 0)) { + return NULL; + } + } + + len = part_id->len; + g_string_append (part_id, ".text-highlight"); + + /* All source codes and scripts are in general plain texts, + * so let text/plain parser handle it. */ + parts = e_mail_parser_parse_part_as ( + parser, part, part_id, "text/plain", cancellable); + + g_string_truncate (part_id, len); + + return parts; +} + +static const gchar ** +empe_mime_types (EMailExtension *extension) +{ + return get_mime_types (); +} + +void +e_mail_parser_text_highlight_type_register (GTypeModule *type_module) +{ + e_mail_parser_text_highlight_register_type (type_module); +} + +static void +e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface) +{ + iface->mime_types = empe_mime_types; +} + +static void +e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface) +{ + iface->parse = empe_text_highlight_parse; +} + +static void +e_mail_parser_text_highlight_constructed (GObject *object) +{ + EExtensible *extensible; + EMailExtensionRegistry *reg; + + extensible = e_extension_get_extensible (E_EXTENSION (object)); + reg = E_MAIL_EXTENSION_REGISTRY (extensible); + + e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object)); +} + +static void +e_mail_parser_text_highlight_class_init (EMailParserTextHighlightClass *class) +{ + GObjectClass *object_class; + EExtensionClass *extension_class; + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = e_mail_parser_text_highlight_constructed; + + extension_class = E_EXTENSION_CLASS (class); + extension_class->extensible_type = E_TYPE_MAIL_PARSER_EXTENSION_REGISTRY; +} + +void +e_mail_parser_text_highlight_class_finalize (EMailParserTextHighlightClass *class) +{ +} + +static void +e_mail_parser_text_highlight_init (EMailParserTextHighlight *parser) +{ + +} diff --git a/modules/text-highlight/e-mail-parser-text-highlight.h b/modules/text-highlight/e-mail-parser-text-highlight.h new file mode 100644 index 0000000000..cc55a777ac --- /dev/null +++ b/modules/text-highlight/e-mail-parser-text-highlight.h @@ -0,0 +1,30 @@ +/* + * e-mail-parser-text-highlight.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#ifndef E_MAIL_PARSER_TEXT_HIGHLIGHT_H +#define E_MAIL_PARSER_TEXT_HIGHLIGHT_H + +#include + +G_BEGIN_DECLS + +void e_mail_parser_text_highlight_type_register (GTypeModule *type_module); + +G_END_DECLS + +#endif /* E_MAIL_PARSER_TEXT_HIGHLIGHT_H */ diff --git a/modules/text-highlight/evolution-module-text-highlight.c b/modules/text-highlight/evolution-module-text-highlight.c index de6e469bde..78c3c4dcf5 100644 --- a/modules/text-highlight/evolution-module-text-highlight.c +++ b/modules/text-highlight/evolution-module-text-highlight.c @@ -16,7 +16,9 @@ * */ -#include "text-highlight.h" +#include "e-mail-parser-text-highlight.h" +#include "e-mail-formatter-text-highlight.h" +#include "e-mail-display-popup-text-highlight.h" #include @@ -28,8 +30,9 @@ G_MODULE_EXPORT void e_module_load (GTypeModule *type_module) { /* Register dynamically loaded types. */ - + e_mail_parser_text_highlight_type_register (type_module); e_mail_formatter_text_highlight_type_register (type_module); + e_mail_display_popup_text_highlight_type_register (type_module); } G_MODULE_EXPORT void diff --git a/modules/text-highlight/languages.c b/modules/text-highlight/languages.c new file mode 100644 index 0000000000..957b0aded9 --- /dev/null +++ b/modules/text-highlight/languages.c @@ -0,0 +1,529 @@ +/* + * languages.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "languages.h" + +#include + +static const gchar **mime_types = NULL; +G_LOCK_DEFINE_STATIC (mime_types); + +static Language languages[] = { + + { "txt", N_("_Plain text"), + (const gchar* []) { (gchar[]) { "text" }, NULL }, + (const gchar* []) { (gchar[]) { "text/plain" }, + (gchar[]) { "text/*" }, NULL } + }, + + { "assembler", N_("_Assembler"), + (const gchar* []) { (gchar[]) { "asm" } , NULL }, + (const gchar* []) { (gchar[]) { "text/x-asm" }, NULL } + }, + + { "sh", N_("_Bash"), + (const gchar* []) { (gchar[]) { "bash" }, (gchar[]) { "sh" }, + (gchar[]) { "ebuild" }, (gchar[]) {"eclass" }, + NULL }, + (const gchar* []) { (gchar[]) { "application/x-bsh" }, + (gchar[]) { "application/x-sh" }, + (gchar[]) { "application/x-shar" }, + (gchar[]) { "application/x-shellscript" }, + (gchar[]) { "text/x-script.sh" }, NULL } + }, + + { "c", N_("_C/C++"), + (const gchar* []) { (gchar[]) { "c" }, (gchar[]) { "c++" }, + (gchar[]) { "cc" }, (gchar[]) { "cpp" }, + (gchar[]) { "cu" }, (gchar[]) { "cxx" }, + (gchar[]) { "h" }, (gchar[]) { "hh" }, + (gchar[]) { "hpp" }, (gchar[]) { "hxx" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-c" }, NULL } + }, + + { "csharp", N_("_C#"), + (const gchar* []) { (gchar[]) { "cs" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-csharp" }, NULL } + }, + + { "css", N_("_Cascade Style Sheet"), + (const gchar* []) { (gchar[]) { "css" }, NULL }, + (const gchar* []) { (gchar[]) { "text/css" }, NULL } + }, + + { "html", N_("_HTML"), + (const gchar* []) { (gchar[]) { "html" }, (gchar[]) { "html" }, + (gchar[]) { "xhtml" }, (gchar[]) { "dhtml" }, NULL }, + (const gchar* []) { NULL } /* Don't register text-highlight as formatter + or parser of text/html as it would break + all text/html emails. */ + }, + + { "java", N_("_Java"), + (const gchar* []) { (gchar[]) { "java" }, (gchar[]) { "groovy" }, + (gchar[]) { "grv" }, NULL }, + (const gchar* []) { (gchar[]) { "text/java-source" }, NULL } + }, + + { "js", N_("_JavaScript"), + (const gchar* []) { (gchar[]) { "js" }, NULL }, + (const gchar* []) { (gchar[]) { "text/javascript" }, + (gchar[]) { "application/x-javascript" }, NULL } + }, + + { "diff", N_("_Patch/diff"), + (const gchar* []) { (gchar[]) { "diff" }, (gchar[]) { "patch" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-diff" }, + (gchar[]) { "text/x-patch" }, NULL } + }, + + { "perl", N_("_Perl"), + (const gchar* []) { (gchar[]) { "perl" }, (gchar[]) { "cgi"}, + (gchar[]) { "perl" }, (gchar[]) { "pl" }, + (gchar[]) { "plex" }, (gchar[]) { "plx" }, + (gchar[]) { "pm" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-script.perl" }, + (gchar[]) { "text/x-script.perl-module" }, + (gchar[]) { "application/x-pixclscript" }, + (gchar[]) { "application/x-xpixmap" }, NULL } + }, + + { "php", N_("_PHP"), + (const gchar* []) { (gchar[]) { "php" }, (gchar[]) { "php3" }, + (gchar[]) { "php4" }, (gchar[]) { "php5" }, + (gchar[]) { "php6" }, NULL }, + (const gchar* []) { (gchar[]) { "text/php" }, + (gchar[]) { "text/x-php" }, + (gchar[]) { "application/php" }, + (gchar[]) { "application/x-php" }, + (gchar[]) { "application/x-httpd-php" }, + (gchar[]) { "application/x-httpd-php-source" }, + NULL } + }, + + { "python", N_("_Python"), + (const gchar* []) { (gchar[]) { "py" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-script.python" }, NULL } + }, + + { "ruby", N_("_Ruby"), + (const gchar* []) { (gchar[]) { "ruby" }, (gchar[]) { "pp" }, + (gchar[]) { "rb" }, (gchar[]) { "rjs" }, + (gchar[]) { "ruby" }, NULL }, + (const gchar* []) { (gchar[]) { "application/x-ruby" }, NULL } + }, + + { "tcl", N_("_Tcl/Tk"), + (const gchar* []) { (gchar[]) { "tcl" }, (gchar[]) { "ictl" }, + (gchar[]) { "wish" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-tcl" }, NULL } + }, + + { "tex", N_("_TeX/LaTeX"), + (const gchar* []) { (gchar[]) { "tex" }, (gchar[]) { "csl" }, + (gchar[]) { "sty" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-tex" }, NULL } + }, + + { "vala", N_("_Vala"), + (const gchar* []) { (gchar[]) { "vala" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-vala" }, NULL } + }, + + { "vb", N_("_Visual Basic"), + (const gchar* []) { (gchar[]) { "vb" }, (gchar[]) { "bas" }, + (gchar[]) { "basic" }, (gchar[]) { "bi" }, + (gchar[]) { "vbs" }, NULL }, + (const gchar* []) { NULL } + }, + + { "xml", N_("_XML"), + (const gchar* []) { (gchar[]) { "xml" }, (gchar[]) { "dtd" }, + (gchar[]) { "ecf" }, (gchar[]) { "ent" }, + (gchar[]) { "hdr" }, (gchar[]) { "hub" }, + (gchar[]) { "jnlp" }, (gchar[]) { "nrm" }, + (gchar[]) { "resx" }, (gchar[]) { "sgm" }, + (gchar[]) { "sgml" }, (gchar[]) { "svg" }, + (gchar[]) { "tld" }, (gchar[]) { "vxml" }, + (gchar[]) { "wml" }, (gchar[]) { "xsd" }, + (gchar[]) { "xsl" }, NULL }, + (const gchar* []) { (gchar[]) { "text/xml" }, + (gchar[]) { "application/xml" }, + (gchar[]) { "application/x-xml" }, NULL } + } +}; + +static struct Language other_languages[] = { + + { "actionscript", N_("_ActionScript"), + (const gchar* []) { (gchar[]) { "as" }, NULL }, + (const gchar* []) { NULL } + }, + + { "ada", N_("_ADA95"), + (const gchar* []) { (gchar[]) { "a" }, (gchar[]) { "adb" }, + (gchar[]) { "ads" }, (gchar[]) { "gnad" }, + NULL }, + (const gchar* []) { (gchar[]) { "text/x-adasrc" }, NULL } + }, + + { "algol", N_("_ALGOL 68"), + (const gchar* []) { (gchar[]) { "alg" }, NULL }, + (const gchar* []) { NULL } + }, + + { "awk", N_("(_G)AWK"), + (const gchar* []) { (gchar[]) { "awk" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-awk" }, NULL } + }, + + { "cobol", N_("_COBOL"), + (const gchar* []) { (gchar[]) { "cbl" }, (gchar[]) { "cob" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-cobol" }, NULL } + }, + + { "bat", N_("_DOS Batch"), + (const gchar* []) { (gchar[]) { "bat" }, (gchar[]) { "cmd" }, NULL }, + (const gchar* []) { NULL } + }, + + { "d", N_("_D"), + (const gchar* []) { (gchar[]) { "d" }, NULL }, + (const gchar* []) { NULL } + }, + + { "erlang", N_("_Erlang"), + (const gchar* []) { (gchar[]) { "erl" }, (gchar[]) { "hrl" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-erlang" }, NULL } + }, + + { "fortran77", N_("_FORTRAN 77"), + (const gchar* []) { (gchar[]) { "f" }, (gchar[]) { "for" }, + (gchar[]) { "ftn" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-fortran" }, NULL } + }, + + { "fortran90", N_("_FORTRAN 90"), + (const gchar* []) { (gchar[]) { "f90" }, (gchar[]) { "f95" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-fortran" }, NULL } + }, + + { "fsharp", N_("_F#"), + (const gchar* []) { (gchar[]) { "fs" }, (gchar[]) { "fsx" }, NULL }, + (const gchar* []) { NULL } + }, + + { "go", N_("_Go"), + (const gchar* []) { (gchar[]) { "go" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-go" }, NULL } + }, + + { "haskell", N_("_Haskell"), + (const gchar* []) { (gchar[]) { "hs" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-haskell" }, NULL } + }, + + { "jsp", N_("_JSP"), + (const gchar* []) { (gchar[]) { "jsp" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-jsp" }, NULL } + }, + + { "lisp", N_("_Lisp"), + (const gchar* []) { (gchar[]) { "cl" }, (gchar[]) { "clisp" }, + (gchar[]) { "el" }, (gchar[]) { "lsp" }, + (gchar[]) { "sbcl"}, (gchar[]) { "scom" }, + NULL }, + (const gchar* []) { (gchar[]) { "text/x-emacs-lisp" }, NULL } + }, + + { "lotus", N_("_Lotus"), + (const gchar* []) { (gchar[]) { "ls" }, NULL }, + (const gchar* []) { (gchar[]) { "application/vnd.lotus-1-2-3" }, NULL } + }, + + { "lua", N_("_Lua"), + (const gchar* []) { (gchar[]) { "lua" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-lua" }, NULL } + }, + + { "maple", N_("_Maple"), + (const gchar* []) { (gchar[]) { "mpl" }, NULL }, + (const gchar* []) { NULL } + }, + + { "matlab", N_("_Matlab"), + (const gchar* []) { (gchar[]) { "m" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-matlab" }, NULL } + }, + + { "maya", N_("_Maya"), + (const gchar* []) { (gchar[]) { "mel" }, NULL }, + (const gchar* []) { NULL } + }, + + { "oberon", N_("_Oberon"), + (const gchar* []) { (gchar[]) { "ooc" }, NULL }, + (const gchar* []) { NULL } + }, + + { "objc", N_("_Objective C"), + (const gchar* []) { (gchar[]) { "objc" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-objchdr" }, + (gchar[]) { "text/x-objcsrc" }, NULL } + }, + + { "ocaml", N_("_OCaml"), + (const gchar* []) { (gchar[]) { "ml" }, (gchar[]) { "mli" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-ocaml" }, NULL } + }, + + { "octave", N_("_Octave"), + (const gchar* []) { (gchar[]) { "octave" }, NULL }, + (const gchar* []) { NULL } + }, + + { "os", N_("_Object Script"), + (const gchar* []) { (gchar[]) { "os" }, NULL }, + (const gchar* []) { NULL } + }, + + { "pascal", N_("_Pascal"), + (const gchar* []) { (gchar[]) { "pas" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-pascal" }, NULL } + }, + + { "pov", N_("_POV-Ray"), + (const gchar* []) { (gchar[]) { "pov" }, NULL }, + (const gchar* []) { NULL } + }, + + { "pro", N_("_Prolog"), + (const gchar* []) { (gchar[]) { "pro" }, NULL }, + (const gchar* []) { NULL } + }, + + { "ps", N_("_PostScript"), + (const gchar* []) { (gchar[]) { "ps" } , NULL }, + (const gchar* []) { (gchar[]) { "application/postscript" }, NULL } + }, + + { "r", N_("_R"), + (const gchar* []) { (gchar[]) { "r" }, NULL }, + (const gchar* []) { NULL } + }, + + { "spec", N_("_RPM Spec"), + (const gchar* []) { (gchar[]) { "spec" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-rpm-spec" }, NULL } + }, + + { "scala", N_("_Scala"), + (const gchar* []) { (gchar[]) { "scala" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-scala" }, NULL } + }, + + { "smalltalk", N_("_Smalltalk"), + (const gchar* []) { (gchar[]) { "gst" }, (gchar[]) { "sq" }, + (gchar[]) { "st" }, NULL }, + (const gchar* []) { NULL } + }, + + { "tcsh", N_("_TCSH"), + (const gchar* []) { (gchar[]) { "tcsh" }, NULL }, + (const gchar* []) { NULL } + }, + + { "vhd", N_("_VHDL"), + (const gchar* []) { (gchar[]) { "vhd" }, NULL }, + (const gchar* []) { (gchar[]) { "text/x-vhdl" }, NULL } + } +}; + +Language * +get_default_langauges (gsize *len) +{ + if (len) { + *len = G_N_ELEMENTS (languages); + } + + return languages; +} + +Language * +get_additinal_languages (gsize *len) +{ + if (len) { + *len = G_N_ELEMENTS (other_languages); + } + + return other_languages; +} + +const gchar * +get_syntax_for_ext(const gchar *extension) +{ + gint i; + gint j; + + for (i = 0; i < G_N_ELEMENTS (languages); i++) { + + Language *lang = &languages[i]; + const gchar *ext; + + j = 0; + ext = lang->extensions[j]; + while (ext) { + if (g_ascii_strncasecmp (ext, extension, strlen (ext)) == 0) { + return lang->action_name; + } + + j++; + ext = lang->extensions[j]; + } + } + + for (i = 0; i < G_N_ELEMENTS (other_languages); i++) { + + Language *lang = &other_languages[i]; + const gchar *ext; + + j = 0; + ext = lang->extensions[j]; + while (ext) { + if (g_ascii_strncasecmp (ext, extension, strlen (ext)) == 0) { + return lang->action_name; + } + + j++; + ext = lang->extensions[j]; + } + } + + return NULL; +} + +const gchar * +get_syntax_for_mime_type(const gchar *mime_type) +{ + gint i; + gint j; + + for (i = 0; i < G_N_ELEMENTS (languages); i++) { + + Language *lang = &languages[i]; + const gchar *mt; + + j = 0; + mt = lang->mime_types[j]; + while (mt) { + if (g_ascii_strncasecmp (mt, mime_type, strlen (mt)) == 0) { + return lang->action_name; + } + + j++; + mt = lang->mime_types[j]; + } + } + + for (i = 0; i < G_N_ELEMENTS (other_languages); i++) { + + Language *lang = &other_languages[i]; + const gchar *mt; + + j = 0; + mt = lang->mime_types[j]; + while (mt) { + if (g_ascii_strncasecmp (mt, mime_type, strlen (mt)) == 0) { + return lang->action_name; + } + + j++; + mt = lang->mime_types[j]; + } + } + + return NULL; +} + + +const gchar ** +get_mime_types (void) +{ + G_LOCK (mime_types); + if (mime_types == NULL) { + gchar **list; + gsize array_len; + gint i, pos; + + array_len = G_N_ELEMENTS (languages); + pos = 0; + + list = g_malloc (array_len * sizeof (gchar *)); + + for (i = 0; i < G_N_ELEMENTS (languages); i++) { + Language *lang = &languages[i]; + + gint j = 0; + while (lang->mime_types[j] != NULL) { + if (pos == array_len) { + array_len += 10; + list = g_realloc (list, array_len * sizeof (gchar *)); + } + + list[pos] = (gchar *) lang->mime_types[j]; + pos++; + j++; + } + } + + for (i = 0; i < G_N_ELEMENTS (other_languages); i++) { + Language *lang = &other_languages[i]; + + gint j = 0; + while (lang->mime_types[j] != NULL) { + if (pos == array_len) { + array_len += 10; + list = g_realloc (list, array_len * sizeof (gchar *)); + } + + list[pos] = (gchar *) lang->mime_types[j]; + pos++; + j++; + } + } + + if (pos == array_len) { + array_len += 1; + list = g_realloc (list, array_len * sizeof (gchar *)); + } + + /* Ensure the array is null-terminated */ + for (i = pos; i < array_len; i++) { + list[i] = NULL; + } + + mime_types = (const gchar **) list; + } + G_UNLOCK (mime_types); + + return mime_types; +} diff --git a/modules/text-highlight/languages.h b/modules/text-highlight/languages.h new file mode 100644 index 0000000000..03f1442531 --- /dev/null +++ b/modules/text-highlight/languages.h @@ -0,0 +1,39 @@ +/* + * languages.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#ifndef LANGUAGES_H +#define LANGUAGES_H + +#include + +typedef struct Language { + const gchar *action_name; + const gchar *action_label; + const gchar **extensions; + const gchar **mime_types; +} Language; + +const gchar * get_syntax_for_ext (const gchar *extension); +const gchar * get_syntax_for_mime_type (const gchar *mime_type); + +Language * get_default_langauges (gsize *len); +Language * get_additinal_languages (gsize *len); + +const gchar ** get_mime_types (void); + +#endif /* LANGUAGES_H */ diff --git a/modules/text-highlight/text-highlight.c b/modules/text-highlight/text-highlight.c deleted file mode 100644 index 26f7708f76..0000000000 --- a/modules/text-highlight/text-highlight.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * text-highlight.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "text-highlight.h" - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -typedef struct _EMailFormatterTextHighlight EMailFormatterTextHighlight; -typedef struct _EMailFormatterTextHighlightClass EMailFormatterTextHighlightClass; - -struct _EMailFormatterTextHighlight { - EExtension parent; -}; - -struct _EMailFormatterTextHighlightClass { - EExtensionClass parent_class; -}; - -GType e_mail_formatter_text_highlight_get_type (void); -static void e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface); -static void e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface); - -G_DEFINE_DYNAMIC_TYPE_EXTENDED ( - EMailFormatterTextHighlight, - e_mail_formatter_text_highlight, - E_TYPE_EXTENSION, - 0, - G_IMPLEMENT_INTERFACE_DYNAMIC ( - E_TYPE_MAIL_EXTENSION, - e_mail_formatter_mail_extension_interface_init) - G_IMPLEMENT_INTERFACE_DYNAMIC ( - E_TYPE_MAIL_FORMATTER_EXTENSION, - e_mail_formatter_formatter_extension_interface_init)); - -static const gchar *formatter_mime_types[] = { "text/x-diff", - "text/x-patch", - NULL }; - -static gchar * get_default_font (void) -{ - gchar *font; - GSettings *settings; - - settings = g_settings_new ("org.gnome.desktop.interface"); - - font = g_settings_get_string (settings, "monospace-font-name"); - - return font ? font : g_strdup ("monospace 10"); -} - -static gboolean -emfe_text_highlight_format (EMailFormatterExtension *extension, - EMailFormatter *formatter, - EMailFormatterContext *context, - EMailPart *part, - CamelStream *stream, - GCancellable *cancellable) -{ - if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) { - - CamelDataWrapper *dw; - CamelStream *filter_stream; - CamelMimeFilter *mime_filter; - - dw = camel_medium_get_content (CAMEL_MEDIUM (part->part)); - if (!dw) { - return FALSE; - } - - camel_stream_write_string ( - stream, "
", cancellable, NULL); - - filter_stream = camel_stream_filter_new (stream); - mime_filter = camel_mime_filter_tohtml_new ( - CAMEL_MIME_FILTER_TOHTML_PRE | - CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES, - 0x7a7a7a); - camel_stream_filter_add ( - CAMEL_STREAM_FILTER (filter_stream), mime_filter); - g_object_unref (mime_filter); - - e_mail_formatter_format_text ( - formatter, part, filter_stream, cancellable); - - camel_stream_flush (filter_stream, cancellable, NULL); - g_object_unref (filter_stream); - - camel_stream_write_string ( - stream, "
", cancellable, NULL); - - return TRUE; - - } else if (context->mode == E_MAIL_FORMATTER_MODE_RAW) { - gint stdin, stdout; - GPid pid; - CamelStream *read, *write; - CamelDataWrapper *dw; - gchar *font_family, *font_size; - gboolean use_custom_font; - GSettings *settings; - PangoFontDescription *fd; - const gchar *argv[] = { "highlight", - NULL, /* don't move these! */ - NULL, - "--out-format=html", - "--include-style", - "--inline-css", - "--style=bclear", - "--syntax=diff", - "--failsafe", - NULL }; - - dw = camel_medium_get_content (CAMEL_MEDIUM (part->part)); - if (!dw) { - return FALSE; - } - - fd = NULL; - settings = g_settings_new ("org.gnome.evolution.mail"); - use_custom_font = g_settings_get_boolean (settings, "use-custom-font"); - if (!use_custom_font) { - gchar *font; - - font = get_default_font (); - fd = pango_font_description_from_string (font); - g_free (font); - - g_object_unref (settings); - - } else { - gchar *font; - - font = g_settings_get_string (settings, "monospace-font"); - if (!font) - font = get_default_font (); - - fd = pango_font_description_from_string (font); - - g_free (font); - } - - font_family = g_strdup_printf ("--font='%s'", - pango_font_description_get_family (fd)); - font_size = g_strdup_printf ("--font-size=%d", - pango_font_description_get_size (fd) / PANGO_SCALE); - - argv[1] = font_family; - argv[2] = font_size; - - if (!g_spawn_async_with_pipes ( - NULL, (gchar **) argv, NULL, - G_SPAWN_SEARCH_PATH | - G_SPAWN_DO_NOT_REAP_CHILD, - NULL, NULL, &pid, &stdin, &stdout, NULL, NULL)) { - return FALSE; - } - - write = camel_stream_fs_new_with_fd (stdin); - read = camel_stream_fs_new_with_fd (stdout); - - camel_data_wrapper_decode_to_stream_sync ( - dw, write, cancellable, NULL); - g_object_unref (write); - - g_spawn_close_pid (pid); - - g_seekable_seek (G_SEEKABLE (read), 0, G_SEEK_SET, cancellable, NULL); - camel_stream_write_to_stream (read, stream, cancellable, NULL); - camel_stream_flush (read, cancellable, NULL); - g_object_unref (read); - - g_free (font_family); - g_free (font_size); - pango_font_description_free (fd); - - } else { - gchar *uri, *str; - - uri = e_mail_part_build_uri ( - context->folder, context->message_uid, - "part_id", G_TYPE_STRING, part->id, - "mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW, - NULL); - - str = g_strdup_printf ( - "
" - "
\n" - "" - "
", - e_color_to_value ((GdkColor *) - e_mail_formatter_get_color ( - formatter, E_MAIL_FORMATTER_COLOR_FRAME)), - e_color_to_value ((GdkColor *) - e_mail_formatter_get_color ( - formatter, E_MAIL_FORMATTER_COLOR_CONTENT)), - part->id, uri); - - camel_stream_write_string (stream, str, cancellable, NULL); - - g_free (str); - g_free (uri); - - } - - return TRUE; -} - -static const gchar * -emfe_text_highlight_get_display_name (EMailFormatterExtension *extension) -{ - return _("Patch"); -} - -static const gchar * -emfe_text_highlight_get_description (EMailFormatterExtension *extension) -{ - return _("Format part as a patch"); -} - -static const gchar ** -emfe_text_highlight_mime_types (EMailExtension *extension) -{ - return formatter_mime_types; -} - -static void -emfe_text_highlight_constructed (GObject *object) -{ - EExtensible *extensible; - EMailExtensionRegistry *reg; - - extensible = e_extension_get_extensible (E_EXTENSION (object)); - reg = E_MAIL_EXTENSION_REGISTRY (extensible); - - e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object)); -} - -static void -e_mail_formatter_text_highlight_init (EMailFormatterTextHighlight *object) -{ -} - -static void -e_mail_formatter_text_highlight_class_init (EMailFormatterTextHighlightClass *class) -{ - GObjectClass *object_class; - EExtensionClass *extension_class; - - object_class = G_OBJECT_CLASS (class); - object_class->constructed = emfe_text_highlight_constructed; - - extension_class = E_EXTENSION_CLASS (class); - extension_class->extensible_type = E_TYPE_MAIL_FORMATTER_EXTENSION_REGISTRY; -} - -static void -e_mail_formatter_text_highlight_class_finalize (EMailFormatterTextHighlightClass *class) -{ -} - -void -e_mail_formatter_text_highlight_type_register (GTypeModule *type_module) -{ - e_mail_formatter_text_highlight_register_type (type_module); -} - -static void -e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface) -{ - iface->format = emfe_text_highlight_format; - iface->get_display_name = emfe_text_highlight_get_display_name; - iface->get_description = emfe_text_highlight_get_description; -} - -static void -e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface) -{ - iface->mime_types = emfe_text_highlight_mime_types; -} diff --git a/modules/text-highlight/text-highlight.h b/modules/text-highlight/text-highlight.h deleted file mode 100644 index af10da4c84..0000000000 --- a/modules/text-highlight/text-highlight.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * text-highlight.h - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see - * - */ - -#ifndef TEXT_HIGHLIGHT_H -#define TEXT_HIGHLIGHT_H - -#include - -G_BEGIN_DECLS - -void e_mail_formatter_text_highlight_type_register (GTypeModule *type_module); - -G_END_DECLS - -#endif /* TEXT_HIGHLIGHT_H */ -- cgit v1.2.3