diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a5eb1278b..f2c757d045 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -705,6 +705,19 @@ if(WITH_GLADE_CATALOG) pkg_check_modules_for_option(WITH_GLADE_CATALOG "Glade 3 catalog files" GLADEUI gladeui-2.0>=${gladeui_minimum_version}) endif(WITH_GLADE_CATALOG) +# ****************************** +# cmark for CommonMarkdown +# ****************************** + +add_printable_option(ENABLE_MARKDOWN "Enable markdown support" ON) + +if(ENABLE_MARKDOWN) + pkg_check_modules_for_option(ENABLE_MARKDOWN "markdown support" MARKDOWN + libcmark + ) + set(HAVE_MARKDOWN ON) +endif(ENABLE_MARKDOWN) + # Generate the ${PROJECT_NAME}-config.h file CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config.h) diff --git a/config.h.in b/config.h.in index f2732f51ea..d1d13dac48 100644 --- a/config.h.in +++ b/config.h.in @@ -119,3 +119,6 @@ /* D-Bus service name of the evolution-source-registry, as provided by evolution-data-server-1.2.pc */ #define EDS_SOURCES_DBUS_SERVICE_NAME "@EDS_SOURCES_DBUS_SERVICE_NAME@" + +/* Define if markdown support is enabled */ +#cmakedefine HAVE_MARKDOWN 1 diff --git a/po/POTFILES.in b/po/POTFILES.in index 1eb44ae079..741155c552 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -141,6 +141,7 @@ src/em-format/e-mail-formatter-secure-button.c src/em-format/e-mail-formatter-source.c src/em-format/e-mail-formatter-text-enriched.c src/em-format/e-mail-formatter-text-html.c +src/em-format/e-mail-formatter-text-markdown.c src/em-format/e-mail-formatter-text-plain.c src/em-format/e-mail-formatter-utils.c src/em-format/e-mail-parser-application-mbox.c diff --git a/src/em-format/CMakeLists.txt b/src/em-format/CMakeLists.txt index 6e32d239de..9b215d4052 100644 --- a/src/em-format/CMakeLists.txt +++ b/src/em-format/CMakeLists.txt @@ -78,6 +78,13 @@ if(ENABLE_SMIME) ) endif(ENABLE_SMIME) +if(ENABLE_MARKDOWN) + list(APPEND SOURCES + e-mail-formatter-text-markdown.c + e-mail-parser-text-markdown.c + ) +endif(ENABLE_MARKDOWN) + set(HEADERS e-mail-extension-registry.h e-mail-formatter-extension.h @@ -130,12 +137,14 @@ target_include_directories(evolution-mail-formatter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${EVOLUTION_DATA_SERVER_INCLUDE_DIRS} ${GNOME_PLATFORM_INCLUDE_DIRS} + ${MARKDOWN_INCLUDE_DIRS} ) target_link_libraries(evolution-mail-formatter ${DEPENDENCIES} ${EVOLUTION_DATA_SERVER_LDFLAGS} ${GNOME_PLATFORM_LDFLAGS} + ${MARKDOWN_LDFLAGS} ) install(TARGETS evolution-mail-formatter diff --git a/src/em-format/e-mail-formatter-text-markdown.c b/src/em-format/e-mail-formatter-text-markdown.c new file mode 100644 index 0000000000..015d41bc6a --- /dev/null +++ b/src/em-format/e-mail-formatter-text-markdown.c @@ -0,0 +1,186 @@ +/* + * 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. + * + * 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 General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * + */ + +#include "evolution-config.h" + +#include +#include + +#include + +#include "e-mail-formatter-extension.h" +#include "e-mail-inline-filter.h" +#include "e-mail-part-utils.h" + +typedef EMailFormatterExtension EMailFormatterTextMarkdown; +typedef EMailFormatterExtensionClass EMailFormatterTextMarkdownClass; + +GType e_mail_formatter_text_markdown_get_type (void); + +G_DEFINE_TYPE (EMailFormatterTextMarkdown, e_mail_formatter_text_markdown, E_TYPE_MAIL_FORMATTER_EXTENSION) + +static const gchar *formatter_mime_types[] = { + "text/markdown", + NULL +}; + +static gboolean +emfe_text_markdown_format (EMailFormatterExtension *extension, + EMailFormatter *formatter, + EMailFormatterContext *context, + EMailPart *part, + GOutputStream *stream, + GCancellable *cancellable) +{ + if (g_cancellable_is_cancelled (cancellable)) + return FALSE; + + if ((context->mode == E_MAIL_FORMATTER_MODE_RAW) || + (context->mode == E_MAIL_FORMATTER_MODE_PRINTING)) { + CamelMimePart *mime_part; + CamelDataWrapper *dw; + GOutputStream *output_stream; + gchar *html; + + mime_part = e_mail_part_ref_mime_part (part); + dw = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); + if (dw == NULL) { + g_object_unref (mime_part); + return FALSE; + } + + output_stream = g_memory_output_stream_new_resizable (); + + e_mail_formatter_format_text (formatter, part, output_stream, cancellable); + g_output_stream_flush (output_stream, cancellable, NULL); + + html = cmark_markdown_to_html ((const gchar *) g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (output_stream)), + g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (output_stream)), + CMARK_OPT_VALIDATE_UTF8); + g_object_unref (output_stream); + g_object_unref (mime_part); + + if (html) { + const gchar *string; + + if (context->mode == E_MAIL_FORMATTER_MODE_RAW) { + string = e_mail_formatter_get_sub_html_header (formatter); + + g_output_stream_write_all ( + stream, string, strlen (string), + NULL, cancellable, NULL); + + /* No need for body margins within " + "", + e_mail_part_get_id (part), + e_mail_part_get_id (part), + uri, + e_mail_part_get_frame_security_style (part)); + + g_output_stream_write_all ( + stream, str, strlen (str), + NULL, cancellable, NULL); + + g_free (str); + g_free (uri); + } + + return TRUE; +} + +static void +e_mail_formatter_text_markdown_class_init (EMailFormatterExtensionClass *class) +{ + class->display_name = _("Markdown Text"); + class->description = _("Format part as markdown text"); + class->mime_types = formatter_mime_types; + class->priority = G_PRIORITY_LOW; + class->format = emfe_text_markdown_format; +} + +static void +e_mail_formatter_text_markdown_init (EMailFormatterExtension *extension) +{ +} diff --git a/src/em-format/e-mail-formatter.c b/src/em-format/e-mail-formatter.c index 1933a690f1..53717f7371 100644 --- a/src/em-format/e-mail-formatter.c +++ b/src/em-format/e-mail-formatter.c @@ -15,6 +15,8 @@ * */ +#include "evolution-config.h" + #include "e-mail-formatter.h" #include @@ -72,6 +74,9 @@ GType e_mail_formatter_source_get_type (void); GType e_mail_formatter_text_enriched_get_type (void); GType e_mail_formatter_text_html_get_type (void); GType e_mail_formatter_text_plain_get_type (void); +#ifdef HAVE_MARKDOWN +GType e_mail_formatter_text_markdown_get_type (void); +#endif static gpointer e_mail_formatter_parent_class = 0; @@ -561,6 +566,9 @@ e_mail_formatter_base_init (EMailFormatterClass *class) g_type_ensure (e_mail_formatter_text_enriched_get_type ()); g_type_ensure (e_mail_formatter_text_html_get_type ()); g_type_ensure (e_mail_formatter_text_plain_get_type ()); +#ifdef HAVE_MARKDOWN + g_type_ensure (e_mail_formatter_text_markdown_get_type ()); +#endif class->extension_registry = g_object_new ( E_TYPE_MAIL_FORMATTER_EXTENSION_REGISTRY, NULL); diff --git a/src/em-format/e-mail-parser-text-markdown.c b/src/em-format/e-mail-parser-text-markdown.c new file mode 100644 index 0000000000..07b7c3a307 --- /dev/null +++ b/src/em-format/e-mail-parser-text-markdown.c @@ -0,0 +1,88 @@ +/* + * 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. + * + * 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 General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * + */ + +#include "evolution-config.h" + +#include "e-mail-parser-extension.h" +#include "e-mail-part-utils.h" + +typedef EMailParserExtension EMailParserTextMarkdown; +typedef EMailParserExtensionClass EMailParserTextMarkdownClass; + +GType e_mail_parser_text_markdown_get_type (void); + +G_DEFINE_TYPE (EMailParserTextMarkdown, e_mail_parser_text_markdown, E_TYPE_MAIL_PARSER_EXTENSION) + +static const gchar *parser_mime_types[] = { + "text/markdown", + NULL +}; + +static gboolean +empe_text_markdown_parse (EMailParserExtension *extension, + EMailParser *parser, + CamelMimePart *part, + GString *part_id, + GCancellable *cancellable, + GQueue *out_mail_parts) +{ + CamelContentType *type; + EMailPart *mail_part; + GQueue work_queue = G_QUEUE_INIT; + gint s_len = part_id->len; + gchar *mime_type; + gboolean is_attachment; + + if (!camel_medium_get_content ((CamelMedium *) part)) + return FALSE; + + is_attachment = e_mail_part_is_attachment (part); + + type = camel_mime_part_get_content_type (part); + if (!camel_content_type_is (type, "text", "markdown")) + return FALSE; + + g_string_append_printf (part_id, ".markdown_text.%d", 0); + + mail_part = e_mail_part_new (part, part_id->str); + + mime_type = camel_content_type_simple (type); + e_mail_part_set_mime_type (mail_part, mime_type); + g_free (mime_type); + + g_string_truncate (part_id, s_len); + + g_queue_push_tail (&work_queue, mail_part); + + if (is_attachment) + e_mail_parser_wrap_as_attachment (parser, part, part_id, &work_queue); + + e_queue_transfer (&work_queue, out_mail_parts); + + return TRUE; +} + +static void +e_mail_parser_text_markdown_class_init (EMailParserExtensionClass *class) +{ + class->mime_types = parser_mime_types; + class->priority = G_PRIORITY_LOW; + class->parse = empe_text_markdown_parse; +} + +static void +e_mail_parser_text_markdown_init (EMailParserExtension *extension) +{ +} diff --git a/src/em-format/e-mail-parser.c b/src/em-format/e-mail-parser.c index c0e6a4c8cc..ad7c1d56ce 100644 --- a/src/em-format/e-mail-parser.c +++ b/src/em-format/e-mail-parser.c @@ -76,6 +76,9 @@ GType e_mail_parser_text_plain_get_type (void); #ifdef ENABLE_SMIME GType e_mail_parser_application_smime_get_type (void); #endif +#ifdef HAVE_MARKDOWN +GType e_mail_parser_text_markdown_get_type (void); +#endif static gpointer parent_class; @@ -323,6 +326,9 @@ e_mail_parser_base_init (EMailParserClass *class) #ifdef ENABLE_SMIME g_type_ensure (e_mail_parser_application_smime_get_type ()); #endif +#ifdef HAVE_MARKDOWN + g_type_ensure (e_mail_parser_text_markdown_get_type ()); +#endif class->extension_registry = g_object_new ( E_TYPE_MAIL_PARSER_EXTENSION_REGISTRY, NULL);