2 * Parts were written/modified by:
3 * Andreas Krennmair <ak@synflood.at>
4 * Peter J. Holzer <hjp@hjp.net>
5 * Rocco Rutte <pdmef@cs.tu-berlin.de>
7 * This file is part of mutt-ng, see http://www.muttng.org/.
8 * It's licensed under the GNU General Public License,
9 * please see the file GPL in the top level source directory.
24 #include "mutt_curses.h"
33 #include "lib/debug.h"
35 typedef int handler_f (BODY *, STATE *);
36 typedef handler_f *handler_t;
40 static int get_quote_level (char *line)
44 for (quoted = 0; line[quoted] == '>'; quoted++);
48 static void print_flowed_line (char *line, STATE * s,
50 int* spaces, int space_len) {
53 int len = str_len (line);
56 if (MaxLineLength > 0) {
57 width = MaxLineLength - WrapMargin - ql - 1;
58 if (option (OPTSTUFFQUOTED))
61 width = MaxLineLength;
64 if (option (OPTMBOXPANE))
65 width = COLS - SidebarWidth - WrapMargin - ql - 1;
67 width = COLS - WrapMargin - ql - 1;
69 if (option (OPTSTUFFQUOTED))
75 if (str_len (line) == 0) {
76 if (option (OPTQUOTEEMPTY)) {
78 state_puts(s->prefix,s);
79 for (i=0;i<ql;++i) state_putc('>',s);
80 if (option(OPTSTUFFQUOTED))
90 for (; oldpos < line + len; pos += width) {
91 /* only search a new position when we're not over
92 * the end of the string w/ pos */
93 if (pos < line + len) {
94 /* fprintf(stderr,"if 1\n"); */
96 /* fprintf(stderr,"if 2: good luck! found a space\n"); */
101 /* fprintf(stderr,"if 2: else\n"); */
104 while (pos >= oldpos && *pos != ' ') {
105 /* fprintf(stderr,"pos(%p) > oldpos(%p)\n",pos,oldpos); */
109 /* fprintf(stderr,"wow, no space found,
110 * searching the other direction\n"); */
112 while (pos < line + len && *pos && *pos != ' ') {
113 /* fprintf(stderr,"pos(%p) < line+len(%p)\n",pos,line+len); */
116 /* fprintf(stderr,"found a space pos = %p\n",pos); */
123 /* fprintf(stderr,"if 1 else\n"); */
126 state_puts (s->prefix, s);
128 for (i = 0; i < ql; ++i)
130 if (option (OPTSTUFFQUOTED) && (ql > 0 || s->prefix))
133 if (delsp && spaces && space_len > 0) {
134 /* here, we need to character-wise step through the line
135 * to eliminate all spaces which were trailing due to DelSp */
136 for (i = 0; i < str_len (oldpos); i++) {
137 if (oldpos[i] == ' ' && spaces[&(oldpos[i])-line] != 0) {
138 debug_print (4, ("DelSp: spaces[%d] forces space removal\n",
142 /* print space at oldpos[i] if it was non-trailing */
143 state_putc (oldpos[i], s);
146 /* for no DelSp, just do whole line as per usual */
147 state_puts (oldpos, s);
148 /* fprintf(stderr,"print_flowed_line: `%s'\n",oldpos); */
149 if (pos < line + len)
151 state_putc ('\n', s);
156 int rfc3676_handler (BODY * a, STATE * s) {
157 int bytes = a->length;
158 char buf[LONG_STRING];
159 char *curline = str_dup ("");
161 unsigned int curline_len = 1, space_len = 1,
162 quotelevel = 0, newql = 0;
163 int buf_off, buf_len;
167 /* respect DelSP of RfC3676 only with f=f parts */
168 if ((t = (char*) mutt_get_parameter ("delsp", a->parameter))) {
169 delsp = str_len (t) == 3 && ascii_strncasecmp (t, "yes", 3) == 0;
173 debug_print (2, ("DelSp: %s\n", delsp ? "yes" : "no"));
175 while (bytes > 0 && fgets (buf, sizeof (buf), s->fpin)) {
176 buf_len = str_len (buf);
179 newql = get_quote_level (buf);
181 /* a change of quoting level in a paragraph - shouldn't happen,
182 * but has to be handled - see RFC 3676, sec. 4.5.
184 if (newql != quotelevel && curline && *curline) {
185 print_flowed_line (curline, s, quotelevel, delsp, spaces, space_len);
192 /* XXX - If a line is longer than buf (shouldn't happen), it is split.
193 * This will almost always cause an unintended line break, and
194 * possibly a change in quoting level. But that's better than not
195 * displaying it at all.
197 if ((t = strrchr (buf, '\n')) || (t = strrchr (buf, '\r'))) {
202 /* respect space-stuffing */
203 if (buf[buf_off] == ' ')
206 /* signature separator also flushes the previous paragraph */
207 if (strcmp(buf + buf_off, "-- ") == 0 && curline && *curline) {
208 print_flowed_line (curline, s, quotelevel, delsp, spaces, space_len);
214 mem_realloc (&curline, curline_len + buf_len - buf_off);
215 mem_realloc (&spaces, (curline_len + buf_len - buf_off)*sizeof (int));
216 strcpy (curline + curline_len - 1, buf + buf_off);
217 memset (&spaces[space_len], 0, (buf_len - buf_off)*sizeof (int));
218 curline_len += buf_len - buf_off;
219 space_len += buf_len - buf_off;
221 /* if this was a fixed line the paragraph is finished */
222 if (buf_len == 0 || buf[buf_len - 1] != ' ' || strcmp(buf + buf_off, "-- ") == 0) {
223 print_flowed_line (curline, s, quotelevel, delsp, spaces, space_len);
228 /* if last line we appended had a space and we have DelSp=yes,
229 * get a 1 into spaces array at proper position so that
230 * print_flowed_line() can handle it; don't kill the space
231 * right here 'cause we maybe need soft linebreaks to search for break
233 if (delsp && curline && *curline && curline_len-2 >= 0 &&
234 curline[curline_len-2] == ' ') {
235 debug_print (4, ("DelSp: marking spaces[%d] for later removal\n",
237 spaces[curline_len-2] = 1;