=================================================================== RCS file: /cvs/docbook2mdoc/docbook2mdoc.c,v retrieving revision 1.77 retrieving revision 1.78 diff -u -p -r1.77 -r1.78 --- docbook2mdoc/docbook2mdoc.c 2019/03/26 22:39:33 1.77 +++ docbook2mdoc/docbook2mdoc.c 2019/03/28 20:41:33 1.78 @@ -1,4 +1,4 @@ -/* $Id: docbook2mdoc.c,v 1.77 2019/03/26 22:39:33 schwarze Exp $ */ +/* $Id: docbook2mdoc.c,v 1.78 2019/03/28 20:41:33 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; @@ -407,6 +390,66 @@ 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 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 +471,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"); } } @@ -563,7 +606,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 +630,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: