=================================================================== RCS file: /cvs/docbook2mdoc/docbook2mdoc.c,v retrieving revision 1.77 retrieving revision 1.85 diff -u -p -r1.77 -r1.85 --- docbook2mdoc/docbook2mdoc.c 2019/03/26 22:39:33 1.77 +++ docbook2mdoc/docbook2mdoc.c 2019/04/03 14:02:07 1.85 @@ -1,4 +1,4 @@ -/* $Id: docbook2mdoc.c,v 1.77 2019/03/26 22:39:33 schwarze Exp $ */ +/* $Id: docbook2mdoc.c,v 1.85 2019/04/03 14:02:07 schwarze Exp $ */ /* * Copyright (c) 2014 Kristaps Dzonsons * Copyright (c) 2019 Ingo Schwarze @@ -32,23 +32,6 @@ static void pnode_print(struct format *, struct pnode static void -print_text(struct format *p, const char *word) -{ - switch (p->linestate) { - case LINE_NEW: - break; - case LINE_TEXT: - putchar(' '); - break; - case LINE_MACRO: - macro_close(p); - break; - } - fputs(word, stdout); - p->linestate = LINE_TEXT; -} - -static void pnode_printpara(struct format *p, struct pnode *pn) { struct pnode *pp; @@ -189,7 +172,6 @@ pnode_printciterefentry(struct format *p, struct pnode macro_addarg(p, "1", ARG_SPACE); else macro_addnode(p, manvol, ARG_SPACE | ARG_SINGLE); - macro_close(p); pnode_unlinksub(pn); } @@ -407,6 +389,76 @@ pnode_printgroup(struct format *p, struct pnode *pn) } static void +pnode_printauthor(struct format *f, struct pnode *n) +{ + struct pnode *nc, *ncn; + int have_contrib, have_name; + + /* + * Print children up front, before the .An scope, + * and figure out whether we a name of a person. + */ + + have_contrib = have_name = 0; + TAILQ_FOREACH_SAFE(nc, &n->childq, child, ncn) { + switch (nc->node) { + case NODE_CONTRIB: + if (have_contrib) + print_text(f, ",", 0); + print_textnode(f, nc); + pnode_unlink(nc); + have_contrib = 1; + break; + case NODE_PERSONNAME: + have_name = 1; + break; + default: + break; + } + } + if (TAILQ_FIRST(&n->childq) == NULL) + return; + + if (have_contrib) + print_text(f, ":", 0); + + /* + * If we have a name, print it in the .An scope and leave + * all other content for child handlers, to print after the + * scope. Otherwise, print everything in the scope. + */ + + macro_open(f, "An"); + TAILQ_FOREACH_SAFE(nc, &n->childq, child, ncn) { + if (nc->node == NODE_PERSONNAME || have_name == 0) { + macro_addnode(f, nc, ARG_SPACE); + pnode_unlink(nc); + } + } + + /* + * If there is an email address, + * print it on the same macro line. + */ + + if ((nc = pnode_findfirst(n, NODE_EMAIL)) != NULL) { + pnode_print(f, nc); + pnode_unlink(nc); + } + + /* + * If there are still unprinted children, end the scope + * with a comma. Otherwise, leave the scope open in case + * a text node follows that starts with closing punctuation. + */ + + if (TAILQ_FIRST(&n->childq) != NULL) { + macro_addarg(f, ",", ARG_SPACE); + macro_close(f); + } +} + +static void pnode_printprologue(struct format *p, struct ptree *tree) { struct pnode *refmeta; @@ -428,7 +480,7 @@ pnode_printprologue(struct format *p, struct ptree *tr if (tree->flags & TREE_EQN) { macro_line(p, "EQ"); - print_text(p, "delim $$"); + print_text(p, "delim $$", 0); macro_line(p, "EN"); } } @@ -488,21 +540,66 @@ pnode_printrow(struct format *p, struct pnode *pn) } static void -pnode_printtable(struct format *p, struct pnode *pn) +pnode_printtgroup1(struct format *f, struct pnode *n) { - struct pnode *pp; + struct pnode *nc; - pnode_printtitle(p, pn); - macro_line(p, "Bl -ohang"); - while ((pp = pnode_findfirst(pn, NODE_ROW)) != NULL) { - macro_line(p, "It Table Row"); - pnode_printrow(p, pp); + macro_line(f, "Bl -bullet -compact"); + while ((nc = pnode_findfirst(n, NODE_ENTRY)) != NULL) { + macro_line(f, "It"); + pnode_print(f, nc); + pnode_unlink(nc); } - macro_line(p, "El"); - pnode_unlinksub(pn); + macro_line(f, "El"); + pnode_unlinksub(n); } static void +pnode_printtgroup2(struct format *f, struct pnode *n) +{ + struct pnode *nr, *ne; + + macro_line(f, "Bl -tag -width Ds"); + while ((nr = pnode_findfirst(n, NODE_ROW)) != NULL) { + if ((ne = pnode_findfirst(n, NODE_ENTRY)) == NULL) + break; + macro_open(f, "It"); + pnode_print(f, ne); + macro_close(f); + pnode_unlink(ne); + pnode_print(f, nr); + pnode_unlink(nr); + } + macro_line(f, "El"); + pnode_unlinksub(n); +} + +static void +pnode_printtgroup(struct format *f, struct pnode *n) +{ + struct pnode *nc; + + switch (atoi(pnode_getattr_raw(n, ATTRKEY_COLS, "0"))) { + case 1: + pnode_printtgroup1(f, n); + return; + case 2: + pnode_printtgroup2(f, n); + return; + default: + break; + } + + macro_line(f, "Bl -ohang"); + while ((nc = pnode_findfirst(n, NODE_ROW)) != NULL) { + macro_line(f, "It Table Row"); + pnode_printrow(f, nc); + } + macro_line(f, "El"); + pnode_unlinksub(n); +} + +static void pnode_printlist(struct format *p, struct pnode *pn) { struct pnode *pp; @@ -527,7 +624,7 @@ pnode_printvariablelist(struct format *p, struct pnode macro_line(p, "Bl -tag -width Ds"); TAILQ_FOREACH(pp, &pn->childq, child) { if (pp->node == NODE_VARLISTENTRY) - pnode_print(p, pp); + pnode_printvarlistentry(p, pp); else macro_nodeline(p, "It", pp, 0); } @@ -563,7 +660,7 @@ pnode_print(struct format *p, struct pnode *pn) pnode_printarg(p, pn); break; case NODE_AUTHOR: - macro_open(p, "An"); + pnode_printauthor(p, pn); break; case NODE_AUTHORGROUP: macro_line(p, "An -split"); @@ -587,7 +684,7 @@ pnode_print(struct format *p, struct pnode *pn) macro_open(p, "Dv"); break; case NODE_EDITOR: - print_text(p, "editor:"); + print_text(p, "editor:", ARG_SPACE); macro_open(p, "An"); break; case NODE_EMAIL: @@ -600,6 +697,13 @@ pnode_print(struct format *p, struct pnode *pn) case NODE_ENVAR: macro_open(p, "Ev"); break; + case NODE_ESCAPE: + if (p->linestate == LINE_NEW) + p->linestate = LINE_TEXT; + else + putchar(' '); + fputs(pn->b, stdout); + break; case NODE_FILENAME: macro_open(p, "Pa"); break; @@ -723,10 +827,6 @@ pnode_print(struct format *p, struct pnode *pn) case NODE_STRUCTNAME: macro_open(p, "Vt"); break; - case NODE_TABLE: - case NODE_INFORMALTABLE: - pnode_printtable(p, pn); - break; case NODE_TEXT: if (pn->bsz == 0) { assert(pn->real != pn->b); @@ -770,9 +870,17 @@ pnode_print(struct format *p, struct pnode *pn) putchar('e'); } break; + case NODE_TGROUP: + pnode_printtgroup(p, pn); + break; case NODE_TITLE: - if (pn->parent->node == NODE_BOOKINFO) + if (pn->parent->node == NODE_BOOKINFO) { macro_open(p, "Nd"); + break; + } + pnode_printpara(p, pn); + macro_nodeline(p, "Sy", pn, 0); + pnode_unlinksub(pn); break; case NODE_TYPE: macro_open(p, "Vt"); @@ -782,9 +890,6 @@ pnode_print(struct format *p, struct pnode *pn) break; case NODE_VARIABLELIST: pnode_printvariablelist(p, pn); - break; - case NODE_VARLISTENTRY: - pnode_printvarlistentry(p, pn); break; case NODE_VARNAME: macro_open(p, "Va");