]> granicus.if.org Git - mutt/commitdiff
Add experimental support for text/plain; format=flowed.
authorThomas Roessler <roessler@does-not-exist.org>
Fri, 11 May 2001 14:43:19 +0000 (14:43 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Fri, 11 May 2001 14:43:19 +0000 (14:43 +0000)
copy.c
handler.c
init.h
mutt.h
send.c

diff --git a/copy.c b/copy.c
index 7e590838bd0294deea8d0853bde0a03644247b53..a650add97fa1328cf385a3d8947a644f7ec98a0e 100644 (file)
--- a/copy.c
+++ b/copy.c
@@ -432,7 +432,12 @@ _mutt_copy_message (FILE *fpout, FILE *fpin, HEADER *hdr, BODY *body,
   long new_offset = -1;
 
   if (flags & M_CM_PREFIX)
-    _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, hdr, 0);
+  {
+    if (option (OPTTEXTFLOWED))
+      strfcpy (prefix, ">", sizeof (prefix));
+    else
+      _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, hdr, 0);
+  }
 
   if ((flags & M_CM_NOHEADER) == 0)
   {
index ffd9d9fa066680f86c57c17794480238bcc6191c..6f86a19b793e5f409ee1e075b267fdaaf8a4ae50 100644 (file)
--- a/handler.c
+++ b/handler.c
@@ -882,6 +882,155 @@ void text_enriched_handler (BODY *a, STATE *s)
   FREE (&(stte.param));
 }                                                                              
 
+#define FLOWED_MAX 78
+
+static void flowed_quote (STATE *s, int level)
+{
+  int i;
+  
+  if (s->prefix)
+  {
+    if (option (OPTTEXTFLOWED))
+      level++;
+    else
+      state_puts (s->prefix, s);
+  }
+  
+  for (i = 0; i < level; i++)
+    state_putc ('>', s);
+}
+
+static void flowed_stuff (STATE *s, const char *cont, int level)
+{
+  if (s->flags & M_DISPLAY)
+    return;
+  if (!option (OPTTEXTFLOWED))
+    return;
+  if ((*cont == ' ') || (*cont == '>') || (!level && !mutt_strncmp (cont, "From ", 5)))
+    state_putc (' ', s);
+}
+
+static void text_plain_flowed_handler (BODY *a, STATE *s)
+{
+  char line[LONG_STRING];
+  int  quoted = -1;
+  int  col = 0;
+
+  int  add = 0;
+  int  soft = 0;
+  int  max;
+  int  l;
+  
+  int  flowed_max;
+  
+  int bytes = a->length;
+  
+  char *cont = NULL;
+  char *tail = NULL;
+  char *lc = NULL;
+  char *t;
+  
+  if (s->prefix)
+    add = 1;
+
+  if ((flowed_max = FLOWED_MAX) > COLS)
+    flowed_max = COLS - 2;
+  
+  while (bytes > 0 && fgets (line, sizeof (line), s->fpin))
+  {
+    bytes -= strlen (line);
+    tail = NULL;
+    
+    if ((t = strrchr (line, '\r')) || (t = strrchr (line, '\n')))
+      *t = '\0';
+    
+    for (quoted = 0; line[quoted] == '>'; quoted++)
+      ;
+
+    dprint (2, (debugfile, "line: `%s', quoted = %d\n", line, quoted));
+    
+    cont = line + quoted;
+    if (*cont == ' ')
+      cont++;
+    
+    do 
+    {
+      if (tail)
+       cont = tail;
+      
+      tail = NULL;
+      soft = 0;
+      
+      /* try to find a point for word wrapping */
+
+    retry_wrap:
+      l = mutt_strlen (cont);
+      if (quoted + add + col + l > flowed_max)
+      {
+       if ((max = flowed_max - quoted - add - col)
+           > l)
+         max = l;
+
+       for (t = cont + max; t > cont; t--)
+       {
+         if (*t == ' ' || *t == '\t')
+         {
+           tail = t;
+           break;
+         }
+       }
+
+       if (tail)
+       {
+         *tail++ = '\0';
+         soft = 2;
+       }
+      }
+
+      /* We might be desperate.  Just wrap. */
+      if (!tail && (quoted + add + col + mutt_strlen (cont) > flowed_max) && col)
+      {
+       state_putc ('\n', s);
+       col = 0;
+       goto retry_wrap;
+      }
+      
+      if (!soft && ascii_strcmp (cont, "-- "))
+      {
+       lc = strrchr (cont, ' ');
+       if (lc && lc[1] == '\0')
+         soft = 1;
+      }
+
+      if (!col)
+      {
+       flowed_quote (s, quoted);
+       flowed_stuff (s, cont, quoted + add);
+      }
+      
+      state_puts (cont, s);
+      col += strlen (cont);
+      
+      if (soft == 2)
+      {
+       state_putc (' ', s);
+       col++;
+      }
+      
+      if (!soft)
+      {
+       state_putc ('\n', s);
+       col = 0;
+      }
+    }
+    while (tail);
+  }
+
+  if (col)
+    state_putc ('\n', s);
+  
+}
+
 #define TXTHTML     1
 #define TXTPLAIN    2
 #define TXTENRICHED 3
@@ -1419,7 +1568,10 @@ void mutt_body_handler (BODY *b, STATE *s)
       /* avoid copying this part twice since removing the transfer-encoding is
        * the only operation needed.
        */
-      plaintext = 1;
+      if (ascii_strcasecmp ("flowed", mutt_get_parameter ("format", b->parameter)) == 0)
+       handler = text_plain_flowed_handler;
+      else
+       plaintext = 1;
     }
     else if (ascii_strcasecmp ("enriched", b->subtype) == 0)
       handler = text_enriched_handler;
diff --git a/init.h b/init.h
index 0e44e17645b731a5f109700669cd65fcba33feca..915606b7ce205ffaa10233afba8341f32e99bb8b 100644 (file)
--- a/init.h
+++ b/init.h
@@ -2076,6 +2076,16 @@ struct option_t MuttVars[] = {
   ** \fIsusp\fP key, usually ``control-Z''. This is useful if you run mutt
   ** inside an xterm using a command like xterm -e mutt.
   */
+  { "text_flowed",     DT_BOOL, R_NONE, OPTTEXTFLOWED,  0 },
+  /*
+  ** .pp
+  ** When set, mutt will generate text/plain; format=flowed attachments.
+  ** This format is easier to handle for some mailing software, and generally
+  ** just looks like ordinary text.  To actually make use of this format's 
+  ** features, you'll need support in your editor.
+  ** .pp
+  ** Note that $$indent_string is ignored when this option is set.
+  */
   { "thorough_search", DT_BOOL, R_NONE, OPTTHOROUGHSRC, 0 },
   /*
   ** .pp
diff --git a/mutt.h b/mutt.h
index 2ae91b54fb854b70457b91d9ed5da2a56b9e2327..6d11a4aa0bf397e4fa9d268833f7aa0eeb70e2bf 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -376,6 +376,7 @@ enum
   OPTSTATUSONTOP,
   OPTSTRICTTHREADS,
   OPTSUSPEND,
+  OPTTEXTFLOWED,
   OPTTHOROUGHSRC,
   OPTTILDE,
   OPTUNCOLLAPSEJUMP,
diff --git a/send.c b/send.c
index e30a39a4ffd28c91261302153cf8613ca57ed61e..ffc4bb88f5a9e38c5e8d5a7521811ddb4f51068b 100644 (file)
--- a/send.c
+++ b/send.c
@@ -1131,6 +1131,8 @@ ci_send_message (int flags,               /* send mode */
     msg->content->unlink = 1;
     msg->content->use_disp = 0;
     msg->content->disposition = DISPINLINE;
+    if (option (OPTTEXTFLOWED))
+      mutt_set_parameter ("format", "flowed", &msg->content->parameter);
     
     if (!tempfile)
     {