Mercurial > hg > mlmmj
changeset 837:f51138584096
Improvements to wrapping.
- Introduce \<space> to indicate line-break positions to enable sensible
wrapping of Chinese and similar text.
- Allow lines to be longer than the wrapping width if there are no spaces, as
generated email addresses (e.g. for moderation) won't work if split.
- Fix a bug where using a whole line while wrapping would turn wrapping off as
the saved (empty) remaining portion would be considered a blank line.
- Use int rather than size_t for line lengths; it's just easier, since we use
negatives for certain conditions, and it should be plenty big enough.
author | Ben Schmidt |
---|---|
date | Mon, 23 Jan 2012 19:55:04 +1100 |
parents | 5ab7b62e8223 |
children | 64552670ace9 |
files | ChangeLog README.listtexts src/prepstdreply.c |
diffstat | 3 files changed, 82 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Jan 23 18:30:06 2012 +1100 +++ b/ChangeLog Mon Jan 23 19:55:04 2012 +1100 @@ -1,3 +1,7 @@ + o Introduce \<space> to indicate line-break positions to enable sensible + wrapping of Chinese and similar text. + o Allow lines to be longer than the wrapping width if there are no spaces, + as generated email addresses (e.g. for moderation) won't work if split. o Add rejection of posts and obstruction of subscriptions. o Avoid bogus error messages when logging that the list address has been found in To: or CC: headers.
--- a/README.listtexts Mon Jan 23 18:30:06 2012 +1100 +++ b/README.listtexts Mon Jan 23 19:55:04 2012 +1100 @@ -248,11 +248,13 @@ - %wrap% - %wrap W% - lines until the next blank line are concatenated (lines have whitespace - trimmed, then a single space is used to separate them) and are then rewrapped - (by breaking them at spaces) to a width of W (or 76 if W is omitted); the - width is reckoned including characters preceding the directive so it is an - absolute maximum width + lines until the next blank line are concatenated and are then rewrapped to a + width of W (or 76 if W is omitted); lines have whitespace trimmed before + being joined with a single space; lines are broken at spaces or at points + marked for breaking with \<space>; the width is reckoned including any text + preceding the directive and any indentation preserved from a file which + included the current one, so it is an absolute maximum width; it is measured + in bytes - %text T% text from the file named T in the listdir/text directory; the name may only @@ -502,6 +504,8 @@ Subject: header as Mlmmj does automatic quoting for that header as described above) +- \<space> + nothing, but allow the line to be broken here when wrapping + - \\ a single \ -
--- a/src/prepstdreply.c Mon Jan 23 18:30:06 2012 +1100 +++ b/src/prepstdreply.c Mon Jan 23 19:55:04 2012 +1100 @@ -106,8 +106,8 @@ substitution *substs; char *mailname; formatted *fmts; - size_t wrapindent; - size_t wrapwidth; + int wrapindent; + int wrapwidth; conditional *cond; conditional *skip; }; @@ -961,11 +961,11 @@ { char *line; const char *item; - char *pos; - char *tmp, *spc; + char *pos, *subpos; + char *tmp; char *prev = NULL; - int incision; - size_t len, i; + int incision, spc, spcnext; + int len, i; int directive; int peeking = 0; /* for a failed conditional without an else */ int swallow; @@ -1060,11 +1060,27 @@ } else { incision = -1; } - spc = NULL; + spc = -1; + spcnext = 0; directive = 0; while (*pos != '\0') { - if (txt->wrapwidth != 0 && len > txt->wrapwidth && - !peeking) break; + if (txt->wrapwidth != 0 && len >= txt->wrapwidth && + !peeking) { + if (spcnext < txt->wrapwidth || spc == -1) { + subpos = line + spcnext; + while (subpos < pos) { + if (*subpos == ' ') { + spc = subpos - line; + } + spcnext++; + if (spcnext >= txt->wrapwidth && + spc != -1) + break; + subpos++; + } + } + if (spc != -1) break; + } if (*pos == '\r') { *pos = '\0'; pos++; @@ -1079,7 +1095,21 @@ txt->src->upcoming = mystrdup(pos); break; } else if (*pos == ' ') { - spc = pos; + if (txt->skip == NULL) { + spc = pos - line; + spcnext = spc + 1; + } + } else if (*pos == '\\' && *(pos + 1) == ' ') { + if (txt->skip == NULL) { + spc = pos - line - 1; + spcnext = spc + 1; + } + *pos = '\0'; + tmp = concatstr(2, line, pos + 2); + pos = tmp + (pos - line); + myfree(line); + line = tmp; + continue; } else if (*pos == '\t') { /* Avoid breaking due to peeking */ } else if (txt->src->transparent) { @@ -1091,7 +1121,6 @@ substitute_one(&line, &pos, listaddr, listdelim, listdir, txt); len = pos - line; - spc = NULL; /* The function sets up for the next character * to process, so continue straight away. */ continue; @@ -1099,7 +1128,6 @@ directive = 1; swallow = handle_directive(txt, &line, &pos, peeking, listdir); - spc = NULL; if (swallow == 1) peeking = 0; if (swallow == -1) break; if (txt->skip != NULL) { @@ -1130,7 +1158,10 @@ } else if (peeking && txt->skip == NULL) { break; } - if (txt->skip == NULL) len++; + if (txt->skip == NULL) { + if (spcnext == len) spcnext++; + len++; + } pos++; } @@ -1155,27 +1186,17 @@ } if (txt->wrapwidth != 0 && !peeking) { - if (len <= txt->wrapwidth) { + if (len < txt->wrapwidth) { prev = line; continue; } - if (spc == NULL) { - pos = line + len - 1; - while (pos >= line) { - if (*pos == ' ') { - spc = pos; - break; - } - pos--; + if (spc != -1) { + if (line[spc] == ' ') line[spc] = '\0'; + spc++; + if (line[spc] == '\0') spc = -1; } - } - if (spc == NULL) { - spc = line + txt->wrapwidth - 1; - } else { - *spc = '\0'; - spc++; - } - len = strlen(spc); + if (spc != -1) { + len = strlen(line + spc); if (txt->src->upcoming == NULL) { tmp = mymalloc((len + txt->wrapindent + 1) * sizeof(char)); @@ -1185,14 +1206,16 @@ sizeof(char)); } pos = tmp; - for (i = txt->wrapindent; i > 0; i--) *pos++ = ' '; - strcpy(pos, spc); + for (i = txt->wrapindent; i > 0; i--) + *pos++ = ' '; + strcpy(pos, line + spc); if (txt->src->upcoming != NULL) { strcpy(pos + len, txt->src->upcoming); myfree(txt->src->upcoming); } txt->src->upcoming = tmp; - *spc = '\0'; + } + line[spc] = '\0'; tmp = mystrdup(line); myfree(line); line = tmp;