aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-mime-filter-enriched.c
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2002-12-16 23:05:06 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2002-12-16 23:05:06 +0800
commitebc92ca5e2d2ba117d5712b6437c1f10d0a5fb2d (patch)
treee436f55cf164932a96b9653d2fc4e5c9667401b8 /camel/camel-mime-filter-enriched.c
parentb6a4a8bdb86886c8715f487f35069a5c90c72b9c (diff)
downloadgsoc2013-evolution-ebc92ca5e2d2ba117d5712b6437c1f10d0a5fb2d.tar
gsoc2013-evolution-ebc92ca5e2d2ba117d5712b6437c1f10d0a5fb2d.tar.gz
gsoc2013-evolution-ebc92ca5e2d2ba117d5712b6437c1f10d0a5fb2d.tar.bz2
gsoc2013-evolution-ebc92ca5e2d2ba117d5712b6437c1f10d0a5fb2d.tar.lz
gsoc2013-evolution-ebc92ca5e2d2ba117d5712b6437c1f10d0a5fb2d.tar.xz
gsoc2013-evolution-ebc92ca5e2d2ba117d5712b6437c1f10d0a5fb2d.tar.zst
gsoc2013-evolution-ebc92ca5e2d2ba117d5712b6437c1f10d0a5fb2d.zip
#include some headers we had forgotten to add previously, also added
2002-12-16 Jeffrey Stedfast <fejj@ximian.com> * camel.h: #include some headers we had forgotten to add previously, also added camel-mime-filter-enriched.h. * camel-mime-filter-enriched.[c,h]: New stream filter to convert text/enriched and text/richtext into HTML. svn path=/trunk/; revision=19124
Diffstat (limited to 'camel/camel-mime-filter-enriched.c')
-rw-r--r--camel/camel-mime-filter-enriched.c375
1 files changed, 375 insertions, 0 deletions
diff --git a/camel/camel-mime-filter-enriched.c b/camel/camel-mime-filter-enriched.c
new file mode 100644
index 0000000000..7f6918bd68
--- /dev/null
+++ b/camel/camel-mime-filter-enriched.c
@@ -0,0 +1,375 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2002 Ximian, Inc. (www.ximian.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "string-utils.h"
+
+#include "camel-mime-filter-enriched.h"
+
+static struct {
+ char *enriched;
+ char *html;
+} enriched_tags[] = {
+ { "bold", "<b>" },
+ { "/bold", "</b>" },
+ { "italic", "<i>" },
+ { "/italic", "</i>" },
+ { "fixed", "<tt>" },
+ { "/fixed", "</tt>" },
+ { "smaller", "<font size=-1>" },
+ { "/smaller", "</font>" },
+ { "bigger", "<font size=+1>" },
+ { "/bigger", "</font>" },
+ { "underline", "<u>" },
+ { "/underline", "</u>" },
+ { "center", "<p align=center>" },
+ { "/center", "</p>" },
+ { "flushleft", "<p align=left>" },
+ { "/flushleft", "</p>" },
+ { "flushright", "<p align=right>" },
+ { "/flushright", "</p>" },
+ { "excerpt", "<blockquote>" },
+ { "/excerpt", "</blockquote>" },
+ { "paragraph", "<p>" },
+ { "signature", "<address>" },
+ { "/signature", "</address>" },
+ { "comment", "<!-- " },
+ { "/comment", " -->" },
+ { "param", "<!-- " },
+ { "/param", " -->" },
+ { "np", "<hr>" }
+};
+
+#define NUM_ENRICHED_TAGS (sizeof (enriched_tags) / sizeof (enriched_tags[0]))
+
+static GHashTable *enriched_hash = NULL;
+
+
+static void camel_mime_filter_enriched_class_init (CamelMimeFilterEnrichedClass *klass);
+static void camel_mime_filter_enriched_init (CamelMimeFilterEnriched *filter);
+static void camel_mime_filter_enriched_finalize (CamelObject *obj);
+
+static void filter_filter (CamelMimeFilter *filter, char *in, size_t len, size_t prespace,
+ char **out, size_t *outlen, size_t *outprespace);
+static void filter_complete (CamelMimeFilter *filter, char *in, size_t len, size_t prespace,
+ char **out, size_t *outlen, size_t *outprespace);
+static void filter_reset (CamelMimeFilter *filter);
+
+
+static CamelMimeFilterClass *parent_class = NULL;
+
+
+CamelType
+camel_mime_filter_enriched_get_type (void)
+{
+ static CamelType type = CAMEL_INVALID_TYPE;
+
+ if (type == CAMEL_INVALID_TYPE) {
+ type = camel_type_register (camel_mime_filter_get_type (),
+ "CamelMimeFilterEnriched",
+ sizeof (CamelMimeFilterEnriched),
+ sizeof (CamelMimeFilterEnrichedClass),
+ (CamelObjectClassInitFunc) camel_mime_filter_enriched_class_init,
+ NULL,
+ (CamelObjectInitFunc) camel_mime_filter_enriched_init,
+ (CamelObjectFinalizeFunc) camel_mime_filter_enriched_finalize);
+ }
+
+ return type;
+}
+
+static void
+camel_mime_filter_enriched_class_init (CamelMimeFilterEnrichedClass *klass)
+{
+ CamelMimeFilterClass *filter_class = (CamelMimeFilterClass *) klass;
+ int i;
+
+ parent_class = CAMEL_MIME_FILTER_CLASS (camel_mime_filter_get_type ());
+
+ filter_class->reset = filter_reset;
+ filter_class->filter = filter_filter;
+ filter_class->complete = filter_complete;
+
+ if (!enriched_hash) {
+ enriched_hash = g_hash_table_new (g_strcase_hash, g_strcase_equal);
+ for (i = 0; i < NUM_ENRICHED_TAGS; i++)
+ g_hash_table_insert (enriched_hash, enriched_tags[i].enriched,
+ enriched_tags[i].html);
+ }
+}
+
+static void
+camel_mime_filter_enriched_finalize (CamelObject *obj)
+{
+ ;
+}
+
+static void
+camel_mime_filter_enriched_init (CamelMimeFilterEnriched *filter)
+{
+ filter->flags = 0;
+ filter->nofill = 0;
+}
+
+#define IS_RICHTEXT CAMEL_MIME_FILTER_ENRICHED_IS_RICHTEXT
+
+static void
+enriched_to_html (CamelMimeFilter *filter, char *in, size_t inlen, size_t prespace,
+ char **out, size_t *outlen, size_t *outprespace, gboolean flush)
+{
+ CamelMimeFilterEnriched *enriched = (CamelMimeFilterEnriched *) filter;
+ const char *tag, *inend, *outend;
+ register const char *inptr;
+ register char *outptr;
+
+ camel_mime_filter_set_size (filter, inlen * 2 + 6, FALSE);
+
+ inptr = in;
+ inend = in + inlen;
+ outptr = filter->outbuf;
+ outend = filter->outbuf + filter->outsize;
+
+ loop:
+ do {
+ while (inptr < inend && outptr < outend && !strchr (" <>&\n", *inptr))
+ *outptr++ = *inptr++;
+
+ if (outptr == outend)
+ goto backup;
+
+ if ((inptr + 1) >= inend)
+ break;
+
+ switch (*inptr++) {
+ case ' ':
+ while (inptr < inend && (outptr + 7) < outend && *inptr == ' ') {
+ memcpy (outptr, "&nbsp;", 6);
+ outptr += 6;
+ inptr++;
+ }
+
+ if (outptr < outend)
+ *outptr++ = ' ';
+
+ break;
+ case '\n':
+ if (!(enriched->flags & IS_RICHTEXT) && enriched->nofill <= 0) {
+ /* text/enriched */
+ while (inptr < inend && (outptr + 4) < outend && *inptr == '\n') {
+ memcpy (outptr, "<br>", 4);
+ outptr += 4;
+ inptr++;
+ }
+ } else {
+ /* text/richtext */
+ *outptr++ = ' ';
+ }
+ break;
+ case '>':
+ if ((outptr + 4) < outend) {
+ memcpy (outptr, "&gt;", 4);
+ outptr += 4;
+ } else {
+ inptr--;
+ goto backup;
+ }
+ break;
+ case '&':
+ if ((outptr + 5) < outend) {
+ memcpy (outptr, "&amp;", 5);
+ outptr += 5;
+ } else {
+ inptr--;
+ goto backup;
+ }
+ break;
+ case '<':
+ if (!(enriched->flags & IS_RICHTEXT)) {
+ /* text/enriched */
+ if ((outptr + 4) < outend && *inptr == '<') {
+ memcpy (outptr, "&lt;", 4);
+ outptr += 4;
+ inptr++;
+ break;
+ } else {
+ inptr--;
+ goto backup;
+ }
+ } else {
+ /* text/richtext */
+ if ((inend - inptr) >= 3 && (outptr + 4) < outend) {
+ if (strncmp (inptr, "lt>", 3) == 0) {
+ memcpy (outptr, "&lt;", 4);
+ outptr += 4;
+ inptr += 3;
+ break;
+ } else if (strncmp (inptr, "nl>", 3) == 0) {
+ memcpy (outptr, "<br>", 4);
+ outptr += 4;
+ inptr += 3;
+ break;
+ }
+ } else {
+ inptr--;
+ goto backup;
+ }
+ }
+
+ tag = inptr;
+ while (inptr < inend && *inptr != '>')
+ inptr++;
+
+ if (inptr == inend) {
+ inptr = tag - 1;
+ goto need_input;
+ }
+
+ if (!strncmp (tag, "nofill>", 7)) {
+ if ((outptr + 5) < outend) {
+ memcpy (outptr, "<pre>", 5);
+ enriched->nofill++;
+ outptr += 5;
+ } else {
+ inptr = tag - 1;
+ goto backup;
+ }
+ } else if (!strncmp (tag, "/nofill>", 8)) {
+ if ((outptr + 6) < outend) {
+ memcpy (outptr, "</pre>", 6);
+ enriched->nofill--;
+ outptr += 6;
+ } else {
+ inptr = tag - 1;
+ goto backup;
+ }
+ } else {
+ const char *html_tag;
+ char *enriched_tag;
+ int len;
+
+ enriched_tag = g_strndup (tag, (inptr - tag));
+ html_tag = g_hash_table_lookup (enriched_hash, enriched_tag);
+ g_free (enriched_tag);
+ if (html_tag) {
+ len = strlen (html_tag);
+ if ((outptr + len) < outend) {
+ memcpy (outptr, html_tag, len);
+ outptr += len;
+ } else {
+ inptr = tag - 1;
+ goto backup;
+ }
+ }
+ }
+
+ inptr++;
+ break;
+ default:
+ break;
+ }
+ } while (inptr < inend);
+
+ need_input:
+
+ /* the reason we ignore @flush here is because if there isn't
+ enough input to parse a tag, then there's nothing we can
+ do. */
+
+ if (inptr < inend)
+ camel_mime_filter_backup (filter, inptr, (unsigned) (inend - inptr));
+
+ *out = filter->outbuf;
+ *outlen = outptr - filter->outbuf;
+ *outprespace = filter->outpre;
+
+ return;
+
+ backup:
+
+ if (flush) {
+ size_t offset, grow;
+
+ grow = (inend - inptr) * 2 + 20;
+ offset = outptr - filter->outbuf;
+ camel_mime_filter_set_size (filter, filter->outsize + grow, TRUE);
+ outend = filter->outbuf + filter->outsize;
+ outptr = filter->outbuf + offset;
+
+ goto loop;
+ } else {
+ camel_mime_filter_backup (filter, inptr, (unsigned) (inend - inptr));
+ }
+
+ *out = filter->outbuf;
+ *outlen = outptr - filter->outbuf;
+ *outprespace = filter->outpre;
+}
+
+static void
+filter_filter (CamelMimeFilter *filter, char *in, size_t len, size_t prespace,
+ char **out, size_t *outlen, size_t *outprespace)
+{
+ enriched_to_html (filter, in, len, prespace, out, outlen, outprespace, FALSE);
+}
+
+static void
+filter_complete (CamelMimeFilter *filter, char *in, size_t len, size_t prespace,
+ char **out, size_t *outlen, size_t *outprespace)
+{
+ enriched_to_html (filter, in, len, prespace, out, outlen, outprespace, TRUE);
+}
+
+static void
+filter_reset (CamelMimeFilter *filter)
+{
+ CamelMimeFilterEnriched *enriched = (CamelMimeFilterEnriched *) filter;
+
+ enriched->nofill = 0;
+}
+
+
+/**
+ * camel_mime_filter_enriched_new:
+ * @flags:
+ *
+ * Creates a new CamelMimeFilterEnriched object.
+ *
+ * Returns a new CamelMimeFilter object.
+ **/
+CamelMimeFilter *
+camel_mime_filter_enriched_new (guint32 flags)
+{
+ CamelMimeFilterEnriched *new;
+ int i;
+
+ new = (CamelMimeFilterEnriched *) camel_object_new (CAMEL_TYPE_MIME_FILTER_ENRICHED);
+ new->flags = flags;
+
+ return CAMEL_MIME_FILTER (new);
+}