em-format: Format text/markdown with cmark library
Use the cmark library to format text/markdown into HTML and show it as such, instead of the raw markdown. The dependency on cmark is optional and can be turned off in the configure time. Related to https://gitlab.gnome.org/GNOME/evolution/-/issues/449
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "evolution-config.h"
|
||||
|
||||
#include <cmark.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include <e-util/e-util.h>
|
||||
|
||||
#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 <iframe> */
|
||||
string = "<style>body{ margin: 0; }</style>";
|
||||
|
||||
g_output_stream_write_all (
|
||||
stream, string, strlen (string),
|
||||
NULL, cancellable, NULL);
|
||||
}
|
||||
|
||||
string =
|
||||
"<div class=\"part-container "
|
||||
"-e-web-view-background-color -e-web-view-text-color\" "
|
||||
"style=\"border: none; padding: 8px; margin: 0;\">";
|
||||
|
||||
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 = "</div>\n";
|
||||
|
||||
g_output_stream_write_all (
|
||||
stream, string, strlen (string),
|
||||
NULL, cancellable, NULL);
|
||||
|
||||
if (context->mode == E_MAIL_FORMATTER_MODE_RAW) {
|
||||
string = "</body></html>";
|
||||
|
||||
g_output_stream_write_all (
|
||||
stream, string, strlen (string),
|
||||
NULL, cancellable, NULL);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
CamelFolder *folder;
|
||||
const gchar *message_uid;
|
||||
gchar *uri, *str;
|
||||
const gchar *default_charset, *charset;
|
||||
|
||||
folder = e_mail_part_list_get_folder (context->part_list);
|
||||
message_uid = e_mail_part_list_get_message_uid (context->part_list);
|
||||
default_charset = e_mail_formatter_get_default_charset (formatter);
|
||||
charset = e_mail_formatter_get_charset (formatter);
|
||||
|
||||
if (!default_charset)
|
||||
default_charset = "";
|
||||
if (!charset)
|
||||
charset = "";
|
||||
|
||||
uri = e_mail_part_build_uri (
|
||||
folder, message_uid,
|
||||
"part_id", G_TYPE_STRING, e_mail_part_get_id (part),
|
||||
"mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW,
|
||||
"formatter_default_charset", G_TYPE_STRING, default_charset,
|
||||
"formatter_charset", G_TYPE_STRING, charset,
|
||||
NULL);
|
||||
|
||||
str = g_strdup_printf (
|
||||
"<div class=\"part-container-nostyle\" >"
|
||||
"<iframe width=\"100%%\" height=\"10\""
|
||||
" id=\"%s.iframe\" name=\"%s\" "
|
||||
" frameborder=\"0\" src=\"%s\" "
|
||||
" class=\"-e-mail-formatter-frame-color %s"
|
||||
" -e-web-view-text-color\" >"
|
||||
"</iframe>"
|
||||
"</div>",
|
||||
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)
|
||||
{
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "evolution-config.h"
|
||||
|
||||
#include "e-mail-formatter.h"
|
||||
|
||||
#include <string.h>
|
||||
@@ -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);
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#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)
|
||||
{
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user