--- /dev/null
+This document lists bug known to exist in mutt-ng.
+
+RfC 3676 defining format=flowed
+===============================
+
+This RfC specifies quote chars to be '>' and due to space-stuffing lines
+there're no spaces withing the quote prefix of a line allowed.
+Currently, the implementation does:
+
+- Change all quote characters by force to '>'. This is plain wrong in
+ some cases where a character from $quote_regexp (even with the default
+ setting) may appear at the beginning of a line but actually doesn't
+ represent a quoted line. For example, someone may quote parts of
+ muttng configs with comments. However, _if_ this _is_ a quoted line
+ using e.g. '#' as $indent_string, we need to change the '#' prefix to
+ '>'.
+
+- Compress the complete quote, i.e. remove any spaces within the
+ complete quote prefix of a line. This, too, is just plain wrong. For
+ example, some people may have $indent_string set to '> ' and this gets
+ quoted several times to something like '>> >>'. However this
+ semanticly has a quote level of 3 as the second poster space-stuffed
+ that line. IMHO it's more common that people use spaces in
+ $indent_string (which the implementation removes right now) than
+ people space-stuffing lines which start '>' to ' >' when composing new
+ messages.
#include "lib/str.h"
#include "lib/debug.h"
-typedef int handler_f (BODY *, STATE *);
-typedef handler_f *handler_t;
-
#define FLOWED_MAX 77
static int get_quote_level (char *line)
/* only search a new position when we're not over
* the end of the string w/ pos */
if (pos < line + len) {
- /* fprintf(stderr,"if 1\n"); */
if (*pos == ' ') {
- /* fprintf(stderr,"if 2: good luck! found a space\n"); */
+ debug_print (4, ("f=f: found space directly at width\n"));
*pos = '\0';
++pos;
}
else {
- /* fprintf(stderr,"if 2: else\n"); */
char *save = pos;
+ debug_print (4, ("f=f: need to search for space\n"));
while (pos >= oldpos && *pos != ' ') {
- /* fprintf(stderr,"pos(%p) > oldpos(%p)\n",pos,oldpos); */
--pos;
}
if (pos < oldpos) {
- /* fprintf(stderr,"wow, no space found,
- * searching the other direction\n"); */
+ debug_print (4, ("f=f: no space found while searching "
+ "to left; going right\n"));
pos = save;
while (pos < line + len && *pos && *pos != ' ') {
- /* fprintf(stderr,"pos(%p) < line+len(%p)\n",pos,line+len); */
++pos;
}
- /* fprintf(stderr,"found a space pos = %p\n",pos); */
+ debug_print (4, ("f=f: found space at pos %d\n", pos-line));
+ } else {
+ debug_print (4, ("f=f: found space while searching to left\n"));
}
*pos = '\0';
++pos;
}
}
else {
- /* fprintf(stderr,"if 1 else\n"); */
+ debug_print (4, ("f=f: line completely fits on screen\n"));
}
if (s->prefix)
state_puts (s->prefix, s);
* to eliminate all spaces which were trailing due to DelSp */
for (i = 0; i < str_len (oldpos); i++) {
if (oldpos[i] == ' ' && spaces[&(oldpos[i])-line] != 0) {
- debug_print (4, ("DelSp: spaces[%d] forces space removal\n",
+ debug_print (4, ("f=f: DelSp: spaces[%d] forces space removal\n",
&(oldpos[i])-line));
continue;
}
t = NULL;
}
- debug_print (2, ("DelSp: %s\n", delsp ? "yes" : "no"));
+ debug_print (2, ("f=f: DelSp: %s\n", delsp ? "yes" : "no"));
while (bytes > 0 && fgets (buf, sizeof (buf), s->fpin)) {
buf_len = str_len (buf);
*/
if (delsp && curline && *curline && curline_len-2 >= 0 &&
curline[curline_len-2] == ' ') {
- debug_print (4, ("DelSp: marking spaces[%d] for later removal\n",
+ debug_print (4, ("f=f: DelSp: marking spaces[%d] for later removal\n",
curline_len-2));
spaces[curline_len-2] = 1;
}
mem_free (&curline);
return (0);
}
+
+void rfc3676_quote_line (STATE* s, char* dst, size_t dstlen,
+ const char* line) {
+ char quote[SHORT_STRING];
+ int offset = 0, i = 0, count = 0;
+ regmatch_t pmatch[1];
+
+ quote[0] = '\0';
+
+ while (regexec ((regex_t *) QuoteRegexp.rx, &line[offset],
+ 1, pmatch, 0) == 0)
+ offset += pmatch->rm_eo;
+
+ if (offset > 0) {
+ /* first count number of real quoting characters;
+ * read: non-spaces
+ * this maybe just plain wrong, but leaving spaces
+ * within quoting characters is what I consider
+ * more plain wrong...
+ */
+ for (i = 0; i < offset; i++)
+ if (line[i] != ' ')
+ count++;
+ /* just make sure we're inside quote althoug we
+ * likely won't have more than SHORT_STRING quote levels... */
+ i = (count > SHORT_STRING-1) ? SHORT_STRING-1 : count;
+ memset (quote, '>', i);
+ quote[i] = '\0';
+ }
+ debug_print (4, ("f=f: quotelevel = %d, new prefix = '%s'\n",
+ i, NONULL (quote)));
+ /* if we changed prefix, make sure we respect $stuff_quoted */
+ snprintf (dst, dstlen, "%s%s%s%s", NONULL (s->prefix), NONULL (quote),
+ option (OPTSTUFFQUOTED) && line[offset] != ' ' ? " " : "",
+ &line[offset]);
+}
#include "mutt.h"
#include "state.h"
+#include "rfc3676.h"
+
+#include "lib/debug.h"
static void state_prefix_put (const char *d, size_t dlen, STATE * s)
{
char buf[2 * SHORT_STRING];
int j = 0, offset = 0;
regmatch_t pmatch[1];
+#ifdef DEBUG
+ unsigned char save = '\0';
+#endif
state_reset_prefix (s);
while (regexec
if (!option (OPTQUOTEEMPTY) && Quotebuf[offset] == '\n') {
buf[0] = '\n';
buf[1] = '\0';
- }
+ } else if (option (OPTTEXTFLOWED))
+ rfc3676_quote_line (s, buf, sizeof (buf), Quotebuf);
else if (option (OPTQUOTEQUOTED) && offset) {
for (i = 0; i < offset; i++)
if (Quotebuf[i] != ' ')
else
snprintf (buf, sizeof (buf), "%s%s", NONULL (s->prefix), Quotebuf);
+#ifdef DEBUG
+ if (str_len (buf) >= 2) {
+ save = buf[str_len (buf) - 1];
+ buf[str_len (buf) - 1] = '\0';
+ debug_print (2, ("buf = '%s'\n", buf));
+ buf[str_len (buf)] = save;
+ }
+#endif
+
state_puts (buf, s);
}
}