=================================================================== RCS file: /cvs/docbook2mdoc/docbook2mdoc.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -r1.2 -r1.3 --- docbook2mdoc/docbook2mdoc.c 2014/03/28 02:06:29 1.2 +++ docbook2mdoc/docbook2mdoc.c 2014/03/28 02:46:40 1.3 @@ -1,4 +1,4 @@ -/* $Id: docbook2mdoc.c,v 1.2 2014/03/28 02:06:29 kristaps Exp $ */ +/* $Id: docbook2mdoc.c,v 1.3 2014/03/28 02:46:40 kristaps Exp $ */ /* * Copyright (c) 2014 Kristaps Dzonsons * @@ -33,10 +33,15 @@ enum nodeid { /* Alpha-ordered hereafter. */ NODE_CITEREFENTRY, NODE_CODE, + NODE_FUNCDEF, + NODE_FUNCPROTOTYPE, NODE_FUNCSYNOPSIS, NODE_FUNCSYNOPSISINFO, + NODE_FUNCTION, NODE_MANVOLNUM, NODE_PARA, + NODE_PARAMDEF, + NODE_PARAMETER, NODE_PROGRAMLISTING, NODE_REFCLASS, NODE_REFDESCRIPTOR, @@ -90,10 +95,15 @@ static const struct node nodes[NODE__MAX] = { { NULL, 0 }, { "citerefentry", NODE_IGNTEXT }, { "code", 0 }, + { "funcdef", 0 }, + { "funcprototype", NODE_IGNTEXT }, { "funcsynopsis", NODE_IGNTEXT }, { "funcsynopsisinfo", 0 }, + { "function", 0 }, { "manvolnum", 0 }, { "para", 0 }, + { "paramdef", 0 }, + { "parameter", 0 }, { "programlisting", 0 }, { "refclass", NODE_IGNTEXT }, { "refdescriptor", NODE_IGNTEXT }, @@ -153,6 +163,39 @@ isparent(enum nodeid node, enum nodeid parent) break; } return(0); + case (NODE_FUNCDEF): + return(NODE_FUNCPROTOTYPE == parent); + case (NODE_FUNCPROTOTYPE): + return(NODE_FUNCSYNOPSIS == parent); + case (NODE_FUNCSYNOPSIS): + switch (parent) { + case (NODE_PARA): + case (NODE_REFSECT1): + case (NODE_REFSYNOPSISDIV): + return(1); + default: + break; + } + return(0); + case (NODE_FUNCSYNOPSISINFO): + return(NODE_FUNCSYNOPSIS == parent); + case (NODE_FUNCTION): + switch (parent) { + case (NODE_CODE): + case (NODE_FUNCDEF): + case (NODE_FUNCSYNOPSISINFO): + case (NODE_PARA): + case (NODE_REFDESCRIPTOR): + case (NODE_REFENTRYTITLE): + case (NODE_REFNAME): + case (NODE_REFPURPOSE): + case (NODE_SYNOPSIS): + case (NODE_TITLE): + return(1); + default: + break; + } + return(0); case (NODE_MANVOLNUM): switch (parent) { case (NODE_CITEREFENTRY): @@ -162,9 +205,8 @@ isparent(enum nodeid node, enum nodeid parent) break; } return(0); - case (NODE_FUNCSYNOPSIS): + case (NODE_PARA): switch (parent) { - case (NODE_PARA): case (NODE_REFSECT1): case (NODE_REFSYNOPSISDIV): return(1); @@ -172,12 +214,20 @@ isparent(enum nodeid node, enum nodeid parent) break; } return(0); - case (NODE_FUNCSYNOPSISINFO): - return(NODE_FUNCSYNOPSIS == parent); - case (NODE_PARA): + case (NODE_PARAMDEF): + return(NODE_FUNCPROTOTYPE == parent); + case (NODE_PARAMETER): switch (parent) { - case (NODE_REFSECT1): - case (NODE_REFSYNOPSISDIV): + case (NODE_CODE): + case (NODE_FUNCSYNOPSISINFO): + case (NODE_PARA): + case (NODE_PARAMDEF): + case (NODE_REFDESCRIPTOR): + case (NODE_REFENTRYTITLE): + case (NODE_REFNAME): + case (NODE_REFPURPOSE): + case (NODE_SYNOPSIS): + case (NODE_TITLE): return(1); default: break; @@ -446,6 +496,17 @@ bufappend(struct parse *p, struct pnode *pn) p->b[p->bsz] = '\0'; } +static void +bufappend_r(struct parse *p, struct pnode *pn) +{ + struct pnode *pp; + + if (NODE_TEXT == pn->node) + bufappend(p, pn); + TAILQ_FOREACH(pp, &pn->childq, child) + bufappend_r(p, pp); +} + /* * Print text presumably on a macro line. * Ignore any child macros. @@ -454,15 +515,10 @@ bufappend(struct parse *p, struct pnode *pn) static void pnode_printmacrolinepart(struct parse *p, struct pnode *pn) { - struct pnode *pp; char *cp; bufclear(p); - while (NULL != (pp = TAILQ_FIRST(&pn->childq))) { - if (NODE_TEXT == pp->node) - bufappend(p, pp); - pnode_unlink(pp); - } + bufappend_r(p, pn); /* Convert all space to spaces. */ for (cp = p->b; '\0' != *cp; cp++) @@ -576,6 +632,80 @@ pnode_printrefmeta(struct parse *p, struct pnode *pn) puts(".Os"); } +static void +pnode_printfuncdef(struct parse *p, struct pnode *pn) +{ + struct pnode *pp, *ftype, *func; + + ftype = func = NULL; + TAILQ_FOREACH(pp, &pn->childq, child) + if (NODE_TEXT == pp->node) + ftype = pp; + else if (NODE_FUNCTION == pp->node) + func = pp; + + if (NULL != ftype) { + fputs(".Ft ", stdout); + pnode_printmacroline(p, ftype); + } + + if (NULL != func) { + fputs(".Fo ", stdout); + pnode_printmacroline(p, func); + } else + puts(".Fo UNKNOWN"); +} + +static void +pnode_printparamdef(struct parse *p, struct pnode *pn) +{ + struct pnode *pp, *ptype, *param; + + ptype = param = NULL; + TAILQ_FOREACH(pp, &pn->childq, child) + if (NODE_TEXT == pp->node) + ptype = pp; + else if (NODE_PARAMETER == pp->node) + param = pp; + + fputs(".Fa \"", stdout); + if (NULL != ptype) { + pnode_printmacrolinepart(p, ptype); + putchar(' '); + } + + if (NULL != param) + pnode_printmacrolinepart(p, param); + else + fputs("UNKNOWN", stdout); + + puts("\""); +} + +static void +pnode_printfuncprototype(struct parse *p, struct pnode *pn) +{ + struct pnode *pp, *fdef; + + TAILQ_FOREACH(fdef, &pn->childq, child) + if (NODE_FUNCDEF == fdef->node) + break; + + if (NULL != fdef) { + pnode_printfuncdef(p, fdef); + pnode_unlink(fdef); + } else + puts(".Fo UNKNOWN"); + + TAILQ_FOREACH(pp, &pn->childq, child) { + if (NODE_PARAMDEF == pp->node) + pnode_printparamdef(p, pp); + pnode_unlink(pp); + } + + puts(".Fc"); +} + /* * Print a parsed node (or ignore it--whatever). * This is a recursive function. @@ -602,6 +732,13 @@ pnode_print(struct parse *p, struct pnode *pn) fputs(".Li ", stdout); pnode_printmacroline(p, pn); break; + case (NODE_FUNCTION): + fputs(".Fn ", stdout); + pnode_printmacroline(p, pn); + break; + case (NODE_FUNCPROTOTYPE): + pnode_printfuncprototype(p, pn); + break; case (NODE_FUNCSYNOPSISINFO): fputs(".Fd ", stdout); pnode_printmacroline(p, pn); @@ -609,6 +746,11 @@ pnode_print(struct parse *p, struct pnode *pn) case (NODE_PARA): /* FIXME: not always. */ puts(".Pp"); + break; + case (NODE_PARAMETER): + fputs(".Fa \"", stdout); + pnode_printmacrolinepart(p, pn); + puts("\""); break; case (NODE_PROGRAMLISTING): puts(".Bd -literal");