=================================================================== RCS file: /cvs/docbook2mdoc/docbook2mdoc.c,v retrieving revision 1.99 retrieving revision 1.109 diff -u -p -r1.99 -r1.109 --- docbook2mdoc/docbook2mdoc.c 2019/04/07 18:51:53 1.99 +++ docbook2mdoc/docbook2mdoc.c 2019/04/12 10:34:48 1.109 @@ -1,4 +1,4 @@ -/* $Id: docbook2mdoc.c,v 1.99 2019/04/07 18:51:53 schwarze Exp $ */ +/* $Id: docbook2mdoc.c,v 1.109 2019/04/12 10:34:48 schwarze Exp $ */ /* * Copyright (c) 2014 Kristaps Dzonsons * Copyright (c) 2019 Ingo Schwarze @@ -19,6 +19,7 @@ #include #include #include +#include #include "node.h" #include "macro.h" @@ -36,12 +37,31 @@ pnode_printtext(struct format *f, struct pnode *n) { struct pnode *nn; char *cp; - char last; + int accept_arg; - if (n->bsz == 0) { - assert(n->real < n->b); - return; + cp = n->b; + accept_arg = f->flags & FMT_ARG; + if (f->linestate == LINE_MACRO && !n->spc && !accept_arg) { + for (;;) { + if (*cp == '\0') + return; + if (strchr("!),.:;?]", *cp) == NULL) + break; + printf(" %c", *cp++); + } + if (isspace((unsigned char)*cp)) { + while (isspace((unsigned char)*cp)) + cp++; + macro_close(f); + } else { + fputs(" Ns", stdout); + f->flags &= FMT_IMPL; + accept_arg = 1; + } } + if (f->linestate == LINE_MACRO && !accept_arg && + (f->flags & (FMT_CHILD | FMT_IMPL)) == 0) + macro_close(f); /* * Text preceding a macro without intervening whitespace @@ -53,20 +73,34 @@ pnode_printtext(struct format *f, struct pnode *n) (nn = TAILQ_NEXT(n, child)) != NULL && nn->spc == 0 && (nn->node != NODE_TEXT && nn->node != NODE_ESCAPE)) { macro_open(f, "Pf"); + accept_arg = 1; + f->flags |= FMT_CHILD; nn->spc = 1; } - if (f->linestate == LINE_NEW) { - last = '\n'; - f->linestate = LINE_TEXT; - } else { - last = ' '; - if (n->spc || f->linestate == LINE_MACRO) + switch (f->linestate) { + case LINE_NEW: + break; + case LINE_TEXT: + if (n->spc) { + if (n->node == NODE_TEXT) + macro_close(f); + else + putchar(' '); + } + break; + case LINE_MACRO: + if (accept_arg) putchar(' '); + else + macro_close(f); + break; } if (n->node == NODE_ESCAPE) { fputs(n->b, stdout); + if (f->linestate == LINE_NEW) + f->linestate = LINE_TEXT; return; } @@ -75,91 +109,81 @@ pnode_printtext(struct format *f, struct pnode *n) * because the arguments of .Fl macros do not need it. */ - cp = n->b; if (n->parent != NULL && n->parent->node == NODE_OPTION && *cp == '-') cp++; - /* - * Print the text, skipping whitespace on new lines, - * escaping control characters on new lines, - * and escaping backslashes. - */ - - for (; *cp != '\0'; cp++) { - if (last == '\n') { - if (isspace((unsigned char)*cp)) - continue; - if (*cp == '\'' || *cp == '.') - fputs("\\&", stdout); - } - putchar(last = *cp); - if (last == '\\') - putchar('e'); - } + if (f->linestate == LINE_MACRO) + macro_addarg(f, cp, 0); + else + print_text(f, cp, 0); } static void -pnode_printpara(struct format *p, struct pnode *pn) +pnode_printpara(struct format *f, struct pnode *n) { - struct pnode *pp; + struct pnode *np; - if (pn->parent == NULL) + if (n->parent == NULL) return; - if ((pp = TAILQ_PREV(pn, pnodeq, child)) == NULL) - pp = pn->parent; + if ((np = TAILQ_PREV(n, pnodeq, child)) == NULL) + np = n->parent; - switch (pp->node) { + f->flags = 0; + + switch (np->node) { case NODE_ENTRY: case NODE_GLOSSTERM: case NODE_LISTITEM: case NODE_TERM: return; + case NODE_APPENDIX: + case NODE_LEGALNOTICE: case NODE_PREFACE: case NODE_SECTION: - if (p->level < 3) + if (f->level < 3) return; break; default: break; } - macro_line(p, "Pp"); + macro_line(f, "Pp"); } /* * If the SYNOPSIS macro has a superfluous title, kill it. */ static void -pnode_printrefsynopsisdiv(struct format *p, struct pnode *pn) +pnode_printrefsynopsisdiv(struct format *f, struct pnode *n) { - struct pnode *pp, *pq; + struct pnode *nc, *nn; - TAILQ_FOREACH_SAFE(pp, &pn->childq, child, pq) - if (pp->node == NODE_TITLE) - pnode_unlink(pp); + TAILQ_FOREACH_SAFE(nc, &n->childq, child, nn) + if (nc->node == NODE_TITLE) + pnode_unlink(nc); - macro_line(p, "Sh SYNOPSIS"); + macro_line(f, "Sh SYNOPSIS"); } /* * Start a hopefully-named `Sh' section. */ static void -pnode_printrefsect(struct format *p, struct pnode *pn) +pnode_printrefsect(struct format *f, struct pnode *n) { - struct pnode *pp; + struct pnode *nc; const char *title; int flags, level; - if (pn->parent == NULL) + if (n->parent == NULL) return; - level = ++p->level; + level = ++f->level; flags = ARG_SPACE; if (level == 1) flags |= ARG_UPPER; if (level < 3) { - switch (pn->node) { + switch (n->node) { case NODE_CAUTION: case NODE_NOTE: case NODE_TIP: @@ -171,15 +195,21 @@ pnode_printrefsect(struct format *p, struct pnode *pn) } } - TAILQ_FOREACH(pp, &pn->childq, child) - if (pp->node == NODE_TITLE) + TAILQ_FOREACH(nc, &n->childq, child) + if (nc->node == NODE_TITLE) break; - if (pp == NULL) { - switch (pn->node) { + if (nc == NULL) { + switch (n->node) { case NODE_PREFACE: title = "Preface"; break; + case NODE_APPENDIX: + title = "Appendix"; + break; + case NODE_LEGALNOTICE: + title = "Legal Notice"; + break; case NODE_CAUTION: title = "Caution"; break; @@ -200,78 +230,78 @@ pnode_printrefsect(struct format *p, struct pnode *pn) switch (level) { case 1: - macro_close(p); - macro_open(p, "Sh"); + macro_close(f); + macro_open(f, "Sh"); break; case 2: - macro_close(p); - macro_open(p, "Ss"); + macro_close(f); + macro_open(f, "Ss"); break; default: - pnode_printpara(p, pn); - macro_open(p, "Sy"); + pnode_printpara(f, n); + macro_open(f, "Sy"); break; } - if (pp != NULL) { - macro_addnode(p, pp, flags); - pnode_unlink(pp); + if (nc != NULL) { + macro_addnode(f, nc, flags); + pnode_unlink(nc); } else - macro_addarg(p, title, ARG_SPACE | ARG_QUOTED); - macro_close(p); + macro_addarg(f, title, flags | ARG_QUOTED); + macro_close(f); } /* * Start a reference, extracting the title and volume. */ static void -pnode_printciterefentry(struct format *p, struct pnode *pn) +pnode_printciterefentry(struct format *f, struct pnode *n) { - struct pnode *pp, *title, *manvol; + struct pnode *nc, *title, *manvol; title = manvol = NULL; - TAILQ_FOREACH(pp, &pn->childq, child) { - if (pp->node == NODE_MANVOLNUM) - manvol = pp; - else if (pp->node == NODE_REFENTRYTITLE) - title = pp; + TAILQ_FOREACH(nc, &n->childq, child) { + if (nc->node == NODE_MANVOLNUM) + manvol = nc; + else if (nc->node == NODE_REFENTRYTITLE) + title = nc; } - macro_open(p, "Xr"); + macro_open(f, "Xr"); if (title == NULL) - macro_addarg(p, "unknown", ARG_SPACE); + macro_addarg(f, "unknown", ARG_SPACE); else - macro_addnode(p, title, ARG_SPACE | ARG_SINGLE); + macro_addnode(f, title, ARG_SPACE | ARG_SINGLE); if (manvol == NULL) - macro_addarg(p, "1", ARG_SPACE); + macro_addarg(f, "1", ARG_SPACE); else - macro_addnode(p, manvol, ARG_SPACE | ARG_SINGLE); - pnode_unlinksub(pn); + macro_addnode(f, manvol, ARG_SPACE | ARG_SINGLE); + pnode_unlinksub(n); } static void -pnode_printrefmeta(struct format *p, struct pnode *pn) +pnode_printrefmeta(struct format *f, struct pnode *n) { - struct pnode *pp, *title, *manvol; + struct pnode *nc, *title, *manvol; title = manvol = NULL; - TAILQ_FOREACH(pp, &pn->childq, child) { - if (pp->node == NODE_MANVOLNUM) - manvol = pp; - else if (pp->node == NODE_REFENTRYTITLE) - title = pp; + TAILQ_FOREACH(nc, &n->childq, child) { + if (nc->node == NODE_MANVOLNUM) + manvol = nc; + else if (nc->node == NODE_REFENTRYTITLE) + title = nc; } - macro_close(p); - macro_open(p, "Dt"); + macro_close(f); + macro_open(f, "Dt"); if (title == NULL) - macro_addarg(p, "UNKNOWN", ARG_SPACE); + macro_addarg(f, "UNKNOWN", ARG_SPACE); else - macro_addnode(p, title, ARG_SPACE | ARG_SINGLE | ARG_UPPER); + macro_addnode(f, title, ARG_SPACE | ARG_SINGLE | ARG_UPPER); if (manvol == NULL) - macro_addarg(p, "1", ARG_SPACE); + macro_addarg(f, "1", ARG_SPACE); else - macro_addnode(p, manvol, ARG_SPACE | ARG_SINGLE); - macro_close(p); - pnode_unlink(pn); + macro_addnode(f, manvol, ARG_SPACE | ARG_SINGLE); + macro_close(f); + pnode_unlink(n); } static void @@ -295,21 +325,21 @@ pnode_printfuncdef(struct format *f, struct pnode *n) * Second, >1 arguments are separated by commas. */ static void -pnode_printmathfenced(struct format *p, struct pnode *pn) +pnode_printmathfenced(struct format *f, struct pnode *n) { - struct pnode *pp; + struct pnode *nc; - printf("left %s ", pnode_getattr_raw(pn, ATTRKEY_OPEN, "(")); + printf("left %s ", pnode_getattr_raw(n, ATTRKEY_OPEN, "(")); - pp = TAILQ_FIRST(&pn->childq); - pnode_print(p, pp); + nc = TAILQ_FIRST(&n->childq); + pnode_print(f, nc); - while ((pp = TAILQ_NEXT(pp, child)) != NULL) { + while ((nc = TAILQ_NEXT(nc, child)) != NULL) { putchar(','); - pnode_print(p, pp); + pnode_print(f, nc); } - printf("right %s ", pnode_getattr_raw(pn, ATTRKEY_CLOSE, ")")); - pnode_unlinksub(pn); + printf("right %s ", pnode_getattr_raw(n, ATTRKEY_CLOSE, ")")); + pnode_unlinksub(n); } /* @@ -319,14 +349,14 @@ pnode_printmathfenced(struct format *p, struct pnode * * particular eqn(7) word. */ static void -pnode_printmath(struct format *p, struct pnode *pn) +pnode_printmath(struct format *f, struct pnode *n) { - struct pnode *pp; + struct pnode *nc; - pp = TAILQ_FIRST(&pn->childq); - pnode_print(p, pp); + nc = TAILQ_FIRST(&n->childq); + pnode_print(f, nc); - switch (pn->node) { + switch (n->node) { case NODE_MML_MSUP: fputs(" sup ", stdout); break; @@ -340,31 +370,31 @@ pnode_printmath(struct format *p, struct pnode *pn) break; } - pp = TAILQ_NEXT(pp, child); - pnode_print(p, pp); - pnode_unlinksub(pn); + nc = TAILQ_NEXT(nc, child); + pnode_print(f, nc); + pnode_unlinksub(n); } static void -pnode_printfuncprototype(struct format *p, struct pnode *pn) +pnode_printfuncprototype(struct format *f, struct pnode *n) { - struct pnode *pp, *fdef; + struct pnode *nc, *fdef; - TAILQ_FOREACH(fdef, &pn->childq, child) + TAILQ_FOREACH(fdef, &n->childq, child) if (fdef->node == NODE_FUNCDEF) break; if (fdef != NULL) { - pnode_printfuncdef(p, fdef); + pnode_printfuncdef(f, fdef); pnode_unlink(fdef); } else - macro_line(p, "Fo UNKNOWN"); + macro_line(f, "Fo UNKNOWN"); - TAILQ_FOREACH(pp, &pn->childq, child) - macro_nodeline(p, "Fa", pp, ARG_SINGLE); + TAILQ_FOREACH(nc, &n->childq, child) + macro_nodeline(f, "Fa", nc, ARG_SINGLE); - macro_line(p, "Fc"); - pnode_unlinksub(pn); + macro_line(f, "Fc"); + pnode_unlinksub(n); } /* @@ -375,45 +405,58 @@ pnode_printfuncprototype(struct format *p, struct pnod * ellipsis following an argument) and optionality. */ static void -pnode_printarg(struct format *p, struct pnode *pn) +pnode_printarg(struct format *f, struct pnode *n) { - struct pnode *pp; - struct pattr *ap; - int isop, isrep; + struct pnode *nc; + struct pattr *a; + int isop, isrep, was_impl; isop = 1; - isrep = 0; - TAILQ_FOREACH(ap, &pn->attrq, child) { - if (ap->key == ATTRKEY_CHOICE && - (ap->val == ATTRVAL_PLAIN || ap->val == ATTRVAL_REQ)) + isrep = was_impl = 0; + TAILQ_FOREACH(a, &n->attrq, child) { + if (a->key == ATTRKEY_CHOICE && + (a->val == ATTRVAL_PLAIN || a->val == ATTRVAL_REQ)) isop = 0; - else if (ap->key == ATTRKEY_REP && ap->val == ATTRVAL_REPEAT) + else if (a->key == ATTRKEY_REP && a->val == ATTRVAL_REPEAT) isrep = 1; } - if (isop) - macro_open(p, "Op"); + if (isop) { + if (f->flags & FMT_IMPL) { + was_impl = 1; + macro_open(f, "Oo"); + } else { + macro_open(f, "Op"); + f->flags |= FMT_IMPL; + } + } - TAILQ_FOREACH(pp, &pn->childq, child) { - if (pp->node == NODE_TEXT) - macro_open(p, "Ar"); - pnode_print(p, pp); - if (isrep && pp->node == NODE_TEXT) - macro_addarg(p, "...", ARG_SPACE); + TAILQ_FOREACH(nc, &n->childq, child) { + if (nc->node == NODE_TEXT) + macro_open(f, "Ar"); + pnode_print(f, nc); + if (isrep && nc->node == NODE_TEXT) + macro_addarg(f, "...", ARG_SPACE); } - pnode_unlinksub(pn); + if (isop) { + if (was_impl) + macro_open(f, "Oc"); + else + f->flags &= ~FMT_IMPL; + } + pnode_unlinksub(n); } static void -pnode_printgroup(struct format *p, struct pnode *pn) +pnode_printgroup(struct format *f, struct pnode *n) { - struct pnode *pp, *np; - struct pattr *ap; + struct pnode *nc, *nn; + struct pattr *a; int isop, sv; isop = 1; - TAILQ_FOREACH(ap, &pn->attrq, child) - if (ap->key == ATTRKEY_CHOICE && - (ap->val == ATTRVAL_PLAIN || ap->val == ATTRVAL_REQ)) { + TAILQ_FOREACH(a, &n->attrq, child) + if (a->key == ATTRKEY_CHOICE && + (a->val == ATTRVAL_PLAIN || a->val == ATTRVAL_REQ)) { isop = 0; break; } @@ -423,11 +466,12 @@ pnode_printgroup(struct format *p, struct pnode *pn) * This will prevent pnode_print() for putting us on a * subsequent line. */ - sv = p->linestate == LINE_NEW; + sv = f->linestate == LINE_NEW; if (isop) - macro_open(p, "Op"); + macro_open(f, "Op"); else if (sv) - macro_open(p, "No"); + macro_open(f, "No"); + f->flags |= FMT_IMPL; /* * Keep on printing text separated by the vertical bar as long @@ -437,27 +481,28 @@ pnode_printgroup(struct format *p, struct pnode *pn) * FIXME: if there's a "Fl", we don't cut off the leading "-" * like we do in pnode_print(). */ - TAILQ_FOREACH(pp, &pn->childq, child) { - pnode_print(p, pp); - np = TAILQ_NEXT(pp, child); - while (np != NULL) { - if (pp->node != np->node) + TAILQ_FOREACH(nc, &n->childq, child) { + pnode_print(f, nc); + nn = TAILQ_NEXT(nc, child); + while (nn != NULL) { + if (nc->node != nn->node) break; - macro_addarg(p, "|", ARG_SPACE); - macro_addnode(p, np, ARG_SPACE); - pp = np; - np = TAILQ_NEXT(np, child); + macro_addarg(f, "|", ARG_SPACE); + macro_addnode(f, nn, ARG_SPACE); + nc = nn; + nn = TAILQ_NEXT(nn, child); } } if (sv) - macro_close(p); - pnode_unlinksub(pn); + macro_close(f); + f->flags &= ~FMT_IMPL; + pnode_unlinksub(n); } static void pnode_printauthor(struct format *f, struct pnode *n) { - struct pnode *nc, *ncn; + struct pnode *nc, *nn; int have_contrib, have_name; /* @@ -466,7 +511,7 @@ pnode_printauthor(struct format *f, struct pnode *n) */ have_contrib = have_name = 0; - TAILQ_FOREACH_SAFE(nc, &n->childq, child, ncn) { + TAILQ_FOREACH_SAFE(nc, &n->childq, child, nn) { switch (nc->node) { case NODE_CONTRIB: if (have_contrib) @@ -495,7 +540,7 @@ pnode_printauthor(struct format *f, struct pnode *n) */ macro_open(f, "An"); - TAILQ_FOREACH_SAFE(nc, &n->childq, child, ncn) { + TAILQ_FOREACH_SAFE(nc, &n->childq, child, nn) { if (nc->node == NODE_PERSONNAME || have_name == 0) { macro_addnode(f, nc, ARG_SPACE); pnode_unlink(nc); @@ -508,6 +553,7 @@ pnode_printauthor(struct format *f, struct pnode *n) */ if ((nc = pnode_findfirst(n, NODE_EMAIL)) != NULL) { + f->flags |= FMT_CHILD; pnode_print(f, nc); pnode_unlink(nc); } @@ -527,22 +573,34 @@ pnode_printauthor(struct format *f, struct pnode *n) static void pnode_printlink(struct format *f, struct pnode *n) { + struct pnode *nc; const char *uri, *text; uri = pnode_getattr_raw(n, ATTRKEY_LINKEND, NULL); if (uri != NULL) { if (TAILQ_FIRST(&n->childq) != NULL) { - print_textnode(f, n); + TAILQ_FOREACH(nc, &n->childq, child) + pnode_print(f, nc); text = ""; - } else { - text = pnode_getattr_raw(n, ATTRKEY_ENDTERM, NULL); - if (text != NULL) + } else if ((text = pnode_getattr_raw(n, + ATTRKEY_ENDTERM, NULL)) != NULL) { + if (f->linestate == LINE_MACRO && f->flags & FMT_ARG) + macro_addarg(f, text, ARG_SPACE); + else print_text(f, text, ARG_SPACE); } - if (text != NULL) - macro_open(f, "Pq"); + if (text != NULL) { + if (f->flags & FMT_IMPL) + macro_open(f, "Po"); + else { + macro_open(f, "Pq"); + f->flags |= FMT_CHILD; + } + } macro_open(f, "Sx"); macro_addarg(f, uri, ARG_SPACE); + if (text != NULL && f->flags & FMT_IMPL) + macro_open(f, "Pc"); pnode_unlinksub(n); return; } @@ -560,29 +618,29 @@ pnode_printlink(struct format *f, struct pnode *n) } static void -pnode_printprologue(struct format *p, struct ptree *tree) +pnode_printprologue(struct format *f, struct ptree *tree) { struct pnode *refmeta; refmeta = tree->root == NULL ? NULL : pnode_findfirst(tree->root, NODE_REFMETA); - macro_line(p, "Dd $Mdocdate" "$"); + macro_line(f, "Dd $Mdocdate" "$"); if (refmeta == NULL) { - macro_open(p, "Dt"); - macro_addarg(p, + macro_open(f, "Dt"); + macro_addarg(f, pnode_getattr_raw(tree->root, ATTRKEY_ID, "UNKNOWN"), ARG_SPACE | ARG_SINGLE | ARG_UPPER); - macro_addarg(p, "1", ARG_SPACE); - macro_close(p); + macro_addarg(f, "1", ARG_SPACE); + macro_close(f); } else - pnode_printrefmeta(p, refmeta); - macro_line(p, "Os"); + pnode_printrefmeta(f, refmeta); + macro_line(f, "Os"); if (tree->flags & TREE_EQN) { - macro_line(p, "EQ"); - print_text(p, "delim $$", 0); - macro_line(p, "EN"); + macro_line(f, "EQ"); + print_text(f, "delim $$", 0); + macro_line(f, "EN"); } } @@ -591,54 +649,66 @@ pnode_printprologue(struct format *p, struct ptree *tr * we should comma-separate as list headers. */ static void -pnode_printvarlistentry(struct format *p, struct pnode *pn) +pnode_printvarlistentry(struct format *f, struct pnode *n) { - struct pnode *pp; + struct pnode *nc, *nn; int first = 1; - macro_close(p); - macro_open(p, "It"); - TAILQ_FOREACH(pp, &pn->childq, child) { - if (pp->node != NODE_TERM && pp->node != NODE_GLOSSTERM) + macro_open(f, "It"); + f->flags |= FMT_IMPL; + TAILQ_FOREACH_SAFE(nc, &n->childq, child, nn) { + if (nc->node != NODE_TERM && nc->node != NODE_GLOSSTERM) continue; - if ( ! first) - macro_addarg(p, ",", 0); - pnode_print(p, pp); + if (first == 0) { + switch (f->linestate) { + case LINE_NEW: + break; + case LINE_TEXT: + print_text(f, ",", 0); + break; + case LINE_MACRO: + macro_addarg(f, ",", 0); + break; + } + } + pnode_print(f, nc); + pnode_unlink(nc); first = 0; } - macro_close(p); - TAILQ_FOREACH(pp, &pn->childq, child) - if (pp->node != NODE_TERM && pp->node != NODE_GLOSSTERM) - pnode_print(p, pp); - pnode_unlinksub(pn); + macro_close(f); + while ((nc = TAILQ_FIRST(&n->childq)) != NULL) { + pnode_print(f, nc); + pnode_unlink(nc); + } + macro_close(f); } static void -pnode_printtitle(struct format *p, struct pnode *pn) +pnode_printtitle(struct format *f, struct pnode *n) { - struct pnode *pp, *pq; + struct pnode *nc, *nn; - TAILQ_FOREACH_SAFE(pp, &pn->childq, child, pq) { - if (pp->node == NODE_TITLE) { - pnode_printpara(p, pp); - pnode_print(p, pp); - pnode_unlink(pp); + TAILQ_FOREACH_SAFE(nc, &n->childq, child, nn) { + if (nc->node == NODE_TITLE) { + pnode_printpara(f, nc); + pnode_print(f, nc); + pnode_unlink(nc); } } } static void -pnode_printrow(struct format *p, struct pnode *pn) +pnode_printrow(struct format *f, struct pnode *n) { - struct pnode *pp; + struct pnode *nc; - macro_line(p, "Bl -dash -compact"); - TAILQ_FOREACH(pp, &pn->childq, child) { - macro_line(p, "It"); - pnode_print(p, pp); + macro_line(f, "Bl -dash -compact"); + TAILQ_FOREACH(nc, &n->childq, child) { + macro_line(f, "It"); + pnode_print(f, nc); } - macro_line(p, "El"); - pnode_unlink(pn); + macro_line(f, "El"); + pnode_unlink(n); } static void @@ -665,8 +735,8 @@ pnode_printtgroup2(struct format *f, struct pnode *n) while ((nr = pnode_findfirst(n, NODE_ROW)) != NULL) { if ((ne = pnode_findfirst(n, NODE_ENTRY)) == NULL) break; - macro_close(f); macro_open(f, "It"); + f->flags |= FMT_IMPL; pnode_print(f, ne); macro_close(f); pnode_unlink(ne); @@ -703,36 +773,36 @@ pnode_printtgroup(struct format *f, struct pnode *n) } static void -pnode_printlist(struct format *p, struct pnode *pn) +pnode_printlist(struct format *f, struct pnode *n) { - struct pnode *pp; + struct pnode *nc; - pnode_printtitle(p, pn); - macro_argline(p, "Bl", - pn->node == NODE_ORDEREDLIST ? "-enum" : "-bullet"); - TAILQ_FOREACH(pp, &pn->childq, child) { - macro_line(p, "It"); - pnode_print(p, pp); + pnode_printtitle(f, n); + macro_argline(f, "Bl", + n->node == NODE_ORDEREDLIST ? "-enum" : "-bullet"); + TAILQ_FOREACH(nc, &n->childq, child) { + macro_line(f, "It"); + pnode_print(f, nc); } - macro_line(p, "El"); - pnode_unlinksub(pn); + macro_line(f, "El"); + pnode_unlinksub(n); } static void -pnode_printvariablelist(struct format *p, struct pnode *pn) +pnode_printvariablelist(struct format *f, struct pnode *n) { - struct pnode *pp; + struct pnode *nc; - pnode_printtitle(p, pn); - macro_line(p, "Bl -tag -width Ds"); - TAILQ_FOREACH(pp, &pn->childq, child) { - if (pp->node == NODE_VARLISTENTRY) - pnode_printvarlistentry(p, pp); + pnode_printtitle(f, n); + macro_line(f, "Bl -tag -width Ds"); + TAILQ_FOREACH(nc, &n->childq, child) { + if (nc->node == NODE_VARLISTENTRY) + pnode_printvarlistentry(f, nc); else - macro_nodeline(p, "It", pp, 0); + macro_nodeline(f, "It", nc, 0); } - macro_line(p, "El"); - pnode_unlinksub(pn); + macro_line(f, "El"); + pnode_unlinksub(n); } /* @@ -742,238 +812,247 @@ pnode_printvariablelist(struct format *p, struct pnode * whatever), don't print inline macros. */ static void -pnode_print(struct format *p, struct pnode *pn) +pnode_print(struct format *f, struct pnode *n) { - struct pnode *pp; + struct pnode *nc, *nn; enum linestate sv; - if (pn == NULL) + if (n == NULL) return; - p->spc = pn->spc; - sv = p->linestate; + sv = f->linestate; + if (n->spc) + f->flags &= ~FMT_NOSPC; + else + f->flags |= FMT_NOSPC; - switch (pn->node) { + switch (n->node) { case NODE_APPLICATION: - macro_open(p, "Nm"); + macro_open(f, "Nm"); break; case NODE_ARG: - pnode_printarg(p, pn); + pnode_printarg(f, n); break; case NODE_AUTHOR: - pnode_printauthor(p, pn); + pnode_printauthor(f, n); break; case NODE_AUTHORGROUP: - macro_line(p, "An -split"); + macro_line(f, "An -split"); break; case NODE_BLOCKQUOTE: - macro_line(p, "Bd -ragged -offset indent"); + macro_line(f, "Bd -ragged -offset indent"); break; case NODE_BOOKINFO: - macro_line(p, "Sh NAME"); + macro_line(f, "Sh NAME"); break; case NODE_CITEREFENTRY: - pnode_printciterefentry(p, pn); + pnode_printciterefentry(f, n); break; case NODE_CITETITLE: - macro_open(p, "%T"); + macro_open(f, "%T"); break; case NODE_COMMAND: - macro_open(p, "Nm"); + macro_open(f, "Nm"); break; case NODE_CONSTANT: - macro_open(p, "Dv"); + macro_open(f, "Dv"); break; case NODE_EDITOR: - print_text(p, "editor:", ARG_SPACE); + print_text(f, "editor:", ARG_SPACE); sv = LINE_TEXT; - macro_open(p, "An"); + macro_open(f, "An"); break; case NODE_EMAIL: - macro_open(p, "Aq Mt"); + macro_open(f, "Aq Mt"); break; case NODE_EMPHASIS: case NODE_FIRSTTERM: case NODE_GLOSSTERM: - macro_open(p, "Em"); + macro_open(f, "Em"); break; case NODE_ENVAR: - macro_open(p, "Ev"); + macro_open(f, "Ev"); break; case NODE_ERRORNAME: - macro_open(p, "Er"); + macro_open(f, "Er"); break; case NODE_FILENAME: - macro_open(p, "Pa"); + macro_open(f, "Pa"); break; case NODE_FUNCTION: - macro_open(p, "Fn"); + macro_open(f, "Fn"); break; case NODE_FUNCPROTOTYPE: - pnode_printfuncprototype(p, pn); + pnode_printfuncprototype(f, n); break; case NODE_FUNCSYNOPSISINFO: - macro_open(p, "Fd"); + macro_open(f, "Fd"); break; case NODE_INFORMALEQUATION: - macro_line(p, "EQ"); + macro_line(f, "EQ"); break; case NODE_INLINEEQUATION: - if (p->linestate == LINE_NEW) - p->linestate = LINE_TEXT; + if (f->linestate == LINE_NEW) + f->linestate = LINE_TEXT; putchar('$'); break; case NODE_ITEMIZEDLIST: - pnode_printlist(p, pn); + pnode_printlist(f, n); break; case NODE_GROUP: - pnode_printgroup(p, pn); + pnode_printgroup(f, n); break; case NODE_KEYSYM: - macro_open(p, "Sy"); + macro_open(f, "Sy"); break; - case NODE_LEGALNOTICE: - macro_line(p, "Sh LEGAL NOTICE"); - break; case NODE_LINK: - pnode_printlink(p, pn); + pnode_printlink(f, n); break; case NODE_LITERAL: - macro_open(p, "Ql"); + macro_open(f, "Ql"); break; case NODE_LITERALLAYOUT: - macro_close(p); - macro_argline(p, "Bd", pnode_getattr(pn, ATTRKEY_CLASS) == + macro_close(f); + macro_argline(f, "Bd", pnode_getattr(n, ATTRKEY_CLASS) == ATTRVAL_MONOSPACED ? "-literal" : "-unfilled"); break; + case NODE_MARKUP: + macro_open(f, "Ic"); + break; case NODE_MML_MFENCED: - pnode_printmathfenced(p, pn); + pnode_printmathfenced(f, n); break; case NODE_MML_MROW: case NODE_MML_MI: case NODE_MML_MN: case NODE_MML_MO: - if (TAILQ_EMPTY(&pn->childq)) + if (TAILQ_EMPTY(&n->childq)) break; fputs(" { ", stdout); break; case NODE_MML_MFRAC: case NODE_MML_MSUB: case NODE_MML_MSUP: - pnode_printmath(p, pn); + pnode_printmath(f, n); break; case NODE_OPTION: - macro_open(p, "Fl"); + macro_open(f, "Fl"); break; case NODE_ORDEREDLIST: - pnode_printlist(p, pn); + pnode_printlist(f, n); break; case NODE_PARA: - pnode_printpara(p, pn); + pnode_printpara(f, n); break; case NODE_PARAMDEF: case NODE_PARAMETER: - macro_nodeline(p, "Fa", pn, ARG_SINGLE); - pnode_unlinksub(pn); + /* More often, these appear inside NODE_FUNCPROTOTYPE. */ + macro_open(f, "Fa"); + macro_addnode(f, n, ARG_SPACE | ARG_SINGLE); + pnode_unlinksub(n); break; case NODE_QUOTE: - macro_open(p, "Qo"); + macro_open(f, "Qo"); break; case NODE_PROGRAMLISTING: case NODE_SCREEN: case NODE_SYNOPSIS: - macro_line(p, "Bd -literal"); + macro_line(f, "Bd -literal"); break; case NODE_REFENTRYINFO: /* Suppress. */ - pnode_unlinksub(pn); + pnode_unlinksub(n); break; case NODE_REFNAME: /* Suppress non-text children... */ - macro_open(p, "Nm"); - macro_addnode(p, pn, ARG_SPACE | ARG_SINGLE); - pnode_unlinksub(pn); + macro_open(f, "Nm"); + macro_addnode(f, n, ARG_SPACE | ARG_SINGLE); + pnode_unlinksub(n); break; case NODE_REFNAMEDIV: - macro_line(p, "Sh NAME"); + macro_line(f, "Sh NAME"); break; case NODE_REFPURPOSE: - macro_open(p, "Nd"); + macro_open(f, "Nd"); break; case NODE_REFSYNOPSISDIV: - pnode_printrefsynopsisdiv(p, pn); + pnode_printrefsynopsisdiv(f, n); break; case NODE_PREFACE: case NODE_SECTION: + case NODE_APPENDIX: + case NODE_LEGALNOTICE: case NODE_NOTE: case NODE_TIP: case NODE_CAUTION: case NODE_WARNING: - pnode_printrefsect(p, pn); + pnode_printrefsect(f, n); break; case NODE_REPLACEABLE: - macro_open(p, "Ar"); + macro_open(f, "Ar"); break; case NODE_SBR: - macro_line(p, "br"); + macro_line(f, "br"); break; - case NODE_SGMLTAG: - macro_open(p, "Ic"); - break; case NODE_TEXT: case NODE_ESCAPE: - pnode_printtext(p, pn); + pnode_printtext(f, n); break; case NODE_TGROUP: - pnode_printtgroup(p, pn); + pnode_printtgroup(f, n); break; case NODE_TITLE: - if (pn->parent != NULL && - pn->parent->node == NODE_BOOKINFO) { - macro_open(p, "Nd"); + if (n->parent != NULL && + n->parent->node == NODE_BOOKINFO) { + macro_open(f, "Nd"); break; } - pnode_printpara(p, pn); - macro_nodeline(p, "Sy", pn, 0); - pnode_unlinksub(pn); + pnode_printpara(f, n); + macro_nodeline(f, "Sy", n, 0); + pnode_unlinksub(n); break; case NODE_TYPE: - macro_open(p, "Vt"); + macro_open(f, "Vt"); break; case NODE_VARIABLELIST: - pnode_printvariablelist(p, pn); + pnode_printvariablelist(f, n); break; case NODE_VARNAME: - macro_open(p, "Va"); + macro_open(f, "Va"); break; default: break; } - TAILQ_FOREACH(pp, &pn->childq, child) - pnode_print(p, pp); + TAILQ_FOREACH(nc, &n->childq, child) + pnode_print(f, nc); - switch (pn->node) { + switch (n->node) { + case NODE_ESCAPE: + case NODE_TERM: + case NODE_TEXT: + /* Accept more arguments to the previous macro. */ + return; case NODE_INFORMALEQUATION: - macro_line(p, "EN"); + macro_line(f, "EN"); break; case NODE_INLINEEQUATION: fputs("$ ", stdout); - p->linestate = sv; + f->linestate = sv; break; case NODE_MEMBER: - if ((pp = TAILQ_NEXT(pn, child)) != NULL && - pp->node != NODE_MEMBER) - pp = NULL; - switch (p->linestate) { + if ((nn = TAILQ_NEXT(n, child)) != NULL && + nn->node != NODE_MEMBER) + nn = NULL; + switch (f->linestate) { case LINE_TEXT: - if (pp != NULL) - print_text(p, ",", 0); + if (nn != NULL) + print_text(f, ",", 0); break; case LINE_MACRO: - if (pp != NULL) - macro_addarg(p, ",", ARG_SPACE); - macro_close(p); + if (nn != NULL) + macro_addarg(f, ",", ARG_SPACE); + macro_close(f); break; case LINE_NEW: break; @@ -983,47 +1062,17 @@ pnode_print(struct format *p, struct pnode *pn) case NODE_MML_MI: case NODE_MML_MN: case NODE_MML_MO: - if (TAILQ_EMPTY(&pn->childq)) + if (TAILQ_EMPTY(&n->childq)) break; fputs(" } ", stdout); break; - case NODE_APPLICATION: - case NODE_ARG: - case NODE_AUTHOR: - case NODE_CITEREFENTRY: - case NODE_CITETITLE: - case NODE_COMMAND: - case NODE_CONSTANT: - case NODE_EDITOR: - case NODE_EMAIL: - case NODE_EMPHASIS: - case NODE_ENVAR: - case NODE_ERRORNAME: - case NODE_FILENAME: - case NODE_FIRSTTERM: - case NODE_FUNCTION: - case NODE_FUNCSYNOPSISINFO: - case NODE_KEYSYM: - case NODE_LINK: - case NODE_LITERAL: - case NODE_OPTION: - case NODE_PARAMETER: - case NODE_REPLACEABLE: - case NODE_REFPURPOSE: - case NODE_SGMLTAG: - case NODE_TYPE: - case NODE_VARNAME: - if (sv != LINE_MACRO && p->linestate == LINE_MACRO && - (pn->parent == NULL || pn->parent->node != NODE_MEMBER)) - macro_closepunct(p, pn); - break; case NODE_QUOTE: if (sv == LINE_NEW) - macro_close(p); - sv = p->linestate; - macro_open(p, "Qc"); + macro_close(f); + sv = f->linestate; + macro_open(f, "Qc"); if (sv == LINE_NEW) - macro_close(p); + macro_close(f); break; case NODE_REFNAME: /* @@ -1031,37 +1080,40 @@ pnode_print(struct format *p, struct pnode *pn) * macros in sequence, then print out a * trailing comma before the newline. */ - if (pn->parent != NULL && - pn->parent->node == NODE_REFNAMEDIV && - TAILQ_NEXT(pn, child) != NULL && - TAILQ_NEXT(pn, child)->node == NODE_REFNAME) - macro_addarg(p, ",", ARG_SPACE); + if (n->parent != NULL && + n->parent->node == NODE_REFNAMEDIV && + TAILQ_NEXT(n, child) != NULL && + TAILQ_NEXT(n, child)->node == NODE_REFNAME) + macro_addarg(f, ",", ARG_SPACE); if (sv == LINE_NEW) - macro_close(p); + macro_close(f); break; case NODE_PREFACE: case NODE_SECTION: + case NODE_APPENDIX: + case NODE_LEGALNOTICE: case NODE_NOTE: case NODE_TIP: case NODE_CAUTION: case NODE_WARNING: - p->level--; + f->level--; break; case NODE_BLOCKQUOTE: case NODE_LITERALLAYOUT: case NODE_PROGRAMLISTING: case NODE_SCREEN: case NODE_SYNOPSIS: - macro_line(p, "Ed"); + macro_line(f, "Ed"); break; case NODE_TITLE: - if (pn->parent != NULL && - pn->parent->node == NODE_BOOKINFO) - macro_line(p, "Sh AUTHORS"); + if (n->parent != NULL && + n->parent->node == NODE_BOOKINFO) + macro_line(f, "Sh AUTHORS"); break; default: break; } + f->flags &= ~FMT_ARG; } void