=================================================================== RCS file: /cvs/pod2mdoc/pod2mdoc.c,v retrieving revision 1.41 retrieving revision 1.47 diff -u -p -r1.41 -r1.47 --- pod2mdoc/pod2mdoc.c 2015/02/13 18:44:04 1.41 +++ pod2mdoc/pod2mdoc.c 2015/02/19 10:46:40 1.47 @@ -1,4 +1,4 @@ -/* $Id: pod2mdoc.c,v 1.41 2015/02/13 18:44:04 schwarze Exp $ */ +/* $Id: pod2mdoc.c,v 1.47 2015/02/19 10:46:40 schwarze Exp $ */ /* * Copyright (c) 2014 Kristaps Dzonsons * Copyright (c) 2014, 2015 Ingo Schwarze @@ -135,7 +135,7 @@ static const char fmts[FMT__MAX] = { 'Z' /* FMT_NULL */ }; -static int last; +static unsigned char last; static void @@ -1120,6 +1120,8 @@ again: break; } switch (buf[i]) { + case '\t': + /* FALLTHROUGH */ case ' ': if ( ! ifa) ifo = i; @@ -1183,7 +1185,7 @@ again: printf(".Fa \"%s\"\n", buf + ifa); if (cp == NULL) break; - while (*cp == ' ') + while (*cp == ' ' || *cp == '\t') cp++; ifa = cp - buf; } @@ -1285,7 +1287,7 @@ donamenm(struct state *st, const char *buf, size_t *st assert(OUST_NL == st->oust); assert(st->wantws); - while (*start < end && ' ' == buf[*start]) + while (*start < end && isspace((unsigned char)buf[*start])) (*start)++; if (end == *start) { @@ -1306,7 +1308,7 @@ donamenm(struct state *st, const char *buf, size_t *st printf(" ,"); mdoc_newln(st); (*start)++; - while (*start < end && ' ' == buf[*start]) + while (*start < end && isspace((unsigned char)buf[*start])) (*start)++; } } @@ -1328,8 +1330,9 @@ donamenm(struct state *st, const char *buf, size_t *st static void ordinary(struct state *st, const char *buf, size_t start, size_t end) { - size_t i, j, opstack; - int seq; + size_t i, j, opstack, wend; + enum mdoc_type mtype; + int eos, noeos, seq; if ( ! st->parsing || st->paused) return; @@ -1342,7 +1345,8 @@ ordinary(struct state *st, const char *buf, size_t sta */ if (SECT_NAME == st->sect) { for (i = end - 2; i > start; i--) - if ('-' == buf[i] && ' ' == buf[i + 1]) + if ('-' == buf[i] && + isspace((unsigned char)buf[i + 1])) break; if ('-' == buf[i]) { j = i; @@ -1352,7 +1356,8 @@ ordinary(struct state *st, const char *buf, size_t sta break; donamenm(st, buf, &start, i + 1); start = j + 1; - while (start < end && ' ' == buf[start]) + while (start < end && + isspace((unsigned char)buf[start])) start++; formatcodeln(st, "Nd", buf, &start, end, 1); mdoc_newln(st); @@ -1395,35 +1400,89 @@ ordinary(struct state *st, const char *buf, size_t sta &start, end, &opstack)) continue; - /* - * On whitespace, flush the output buffer - * and allow breaking to a macro line. - * Otherwise, merely buffer text. - */ + /* Merely buffer non-whitespace. */ last = buf[start++]; - if (' ' != last) { + if ( ! isspace(last)) outbuf_addchar(st); + if (start < end && + ! isspace((unsigned char)buf[start])) continue; - } - if ( ! strcmp(st->outbuf + st->outbuflen - 2, "()") && - dict_get(st->outbuf, st->outbuflen - 2) == - MDOC_Fo) { - st->outbuflen -= 2; - st->outbuf[st->outbuflen] = '\0'; - mdoc_newln(st); - fputs(".Fn ", stdout); - outbuf_flush(st); - mdoc_newln(st); - continue; + /* + * Found the end of a word. + * Rewind trailing delimiters. + */ + + eos = noeos = 0; + for (wend = st->outbuflen; wend; wend--) + if ('.' == st->outbuf[wend - 1] || + '!' == st->outbuf[wend - 1] || + '?' == st->outbuf[wend - 1]) + eos = 1; + else if ('|' == st->outbuf[wend - 1] || + ',' == st->outbuf[wend - 1] || + ';' == st->outbuf[wend - 1] || + ':' == st->outbuf[wend - 1]) + noeos = 1; + else if ('\'' != st->outbuf[wend - 1] && + '"' != st->outbuf[wend - 1] && + ')' != st->outbuf[wend - 1] && + ']' != st->outbuf[wend - 1]) + break; + eos &= ! noeos; + + /* + * Detect function names. + */ + + mtype = MDOC_Fa; + if (wend && ')' == st->outbuf[wend] && + '(' == st->outbuf[wend - 1]) { + mtype = dict_get(st->outbuf, --wend); + if (MDOC_Fo == mtype || MDOC_MAX == mtype) { + st->outbuflen = wend; + st->outbuf[wend] = '\0'; + mdoc_newln(st); + if (MDOC_Fo == mtype) + fputs(".Fn ", stdout); + else + fputs(".Xr ", stdout); + st->oust = OUST_MAC; + } } + /* + * On whitespace, flush the output buffer + * and allow breaking to a macro line. + */ + outbuf_flush(st); - if (OUST_MAC == st->oust) + + /* + * End macro lines, and + * end text lines at the end of sentences. + */ + + if (OUST_MAC == st->oust || (eos && wend > 1 && + islower((unsigned char)st->outbuf[wend - 1]))) { + if (MDOC_MAX == mtype) + fputs(" 3", stdout); + if (MDOC_Fa != mtype) + for (wend += 2; + '\0' != st->outbuf[wend]; + wend++) + printf(" %c", + st->outbuf[wend]); mdoc_newln(st); - else - st->wantws = 1; + } + + /* Advance to the next word. */ + + while ('\n' != buf[start] && + isspace((unsigned char)buf[start])) + start++; + st->wantws = 1; } if (start < end - 1 && '<' == buf[start + 1] && @@ -1528,7 +1587,7 @@ dofile(const struct args *args, const char *fname, { char datebuf[64]; struct state st; - const char *fbase, *fext, *section, *date; + const char *fbase, *fext, *section, *date, *format; char *title, *cp; size_t sup, end, i, cur = 0; @@ -1573,8 +1632,12 @@ dofile(const struct args *args, const char *fname, /* Date. Or the given "tm" if not supplied. */ - if (NULL == (date = args->date)) { - strftime(datebuf, sizeof(datebuf), "%B %d, %Y", tm); + date = args->date; + format = (NULL == date) ? "%B %d, %Y" : + strcmp(date, "Mdocdate") ? NULL : "$Mdocdate: February 19 2015 $"; + + if (NULL != format) { + strftime(datebuf, sizeof(datebuf), format, tm); date = datebuf; }