"
"
\n",
e_color_to_value (&efh->priv->colors[
EM_FORMAT_HTML_COLOR_FRAME]),
e_color_to_value (&efh->priv->colors[
EM_FORMAT_HTML_COLOR_CONTENT]),
e_color_to_value (&efh->priv->colors[
EM_FORMAT_HTML_COLOR_TEXT]));
camel_stream_write_string (stream, buffer->str, cancellable, NULL);
g_string_free (buffer, TRUE);
em_format_format_text (
emf, (CamelStream *) filtered_stream,
(CamelDataWrapper *) puri->part, cancellable);
g_object_unref (filtered_stream);
camel_stream_write_string (stream, "
", cancellable, NULL);
}
static void
efh_write_text_plain (EMFormat *emf,
EMFormatPURI *puri,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
{
CamelDataWrapper *dw;
CamelStream *filtered_stream;
CamelMimeFilter *html_filter;
EMFormatHTML *efh = (EMFormatHTML *) emf;
gchar *content;
const gchar *format;
guint32 flags;
guint32 rgb;
if (g_cancellable_is_cancelled (cancellable))
return;
flags = efh->text_html_flags;
dw = camel_medium_get_content (CAMEL_MEDIUM (puri->part));
/* Check for RFC 2646 flowed text. */
if (camel_content_type_is(dw->mime_type, "text", "plain")
&& (format = camel_content_type_param(dw->mime_type, "format"))
&& !g_ascii_strcasecmp(format, "flowed"))
flags |= CAMEL_MIME_FILTER_TOHTML_FORMAT_FLOWED;
rgb = e_color_to_value (
&efh->priv->colors[EM_FORMAT_HTML_COLOR_CITATION]);
filtered_stream = camel_stream_filter_new (stream);
html_filter = camel_mime_filter_tohtml_new (flags, rgb);
camel_stream_filter_add (
CAMEL_STREAM_FILTER (filtered_stream), html_filter);
g_object_unref (html_filter);
content = g_strdup_printf (
""
"
\n",
e_color_to_value (&efh->priv->colors[
EM_FORMAT_HTML_COLOR_FRAME]),
e_color_to_value (&efh->priv->colors[
EM_FORMAT_HTML_COLOR_CONTENT]),
e_color_to_value (&efh->priv->colors[
EM_FORMAT_HTML_COLOR_TEXT]));
camel_stream_write_string (stream, content, cancellable, NULL);
em_format_format_text (emf, filtered_stream, (CamelDataWrapper *) puri->part, cancellable);
camel_stream_flush (filtered_stream, cancellable, NULL);
g_object_unref (filtered_stream);
g_free (content);
camel_stream_write_string (stream, "
\n", cancellable, NULL);
}
static gchar *
get_tag (const gchar *tag_name,
gchar *opening,
gchar *closing)
{
gchar *t;
gboolean has_end;
for (t = closing - 1; t != opening; t--) {
if (*t != ' ')
break;
}
/* Not a pair tag */
if (*t == '/')
return g_strndup (opening, closing - opening + 1);
for (t = closing; t && *t; t++) {
if (*t == '<')
break;
}
do {
if (*t == '/') {
has_end = TRUE;
break;
}
if (*t == '>') {
has_end = FALSE;
break;
}
t++;
} while (t && *t);
/* Broken HTML? */
if (!has_end)
return g_strndup (opening, closing - opening + 1);
do {
if ((*t != ' ') && (*t != '/'))
break;
t++;
} while (t && *t);
if (g_strncasecmp (t, tag_name, strlen (tag_name)) == 0) {
closing = strstr (t, ">");
return g_strndup (opening, closing - opening + strlen (tag_name));
}
/* Broken HTML? */
return g_strndup (opening, closing - opening + 1);
}
static void
efh_write_text_html (EMFormat *emf,
EMFormatPURI *puri,
CamelStream *stream,
EMFormatWriterInfo *info,
GCancellable *cancellable)
{
EMFormatHTML *efh = (EMFormatHTML *) emf;
if (g_cancellable_is_cancelled (cancellable))
return;
if (info->mode == EM_FORMAT_WRITE_MODE_RAW) {
em_format_format_text (emf, stream,
(CamelDataWrapper *) puri->part, cancellable);
} else if (info->mode == EM_FORMAT_WRITE_MODE_PRINTING) {
GString *string;
GByteArray *ba;
gchar *pos;
GList *tags, *iter;
gboolean valid;
gchar *tag;
const gchar *document_end;
gint length;
gint i;
CamelStream *decoded_stream;
decoded_stream = camel_stream_mem_new ();
em_format_format_text (emf, decoded_stream,
(CamelDataWrapper *) puri->part, cancellable);
g_seekable_seek (G_SEEKABLE (decoded_stream), 0, G_SEEK_SET, cancellable, NULL);
ba = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (decoded_stream));
string = g_string_new_len ((gchar *) ba->data, ba->len);
g_object_unref (decoded_stream);
tags = NULL;
pos = string->str;
valid = FALSE;
do {
gchar *closing;
gchar *opening;
pos = strstr (pos + 1, "<");
if (!pos)
break;
opening = pos;
closing = strstr (pos, ">");
/* Find where the actual tag name begins */
for (tag = pos + 1; tag && *tag; tag++) {
if (*tag != ' ')
break;
}
if (g_ascii_strncasecmp (tag, "style", 5) == 0) {
tags = g_list_append (
tags,
get_tag ("style", opening, closing));
} else if (g_ascii_strncasecmp (tag, "script", 6) == 0) {
tags = g_list_append (
tags,
get_tag ("script", opening, closing));
} else if (g_ascii_strncasecmp (tag, "link", 4) == 0) {
tags = g_list_append (
tags,
get_tag ("link", opening, closing));
} else if (g_ascii_strncasecmp (tag, "body", 4) == 0) {
valid = TRUE;
break;
}
} while (TRUE);
/* Something's wrong, let's write the entire HTML and hope
* that WebKit can handle it */
if (!valid) {
EMFormatWriterInfo i = *info;
i.mode = EM_FORMAT_WRITE_MODE_RAW;
efh_write_text_html (emf, puri, stream, &i, cancellable);
return;
}
/* include the "body" as well -----v */
g_string_erase (string, 0, tag - string->str + 4);
g_string_prepend (string, "next) {
g_string_prepend (string, iter->data);
}
g_list_free_full (tags, g_free);
/* that's reversed