=================================================================== RCS file: /cvs/docbook2mdoc/macro.c,v retrieving revision 1.9 retrieving revision 1.17 diff -u -p -r1.9 -r1.17 --- docbook2mdoc/macro.c 2019/04/11 04:23:22 1.9 +++ docbook2mdoc/macro.c 2019/05/01 15:05:39 1.17 @@ -1,4 +1,4 @@ -/* $Id: macro.c,v 1.9 2019/04/11 04:23:22 schwarze Exp $ */ +/* $Id: macro.c,v 1.17 2019/05/01 15:05:39 schwarze Exp $ */ /* * Copyright (c) 2019 Ingo Schwarze * @@ -30,6 +30,13 @@ void macro_open(struct format *f, const char *name) { + if (f->parastate == PARA_WANT) { + if (f->linestate != LINE_NEW) { + putchar('\n'); + f->linestate = LINE_NEW; + } + puts(".Pp"); + } switch (f->linestate) { case LINE_MACRO: if (f->flags & FMT_NOSPC) { @@ -42,6 +49,8 @@ macro_open(struct format *f, const char *name) } /* FALLTHROUGH */ case LINE_TEXT: + if (f->nofill) + fputs(" \\c", stdout); putchar('\n'); /* FALLTHROUGH */ case LINE_NEW: @@ -53,6 +62,7 @@ macro_open(struct format *f, const char *name) fputs(name, stdout); f->flags &= FMT_IMPL; f->flags |= FMT_ARG; + f->parastate = PARA_MID; } void @@ -79,11 +89,13 @@ void macro_addarg(struct format *f, const char *arg, int flags) { const char *cp; + int quote_now; assert(f->linestate == LINE_MACRO); /* Quote if requested and necessary. */ + quote_now = 0; if ((flags & (ARG_SINGLE | ARG_QUOTED)) == ARG_SINGLE) { for (cp = arg; *cp != '\0'; cp++) if (isspace((unsigned char)*cp)) @@ -95,6 +107,7 @@ macro_addarg(struct format *f, const char *arg, int fl } putchar('"'); flags = ARG_QUOTED; + quote_now = 1; } } @@ -112,13 +125,16 @@ macro_addarg(struct format *f, const char *arg, int fl /* Escape us if we look like a macro. */ - if ((flags & ARG_QUOTED) == 0 && + if ((flags & (ARG_QUOTED | ARG_UPPER)) == 0 && (cp == arg || isspace((unsigned char)cp[-1])) && isupper((unsigned char)cp[0]) && islower((unsigned char)cp[1]) && (cp[2] == '\0' || cp[2] == ' ' || - (islower((unsigned char)cp[2]) && - (cp[3] == '\0' || cp[3] == ' ')))) + ((cp[3] == '\0' || cp[3] == ' ') && + (strncmp(cp, "Brq", 3) == 0 || + strncmp(cp, "Bro", 3) == 0 || + strncmp(cp, "Brc", 3) == 0 || + strncmp(cp, "Bsx", 3) == 0)))) fputs("\\&", stdout); if (*cp == '"') @@ -130,6 +146,9 @@ macro_addarg(struct format *f, const char *arg, int fl if (*cp == '\\') putchar('e'); } + if (quote_now) + putchar('"'); + f->parastate = PARA_MID; } void @@ -147,7 +166,7 @@ void macro_addnode(struct format *f, struct pnode *n, int flags) { struct pnode *nc; - int quote_now; + int is_text, quote_now; assert(f->linestate == LINE_MACRO); @@ -162,6 +181,7 @@ macro_addnode(struct format *f, struct pnode *n, int f if (n->node == NODE_TEXT || n->node == NODE_ESCAPE) { macro_addarg(f, n->b, flags); + f->parastate = PARA_MID; return; } @@ -191,11 +211,18 @@ macro_addnode(struct format *f, struct pnode *n, int f while (nc != NULL) { macro_addnode(f, nc, flags); + is_text = pnode_class(nc->node) == CLASS_TEXT; nc = TAILQ_NEXT(nc, child); - flags |= ARG_SPACE; + if (nc == NULL || pnode_class(nc->node) != CLASS_TEXT) + is_text = 0; + if (is_text && (nc->flags & NFLAG_SPC) == 0) + flags &= ~ARG_SPACE; + else + flags |= ARG_SPACE; } if (quote_now) putchar('"'); + f->parastate = PARA_MID; } void @@ -212,7 +239,15 @@ macro_nodeline(struct format *f, const char *name, str * line otherwise. The flag ARG_SPACE inserts spaces between words. */ void -print_text(struct format *f, const char *word, int flags) { +print_text(struct format *f, const char *word, int flags) +{ + if (f->parastate == PARA_WANT) { + if (f->linestate != LINE_NEW) { + putchar('\n'); + f->linestate = LINE_NEW; + } + puts(".Pp"); + } switch (f->linestate) { case LINE_NEW: break; @@ -224,8 +259,15 @@ print_text(struct format *f, const char *word, int fla macro_close(f); break; } - fputs(word, stdout); + if (f->linestate == LINE_NEW && (*word == '.' || *word == '\'')) + fputs("\\&", stdout); + while (*word != '\0') { + putchar(*word); + if (*word++ == '\\') + putchar('e'); + } f->linestate = LINE_TEXT; + f->parastate = PARA_MID; f->flags = 0; }