=================================================================== RCS file: /cvs/docbook2mdoc/docbook2mdoc.c,v retrieving revision 1.39 retrieving revision 1.43 diff -u -p -r1.39 -r1.43 --- docbook2mdoc/docbook2mdoc.c 2014/04/30 13:18:38 1.39 +++ docbook2mdoc/docbook2mdoc.c 2014/10/19 19:11:29 1.43 @@ -1,4 +1,4 @@ -/* $Id: docbook2mdoc.c,v 1.39 2014/04/30 13:18:38 kristaps Exp $ */ +/* $Id: docbook2mdoc.c,v 1.43 2014/10/19 19:11:29 kristaps Exp $ */ /* * Copyright (c) 2014 Kristaps Dzonsons * @@ -37,6 +37,8 @@ struct parse { enum nodeid node; /* current (NODE_ROOT if pre-tree) */ const char *fname; /* filename */ int stop; /* should we stop now? */ +#define PARSE_EQN 1 + unsigned int flags; /* document-wide flags */ struct pnode *root; /* root of parse tree */ struct pnode *cur; /* current node in tree */ char *b; /* nil-terminated buffer for pre-print */ @@ -74,7 +76,9 @@ struct pnode { static const char *attrkeys[ATTRKEY__MAX] = { "choice", + "close", "id", + "open", "rep" }; @@ -114,12 +118,23 @@ static const struct node nodes[NODE__MAX] = { { "group", NODE_IGNTEXT }, { "holder", NODE_IGNTEXT }, { "info", NODE_IGNTEXT }, + { "informalequation", NODE_IGNTEXT }, { "informaltable", NODE_IGNTEXT }, + { "inlineequation", NODE_IGNTEXT }, { "itemizedlist", NODE_IGNTEXT }, { "link", 0 }, { "listitem", NODE_IGNTEXT }, { "literal", 0 }, { "manvolnum", 0 }, + { "mml:math", NODE_IGNTEXT }, + { "mml:mfenced", 0 }, + { "mml:mfrac", 0 }, + { "mml:mi", 0 }, + { "mml:mn", 0 }, + { "mml:mo", 0 }, + { "mml:mrow", 0 }, + { "mml:msub", 0 }, + { "mml:msup", 0 }, { "modifier", 0 }, { "note", NODE_IGNTEXT }, { "option", 0 }, @@ -292,7 +307,6 @@ xml_elem_start(void *arg, const XML_Char *name, const ps->node = ps->cur->node; } - for (node = 0; node < NODE__MAX; node++) if (NULL == nodes[node].name) continue; @@ -328,6 +342,9 @@ xml_elem_start(void *arg, const XML_Char *name, const return; } + if (NODE_INLINEEQUATION == node) + ps->flags |= PARSE_EQN; + if (NULL == (dat = calloc(1, sizeof(struct pnode)))) { perror(NULL); exit(EXIT_FAILURE); @@ -851,7 +868,76 @@ pnode_printparamdef(struct parse *p, struct pnode *pn) p->newln = 1; } +/* + * The node is a little peculiar. + * First, it can have arbitrary open and closing tokens, which default + * to parentheses. + * Second, >1 arguments are separated by commas. + */ static void +pnode_printmathfenced(struct parse *p, struct pnode *pn) +{ + struct pnode *pp; + struct pattr *ap; + + TAILQ_FOREACH(ap, &pn->attrq, child) + if (ATTRKEY_OPEN == ap->key) { + printf("left %s ", ap->rawval); + break; + } + if (NULL == ap) + printf("left ( "); + + pp = TAILQ_FIRST(&pn->childq); + pnode_print(p, pp); + + while (NULL != (pp = TAILQ_NEXT(pp, child))) { + putchar(','); + pnode_print(p, pp); + } + + TAILQ_FOREACH(ap, &pn->attrq, child) + if (ATTRKEY_CLOSE == ap->key) { + printf("right %s ", ap->rawval); + break; + } + if (NULL == ap) + printf("right ) "); +} + +/* + * These math nodes require special handling because they have infix + * syntax, instead of the usual prefix or prefix. + * So we need to break up the first and second child node with a + * particular eqn(7) word. + */ +static void +pnode_printmath(struct parse *p, struct pnode *pn) +{ + struct pnode *pp; + + pp = TAILQ_FIRST(&pn->childq); + pnode_print(p, pp); + + switch (pn->node) { + case (NODE_MML_MSUP): + fputs(" sup ", stdout); + break; + case (NODE_MML_MFRAC): + fputs(" over ", stdout); + break; + case (NODE_MML_MSUB): + fputs(" sub ", stdout); + break; + default: + break; + } + + pp = TAILQ_NEXT(pp, child); + pnode_print(p, pp); +} + +static void pnode_printfuncprototype(struct parse *p, struct pnode *pn) { struct pnode *pp, *fdef; @@ -984,26 +1070,39 @@ pnode_printprologue(struct parse *p, struct pnode *pn) puts(".Dt UNKNOWN 1"); puts(".Os"); } + + if (PARSE_EQN & p->flags) { + puts(".EQ"); + puts("delim $$"); + puts(".EN"); + } } +/* + * We can have multiple elements within a , which + * we should comma-separate as list headers. + */ static void pnode_printvarlistentry(struct parse *p, struct pnode *pn) { struct pnode *pp; + int first = 1; assert(p->newln); + fputs(".It", stdout); + p->newln = 0; + TAILQ_FOREACH(pp, &pn->childq, child) if (NODE_TERM == pp->node) { - assert(p->newln); - fputs(".It", stdout); - p->newln = 0; + if ( ! first) + putchar(','); pnode_print(p, pp); pnode_unlink(pp); - pnode_printmclose(p, 1); - return; - } + first = 0; + } else + break; - puts(".It"); + putchar('\n'); p->newln = 1; } @@ -1178,6 +1277,16 @@ pnode_print(struct parse *p, struct pnode *pn) pnode_printmopen(p); fputs("Fd", stdout); break; + case (NODE_INFORMALEQUATION): + if ( ! p->newln) + putchar('\n'); + puts(".EQ"); + p->newln = 0; + break; + case (NODE_INLINEEQUATION): + fputc('$', stdout); + p->newln = 0; + break; case (NODE_ITEMIZEDLIST): assert(p->newln); pnode_printlist(p, pn); @@ -1191,6 +1300,24 @@ pnode_print(struct parse *p, struct pnode *pn) pnode_printmopen(p); fputs("Li", stdout); break; + case (NODE_MML_MFENCED): + pnode_printmathfenced(p, pn); + pnode_unlinksub(pn); + break; + case (NODE_MML_MROW): + case (NODE_MML_MI): + case (NODE_MML_MN): + case (NODE_MML_MO): + if (TAILQ_EMPTY(&pn->childq)) + break; + fputs(" { ", stdout); + break; + case (NODE_MML_MFRAC): + case (NODE_MML_MSUB): + case (NODE_MML_MSUP): + pnode_printmath(p, pn); + pnode_unlinksub(pn); + break; case (NODE_OPTION): pnode_printmopen(p); fputs("Fl", stdout); @@ -1371,6 +1498,24 @@ pnode_print(struct parse *p, struct pnode *pn) pnode_print(p, pp); switch (pn->node) { + case (NODE_INFORMALEQUATION): + if ( ! p->newln) + putchar('\n'); + puts(".EN"); + p->newln = 1; + break; + case (NODE_INLINEEQUATION): + fputs("$ ", stdout); + p->newln = sv; + break; + case (NODE_MML_MROW): + case (NODE_MML_MI): + case (NODE_MML_MN): + case (NODE_MML_MO): + if (TAILQ_EMPTY(&pn->childq)) + break; + fputs(" } ", stdout); + break; case (NODE_APPLICATION): case (NODE_ARG): case (NODE_CITEREFENTRY):