Mercurial > hg > mlmmj
changeset 815:fdd43713fb52
Add %wrap% and %wrap W% formatting directives.
author | Ben Schmidt |
---|---|
date | Tue, 17 Jan 2012 13:05:40 +1100 |
parents | 757225257ef3 |
children | ed446ead03bd |
files | ChangeLog README.listtexts src/prepstdreply.c |
diffstat | 3 files changed, 199 insertions(+), 74 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Jan 17 11:20:38 2012 +1100 +++ b/ChangeLog Tue Jan 17 13:05:40 2012 +1100 @@ -1,3 +1,4 @@ + o Add %wrap% and %wrap W% formatting directives o Add %digestthreads%, %gatekeepers%, %listsubs%, %digestsubs%, %nomailsubs%, %moderators% and %bouncenumbers% o Deprecate various list text substitutions such as $newsub$, $oldsub$,
--- a/README.listtexts Tue Jan 17 11:20:38 2012 +1100 +++ b/README.listtexts Tue Jan 17 13:05:40 2012 +1100 @@ -248,10 +248,11 @@ - %wrap% - %wrap W% - lines until the next blank line are all concatenated (lines after the first - have whitespace trimmed; a single space separates lines) and are then - rewrapped (by breaking them at spaces) to a width of W (or 76 if W is - omitted) + 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 - %text T% text from the file named T in the listdir/text directory; the name may only
--- a/src/prepstdreply.c Tue Jan 17 11:20:38 2012 +1100 +++ b/src/prepstdreply.c Tue Jan 17 13:05:40 2012 +1100 @@ -85,6 +85,8 @@ substitution *substs; char *mailname; formatted *fmts; + size_t wrapindent; + size_t wrapwidth; }; @@ -425,6 +427,8 @@ txt->substs = NULL; txt->mailname = NULL; txt->fmts = NULL; + txt->wrapindent = 0; + txt->wrapwidth = 0; tmp = concatstr(3, listdir, "/text/", filename); txt->src->fd = open(tmp, O_RDONLY); @@ -659,13 +663,33 @@ *line_p = line; return; } else if(strcmp(token, "comment") == 0 || strcmp(token, "$") == 0 ) { - /* Skip the rest of the line; the earlier part which we - * will return has already been truncated; the caller - * will save the next line for later use if necessary. */ pos = endpos + 1; while (*pos != '\0' && *pos != '\r' && *pos != '\n') pos++; - *pos_p = pos; + line = concatstr(2, line, pos); + *pos_p = line + (*pos_p - *line_p); + myfree(*line_p); + *line_p = line; return; + } else if(strncmp(token, "wrap", 4) == 0) { + token += 4; + limit = 0; + if (*token == '\0') { + limit = 76; + } else if (*token == ' ') { + token = numeric_token(token + 1); + if (token != NULL) limit = atol(token); + } + if (limit != 0) { + txt->wrapindent = strlen(line); + if (txt->src->prefix != NULL) + txt->wrapindent -= strlen(txt->src->prefix); + txt->wrapwidth = limit; + line = concatstr(2, line, endpos + 1); + *pos_p = line + (*pos_p - *line_p); + myfree(*line_p); + *line_p = line; + return; + } } else if(strncmp(token, "control ", 8) == 0) { token = filename_token(token + 8); if (token != NULL) { @@ -736,14 +760,18 @@ const char *listdir) { char *line = NULL; + const char *item; char *pos; - char *tmp; - const char *item; + char *tmp, *spc; + char *prev = NULL; + size_t len, i; + for (;;) { while (txt->src != NULL) { if (txt->src->upcoming != NULL) { if (txt->src->prefix != NULL) { - line = concatstr(2, txt->src->prefix, txt->src->upcoming); + line = concatstr(2, txt->src->prefix, + txt->src->upcoming); myfree(txt->src->upcoming); } else { line = txt->src->upcoming; @@ -753,7 +781,8 @@ } if (txt->src->limit != 0) { if (txt->src->fd != -1) { - txt->src->upcoming = mygetline(txt->src->fd); + txt->src->upcoming = + mygetline(txt->src->fd); } else if (txt->src->fmt != NULL) { item = (*txt->src->fmt->get)( txt->src->fmt->state); @@ -775,8 +804,50 @@ myfree(line); line = tmp; + if (prev != NULL) { + /* Wrapping */ + len = strlen(prev); + pos = prev + len - 1; + while (pos > prev && (*pos == ' ' || *pos == '\t')) + pos--; + pos++; + *pos = '\0'; + len = pos - prev; + if (*line == '\r' || *line == '\n' || *line == '\0') { + /* Blank line; stop wrapping, finish + the last line and save the blank + line for later. */ + txt->wrapwidth = 0; + txt->src->upcoming = line; + line = prev; + pos = line + len; + } else { pos = line; + while (*pos == ' ' || *pos == '\t') pos++; + if (*pos == '\0') { + myfree(line); + continue; + } + if (*prev == '\0') { + tmp = mystrdup(pos); + } else { + tmp = concatstr(3, prev, " ", pos); + } + myfree(line); + line = tmp; + myfree(prev); + len++; + pos = line + len; + } + prev = NULL; + } else { + len = 0; + pos = line; + } + + spc = NULL; while (*pos != '\0') { + if (txt->wrapwidth != 0 && len > txt->wrapwidth) break; if (*pos == '\r') { *pos = '\0'; pos++; @@ -790,24 +861,75 @@ if (*pos == '\0') break; txt->src->upcoming = mystrdup(pos); break; + } else if (*pos == ' ') { + spc = pos; } else if (txt->src->transparent) { /* Do nothing if the file is to be included * transparently */ } else if (*pos == '$') { - substitute_one(&line, &pos, - listaddr, listdelim, listdir, txt); + 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; } else if (*pos == '%') { handle_directive(txt, &line, &pos, listdir); + len = pos - line; + spc = NULL; /* The function sets up for the next character * to process, so continue straight away. */ continue; } + len++; pos++; } + if (txt->wrapwidth != 0) { + 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 == NULL) { + spc = line + txt->wrapwidth - 1; + } else { + *spc = '\0'; + spc++; + } + len = strlen(spc); + if (txt->src->upcoming == NULL) { + tmp = mymalloc((len + txt->wrapindent + 1) * + sizeof(char)); + } else { + tmp = mymalloc((len + txt->wrapindent + 1 + + strlen(txt->src->upcoming)) * + sizeof(char)); + } + pos = tmp; + for (i = txt->wrapindent; i > 0; i--) *pos++ = ' '; + strcpy(pos, spc); + if (txt->src->upcoming != NULL) { + strcpy(pos + len, txt->src->upcoming); + myfree(txt->src->upcoming); + } + txt->src->upcoming = tmp; + *spc = '\0'; + tmp = mystrdup(line); + myfree(line); + line = tmp; + } + if (txt->src->suffix != NULL) { tmp = concatstr(2, line, txt->src->suffix); myfree(line); @@ -816,6 +938,7 @@ return line; } } +} void close_text(text *txt) {