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 */ + string = ""; + + g_output_stream_write_all ( + stream, string, strlen (string), + NULL, cancellable, NULL); + } + + string = + ""; + + g_output_stream_write_all ( + stream, string, strlen (string), + NULL, cancellable, NULL); + + g_output_stream_write_all (stream, html, strlen (html), NULL, cancellable, NULL); + g_free (html); + + string = "\n"; + + g_output_stream_write_all ( + stream, string, strlen (string), + NULL, cancellable, NULL); + + if (context->mode == E_MAIL_FORMATTER_MODE_RAW) { + string = "