From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from localhost (fantadrom.bsd.lv [local]) by fantadrom.bsd.lv (OpenSMTPD) with ESMTPA id 33673153 for ; Thu, 28 Mar 2019 15:42:03 -0500 (EST) Date: Thu, 28 Mar 2019 15:42:03 -0500 (EST) X-Mailinglist: mandoc-source Reply-To: source@mandoc.bsd.lv MIME-Version: 1.0 From: schwarze@mandoc.bsd.lv To: source@mandoc.bsd.lv Subject: docbook2mdoc: Implement a formatter for elements, handling X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Message-ID: Log Message: ----------- Implement a formatter for elements, handling , , , , , as well as arbitrary children properly. This required minor work on the formatting infrastructure: Improve macro_addnode() such that it also handles text nodes. Add a companion function print_textnode(). Let print_text() optionally work without ARG_SPACE. Triggered by a report from Stephen Gregoratto that and how GTK documentation uses . Modified Files: -------------- docbook2mdoc: docbook2mdoc.c macro.c macro.h node.h parse.c Revision Data ------------- Index: node.h =================================================================== RCS file: /home/cvs/mdocml/docbook2mdoc/node.h,v retrieving revision 1.5 retrieving revision 1.6 diff -Lnode.h -Lnode.h -u -p -r1.5 -r1.6 --- node.h +++ node.h @@ -46,6 +46,7 @@ enum nodeid { NODE_COLSPEC, NODE_COMMAND, NODE_CONSTANT, + NODE_CONTRIB, NODE_COPYRIGHT, NODE_DATE, NODE_EDITOR, Index: macro.h =================================================================== RCS file: /home/cvs/mdocml/docbook2mdoc/macro.h,v retrieving revision 1.1 retrieving revision 1.2 diff -Lmacro.h -Lmacro.h -u -p -r1.1 -r1.2 --- macro.h +++ macro.h @@ -46,3 +46,6 @@ void macro_addarg(struct format *, cons void macro_argline(struct format *, const char *, const char *); void macro_addnode(struct format *, struct pnode *, int); void macro_nodeline(struct format *, const char *, struct pnode *, int); + +void print_text(struct format *, const char *, int); +void print_textnode(struct format *, struct pnode *); Index: docbook2mdoc.c =================================================================== RCS file: /home/cvs/mdocml/docbook2mdoc/docbook2mdoc.c,v retrieving revision 1.77 retrieving revision 1.78 diff -Ldocbook2mdoc.c -Ldocbook2mdoc.c -u -p -r1.77 -r1.78 --- docbook2mdoc.c +++ docbook2mdoc.c @@ -32,23 +32,6 @@ static void pnode_print(struct format * 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, struc } 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, st 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 pno 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 pno 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: Index: macro.c =================================================================== RCS file: /home/cvs/mdocml/docbook2mdoc/macro.c,v retrieving revision 1.1 retrieving revision 1.2 diff -Lmacro.c -Lmacro.c -u -p -r1.1 -r1.2 --- macro.c +++ macro.c @@ -157,13 +157,13 @@ macro_addnode(struct format *f, struct p assert(f->linestate == LINE_MACRO); /* - * If the only child is a text node, just add that text, - * letting macro_addarg() decide about quoting. + * If this node or its only child is a text node, just add + * that text, letting macro_addarg() decide about quoting. */ - pn = TAILQ_FIRST(&pn->childq); - if (pn != NULL && pn->node == NODE_TEXT && - TAILQ_NEXT(pn, child) == NULL) { + if (pn->node == NODE_TEXT || + ((pn = TAILQ_FIRST(&pn->childq)) != NULL && + pn->node == NODE_TEXT && TAILQ_NEXT(pn, child) == NULL)) { macro_addarg(f, pn->b, flags); return; } @@ -193,10 +193,7 @@ macro_addnode(struct format *f, struct p */ while (pn != NULL) { - if (pn->node == NODE_TEXT) - macro_addarg(f, pn->b, flags); - else - macro_addnode(f, pn, flags); + macro_addnode(f, pn, flags); pn = TAILQ_NEXT(pn, child); flags |= ARG_SPACE; } @@ -210,4 +207,41 @@ macro_nodeline(struct format *f, const c macro_open(f, name); macro_addnode(f, pn, ARG_SPACE | flags); macro_close(f); +} + + +/* + * Print a word on the current text line if one is open, or on a new text + * line otherwise. The flag ARG_SPACE inserts spaces between words. + */ +void +print_text(struct format *f, const char *word, int flags) { + switch (f->linestate) { + case LINE_NEW: + break; + case LINE_TEXT: + if (flags & ARG_SPACE) + putchar(' '); + break; + case LINE_MACRO: + macro_close(f); + break; + } + fputs(word, stdout); + f->linestate = LINE_TEXT; +} + +/* + * Recursively print the content of a node on a text line. + */ +void +print_textnode(struct format *f, struct pnode *n) +{ + struct pnode *nc; + + if (n->node == NODE_TEXT) + print_text(f, n->b, ARG_SPACE); + else + TAILQ_FOREACH(nc, &n->childq, child) + print_textnode(f, nc); } Index: parse.c =================================================================== RCS file: /home/cvs/mdocml/docbook2mdoc/parse.c,v retrieving revision 1.6 retrieving revision 1.7 diff -Lparse.c -Lparse.c -u -p -r1.6 -r1.7 --- parse.c +++ parse.c @@ -73,6 +73,7 @@ static const struct element elements[] = { "colspec", NODE_COLSPEC }, { "command", NODE_COMMAND }, { "constant", NODE_CONSTANT }, + { "contrib", NODE_CONTRIB }, { "copyright", NODE_COPYRIGHT }, { "date", NODE_DATE }, { "editor", NODE_EDITOR }, @@ -82,7 +83,7 @@ static const struct element elements[] = { "envar", NODE_ENVAR }, { "fieldsynopsis", NODE_FIELDSYNOPSIS }, { "filename", NODE_FILENAME }, - { "firstname", NODE_IGNORE }, + { "firstname", NODE_PERSONNAME }, { "firstterm", NODE_FIRSTTERM }, { "footnote", NODE_FOOTNOTE }, { "funcdef", NODE_FUNCDEF }, @@ -122,7 +123,7 @@ static const struct element elements[] = { "option", NODE_OPTION }, { "orderedlist", NODE_ORDEREDLIST }, { "orgname", NODE_ORGNAME }, - { "othername", NODE_IGNORE }, + { "othername", NODE_PERSONNAME }, { "para", NODE_PARA }, { "paramdef", NODE_PARAMDEF }, { "parameter", NODE_PARAMETER }, @@ -164,7 +165,7 @@ static const struct element elements[] = { "spanspec", NODE_SPANSPEC }, { "structname", NODE_STRUCTNAME }, { "subtitle", NODE_SUBTITLE }, - { "surname", NODE_IGNORE }, + { "surname", NODE_PERSONNAME }, { "synopsis", NODE_SYNOPSIS }, { "table", NODE_TABLE }, { "tbody", NODE_TBODY }, -- To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv