=================================================================== RCS file: /cvs/docbook2mdoc/docbook2mdoc.c,v retrieving revision 1.125 retrieving revision 1.134 diff -u -p -r1.125 -r1.134 --- docbook2mdoc/docbook2mdoc.c 2019/04/14 21:11:04 1.125 +++ docbook2mdoc/docbook2mdoc.c 2019/04/23 22:25:28 1.134 @@ -1,4 +1,4 @@ -/* $Id: docbook2mdoc.c,v 1.125 2019/04/14 21:11:04 schwarze Exp $ */ +/* $Id: docbook2mdoc.c,v 1.134 2019/04/23 22:25:28 schwarze Exp $ */ /* * Copyright (c) 2014 Kristaps Dzonsons * Copyright (c) 2019 Ingo Schwarze @@ -126,36 +126,18 @@ pnode_printtext(struct format *f, struct pnode *n) } static void -pnode_printpara(struct format *f, struct pnode *n) +pnode_printimagedata(struct format *f, struct pnode *n) { - struct pnode *np; + const char *cp; - if (n->parent == NULL) - return; - - if ((np = TAILQ_PREV(n, pnodeq, child)) == NULL) - np = n->parent; - - f->flags = 0; - - switch (np->node) { - case NODE_ENTRY: - case NODE_FOOTNOTE: - case NODE_GLOSSTERM: - case NODE_LISTITEM: - case NODE_TERM: - return; - case NODE_APPENDIX: - case NODE_LEGALNOTICE: - case NODE_PREFACE: - case NODE_SECTION: - if (f->level < 3) - return; - break; - default: - break; - } - macro_line(f, "Pp"); + if ((cp = pnode_getattr_raw(n, ATTRKEY_FILEREF, NULL)) == NULL) + cp = pnode_getattr_raw(n, ATTRKEY_ENTITYREF, NULL); + if (cp != NULL) { + print_text(f, "[image:", ARG_SPACE); + print_text(f, cp, ARG_SPACE); + print_text(f, "]", 0); + } else + print_text(f, "[image]", ARG_SPACE); } static void @@ -164,7 +146,9 @@ pnode_printrefnamediv(struct format *f, struct pnode * struct pnode *nc, *nn; int comma; + f->parastate = PARA_HAVE; macro_line(f, "Sh NAME"); + f->parastate = PARA_HAVE; comma = 0; TAILQ_FOREACH_SAFE(nc, &n->childq, child, nn) { if (nc->node != NODE_REFNAME) @@ -191,7 +175,9 @@ pnode_printrefsynopsisdiv(struct format *f, struct pno if (nc->node == NODE_TITLE) pnode_unlink(nc); + f->parastate = PARA_HAVE; macro_line(f, "Sh SYNOPSIS"); + f->parastate = PARA_HAVE; } /* @@ -265,14 +251,17 @@ pnode_printsection(struct format *f, struct pnode *n) switch (level) { case 1: macro_close(f); + f->parastate = PARA_HAVE; macro_open(f, "Sh"); break; case 2: macro_close(f); + f->parastate = PARA_HAVE; macro_open(f, "Ss"); break; default: - pnode_printpara(f, n); + if (f->parastate == PARA_MID) + f->parastate = PARA_WANT; macro_open(f, "Sy"); break; } @@ -289,12 +278,14 @@ pnode_printsection(struct format *f, struct pnode *n) */ if (nc != NULL) { - ncc = TAILQ_FIRST(&nc->childq); - if (ncc != NULL && ncc->node == NODE_TEXT && + if (level == 1 && + (ncc = TAILQ_FIRST(&nc->childq)) != NULL && + ncc->node == NODE_TEXT && strcasecmp(ncc->b, "AUTHORS") == 0) macro_line(f, "An -nosplit"); pnode_unlink(nc); } + f->parastate = level > 2 ? PARA_WANT : PARA_HAVE; } /* @@ -324,20 +315,6 @@ pnode_printciterefentry(struct format *f, struct pnode pnode_unlinksub(n); } -static void -pnode_printfuncdef(struct format *f, struct pnode *n) -{ - struct pnode *nc; - - nc = TAILQ_FIRST(&n->childq); - if (nc != NULL && nc->node == NODE_TEXT) { - macro_argline(f, "Ft", nc->b); - pnode_unlink(nc); - } - macro_nodeline(f, "Fo", n, ARG_SINGLE); - pnode_unlinksub(n); -} - /* * The node is a little peculiar. * First, it can have arbitrary open and closing tokens, which default @@ -398,23 +375,65 @@ pnode_printmath(struct format *f, struct pnode *n) static void pnode_printfuncprototype(struct format *f, struct pnode *n) { - struct pnode *nc, *fdef; + struct pnode *fdef, *ftype, *nc, *nn; - TAILQ_FOREACH(fdef, &n->childq, child) - if (fdef->node == NODE_FUNCDEF) + /* + * Extract child and ignore child. + * Leave other children in place, to be treated as parameters. + */ + + fdef = NULL; + TAILQ_FOREACH_SAFE(nc, &n->childq, child, nn) { + switch (nc->node) { + case NODE_FUNCDEF: + if (fdef == NULL) { + fdef = nc; + TAILQ_REMOVE(&n->childq, nc, child); + nc->parent = NULL; + } break; + case NODE_VOID: + pnode_unlink(nc); + break; + default: + break; + } + } + /* + * If no children are left, the function is void; use .Fn. + * Otherwise, use .Fo. + */ + + nc = TAILQ_FIRST(&n->childq); if (fdef != NULL) { - pnode_printfuncdef(f, fdef); + ftype = TAILQ_FIRST(&fdef->childq); + if (ftype != NULL && ftype->node == NODE_TEXT) { + macro_argline(f, "Ft", ftype->b); + pnode_unlink(ftype); + } + if (nc == NULL) { + macro_open(f, "Fn"); + macro_addnode(f, fdef, ARG_SPACE | ARG_SINGLE); + macro_addarg(f, "void", ARG_SPACE); + macro_close(f); + } else + macro_nodeline(f, "Fo", fdef, ARG_SINGLE); pnode_unlink(fdef); - } else + } else if (nc == NULL) + macro_line(f, "Fn UNKNOWN void"); + else macro_line(f, "Fo UNKNOWN"); - TAILQ_FOREACH(nc, &n->childq, child) - macro_nodeline(f, "Fa", nc, ARG_SINGLE); + if (nc == NULL) + return; + while (nc != NULL) { + macro_nodeline(f, "Fa", nc, ARG_SINGLE); + pnode_unlink(nc); + nc = TAILQ_FIRST(&n->childq); + } macro_line(f, "Fc"); - pnode_unlinksub(n); } /* @@ -610,6 +629,18 @@ pnode_printauthor(struct format *f, struct pnode *n) } static void +pnode_printxref(struct format *f, struct pnode *n) +{ + const char *linkend; + + linkend = pnode_getattr_raw(n, ATTRKEY_LINKEND, NULL); + if (linkend != NULL) { + macro_open(f, "Sx"); + macro_addarg(f, linkend, ARG_SPACE); + } +} + +static void pnode_printlink(struct format *f, struct pnode *n) { struct pnode *nc; @@ -652,8 +683,40 @@ pnode_printlink(struct format *f, struct pnode *n) if (TAILQ_FIRST(&n->childq) != NULL) macro_addnode(f, n, ARG_SPACE | ARG_SINGLE); pnode_unlinksub(n); + } +} + +static void +pnode_printolink(struct format *f, struct pnode *n) +{ + const char *uri, *ptr, *local; + + uri = pnode_getattr_raw(n, ATTRKEY_TARGETDOC, NULL); + ptr = pnode_getattr_raw(n, ATTRKEY_TARGETPTR, NULL); + local = pnode_getattr_raw(n, ATTRKEY_LOCALINFO, NULL); + if (uri == NULL) { + uri = ptr; + ptr = NULL; + } + if (uri == NULL) { + uri = local; + local = NULL; + } + if (uri == NULL) return; + + macro_open(f, "Lk"); + macro_addarg(f, uri, ARG_SPACE | ARG_SINGLE); + macro_addnode(f, n, ARG_SPACE | ARG_SINGLE); + if (ptr != NULL || local != NULL) { + macro_close(f); + macro_open(f, "Pq"); + if (ptr != NULL) + macro_addarg(f, ptr, ARG_SPACE); + if (local != NULL) + macro_addarg(f, local, ARG_SPACE); } + pnode_unlinksub(n); } static void @@ -726,6 +789,7 @@ pnode_printprologue(struct format *f, struct pnode *ro pnode_unlink(name); pnode_unlink(vol); pnode_unlink(descr); + f->parastate = PARA_HAVE; } static void @@ -748,6 +812,8 @@ pnode_printrefentry(struct format *f, struct pnode *n) pnode_unlink(info); info = NULL; } + if (info == NULL) + info = pnode_takefirst(n, NODE_INFO); meta = pnode_takefirst(n, NODE_REFMETA); if (meta != NULL && TAILQ_FIRST(&meta->childq) == NULL) { pnode_unlink(meta); @@ -865,15 +931,17 @@ pnode_printrefentry(struct format *f, struct pnode *n) static void pnode_printvarlistentry(struct format *f, struct pnode *n) { - struct pnode *nc, *nn; - int first = 1; + struct pnode *nc, *nn, *ncc; + int comma; macro_open(f, "It"); + f->parastate = PARA_HAVE; f->flags |= FMT_IMPL; + comma = -1; TAILQ_FOREACH_SAFE(nc, &n->childq, child, nn) { if (nc->node != NODE_TERM && nc->node != NODE_GLOSSTERM) continue; - if (first == 0) { + if (comma != -1) { switch (f->linestate) { case LINE_NEW: break; @@ -881,20 +949,24 @@ pnode_printvarlistentry(struct format *f, struct pnode print_text(f, ",", 0); break; case LINE_MACRO: - macro_addarg(f, ",", 0); + macro_addarg(f, ",", comma); break; } } + f->parastate = PARA_HAVE; + comma = (ncc = TAILQ_FIRST(&nc->childq)) == NULL || + pnode_class(ncc->node) == CLASS_TEXT ? 0 : ARG_SPACE; pnode_print(f, nc); pnode_unlink(nc); - first = 0; } macro_close(f); + f->parastate = PARA_HAVE; while ((nc = TAILQ_FIRST(&n->childq)) != NULL) { pnode_print(f, nc); pnode_unlink(nc); } macro_close(f); + f->parastate = PARA_HAVE; } static void @@ -904,8 +976,9 @@ pnode_printtitle(struct format *f, struct pnode *n) TAILQ_FOREACH_SAFE(nc, &n->childq, child, nn) { if (nc->node == NODE_TITLE) { - pnode_printpara(f, nc); - pnode_print(f, nc); + if (f->parastate == PARA_MID) + f->parastate = PARA_WANT; + macro_nodeline(f, "Sy", nc, 0); pnode_unlink(nc); } } @@ -933,7 +1006,9 @@ pnode_printtgroup1(struct format *f, struct pnode *n) macro_line(f, "Bl -bullet -compact"); while ((nc = pnode_findfirst(n, NODE_ENTRY)) != NULL) { macro_line(f, "It"); + f->parastate = PARA_HAVE; pnode_print(f, nc); + f->parastate = PARA_HAVE; pnode_unlink(nc); } macro_line(f, "El"); @@ -945,16 +1020,20 @@ pnode_printtgroup2(struct format *f, struct pnode *n) { struct pnode *nr, *ne; + f->parastate = PARA_HAVE; 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"); f->flags |= FMT_IMPL; + f->parastate = PARA_HAVE; pnode_print(f, ne); macro_close(f); pnode_unlink(ne); + f->parastate = PARA_HAVE; pnode_print(f, nr); + f->parastate = PARA_HAVE; pnode_unlink(nr); } macro_line(f, "El"); @@ -977,6 +1056,7 @@ pnode_printtgroup(struct format *f, struct pnode *n) break; } + f->parastate = PARA_HAVE; macro_line(f, "Bl -ohang"); while ((nc = pnode_findfirst(n, NODE_ROW)) != NULL) { macro_line(f, "It Table Row"); @@ -992,11 +1072,14 @@ pnode_printlist(struct format *f, struct pnode *n) struct pnode *nc; pnode_printtitle(f, n); + f->parastate = PARA_HAVE; macro_argline(f, "Bl", n->node == NODE_ORDEREDLIST ? "-enum" : "-bullet"); TAILQ_FOREACH(nc, &n->childq, child) { macro_line(f, "It"); + f->parastate = PARA_HAVE; pnode_print(f, nc); + f->parastate = PARA_HAVE; } macro_line(f, "El"); pnode_unlinksub(n); @@ -1008,6 +1091,7 @@ pnode_printvariablelist(struct format *f, struct pnode struct pnode *nc; pnode_printtitle(f, n); + f->parastate = PARA_HAVE; macro_line(f, "Bl -tag -width Ds"); TAILQ_FOREACH(nc, &n->childq, child) { if (nc->node == NODE_VARLISTENTRY) @@ -1051,7 +1135,9 @@ pnode_print(struct format *f, struct pnode *n) macro_line(f, "An -split"); break; case NODE_BLOCKQUOTE: + f->parastate = PARA_HAVE; macro_line(f, "Bd -ragged -offset indent"); + f->parastate = PARA_HAVE; break; case NODE_CITEREFENTRY: pnode_printciterefentry(f, n); @@ -1087,6 +1173,8 @@ pnode_print(struct format *f, struct pnode *n) if ((nc = TAILQ_FIRST(&n->childq)) != NULL && pnode_class(nc->node) < CLASS_LINE) macro_open(f, "Em"); + if (n->node == NODE_GLOSSTERM) + f->parastate = PARA_HAVE; break; case NODE_ENVAR: macro_open(f, "Ev"); @@ -1099,6 +1187,7 @@ pnode_print(struct format *f, struct pnode *n) break; case NODE_FOOTNOTE: macro_line(f, "Bo"); + f->parastate = PARA_HAVE; break; case NODE_FUNCTION: macro_open(f, "Fn"); @@ -1109,8 +1198,13 @@ pnode_print(struct format *f, struct pnode *n) case NODE_FUNCSYNOPSISINFO: macro_open(f, "Fd"); break; + case NODE_IMAGEDATA: + pnode_printimagedata(f, n); + break; case NODE_INFORMALEQUATION: + f->parastate = PARA_HAVE; macro_line(f, "Bd -ragged -offset indent"); + f->parastate = PARA_HAVE; /* FALLTHROUGH */ case NODE_INLINEEQUATION: macro_line(f, "EQ"); @@ -1122,6 +1216,7 @@ pnode_print(struct format *f, struct pnode *n) pnode_printgroup(f, n); break; case NODE_KEYSYM: + case NODE_PRODUCTNAME: macro_open(f, "Sy"); break; case NODE_LINK: @@ -1139,8 +1234,10 @@ pnode_print(struct format *f, struct pnode *n) break; case NODE_LITERALLAYOUT: macro_close(f); + f->parastate = PARA_HAVE; macro_argline(f, "Bd", pnode_getattr(n, ATTRKEY_CLASS) == ATTRVAL_MONOSPACED ? "-literal" : "-unfilled"); + f->parastate = PARA_HAVE; break; case NODE_MARKUP: macro_open(f, "Ic"); @@ -1161,6 +1258,9 @@ pnode_print(struct format *f, struct pnode *n) case NODE_MML_MSUP: pnode_printmath(f, n); break; + case NODE_OLINK: + pnode_printolink(f, n); + break; case NODE_OPTION: if ((nc = TAILQ_FIRST(&n->childq)) != NULL && pnode_class(nc->node) < CLASS_LINE) @@ -1170,7 +1270,8 @@ pnode_print(struct format *f, struct pnode *n) pnode_printlist(f, n); break; case NODE_PARA: - pnode_printpara(f, n); + if (f->parastate == PARA_MID) + f->parastate = PARA_WANT; break; case NODE_PARAMDEF: case NODE_PARAMETER: @@ -1180,7 +1281,12 @@ pnode_print(struct format *f, struct pnode *n) pnode_unlinksub(n); break; case NODE_QUOTE: - if (was_impl) + if ((nc = TAILQ_FIRST(&n->childq)) != NULL && + nc->node == NODE_FILENAME && + TAILQ_NEXT(nc, child) == NULL) { + if (n->spc) + nc->spc = 1; + } else if (was_impl) macro_open(f, "Do"); else { macro_open(f, "Dq"); @@ -1190,7 +1296,9 @@ pnode_print(struct format *f, struct pnode *n) case NODE_PROGRAMLISTING: case NODE_SCREEN: case NODE_SYNOPSIS: + f->parastate = PARA_HAVE; macro_line(f, "Bd -literal"); + f->parastate = PARA_HAVE; break; case NODE_SYSTEMITEM: pnode_printsystemitem(f, n); @@ -1226,7 +1334,8 @@ pnode_print(struct format *f, struct pnode *n) macro_open(f, "Ar"); break; case NODE_SBR: - macro_line(f, "br"); + if (f->parastate == PARA_MID) + macro_line(f, "br"); break; case NODE_SUBSCRIPT: if (f->linestate == LINE_MACRO) @@ -1250,7 +1359,8 @@ pnode_print(struct format *f, struct pnode *n) break; case NODE_TITLE: case NODE_SUBTITLE: - pnode_printpara(f, n); + if (f->parastate == PARA_MID) + f->parastate = PARA_WANT; macro_nodeline(f, "Sy", n, 0); pnode_unlinksub(n); break; @@ -1263,6 +1373,12 @@ pnode_print(struct format *f, struct pnode *n) case NODE_VARNAME: macro_open(f, "Va"); break; + case NODE_VOID: + print_text(f, "void", ARG_SPACE); + break; + case NODE_XREF: + pnode_printxref(f, n); + break; default: break; } @@ -1284,8 +1400,12 @@ pnode_print(struct format *f, struct pnode *n) /* Accept more arguments to the previous macro. */ return; case NODE_FOOTNOTE: + f->parastate = PARA_HAVE; macro_line(f, "Bc"); break; + case NODE_GLOSSTERM: + f->parastate = PARA_HAVE; + break; case NODE_INFORMALEQUATION: macro_line(f, "EN"); macro_line(f, "Ed"); @@ -1328,8 +1448,16 @@ pnode_print(struct format *f, struct pnode *n) break; fputs(" } ", stdout); break; + case NODE_PARA: + if (f->parastate == PARA_MID) + f->parastate = PARA_WANT; + break; case NODE_QUOTE: - if (was_impl) { + if ((nc = TAILQ_FIRST(&n->childq)) != NULL && + nc->node == NODE_FILENAME && + TAILQ_NEXT(nc, child) == NULL) + /* nothing */; + else if (was_impl) { f->flags &= ~FMT_NOSPC; macro_open(f, "Dc"); } else @@ -1350,8 +1478,13 @@ pnode_print(struct format *f, struct pnode *n) case NODE_PROGRAMLISTING: case NODE_SCREEN: case NODE_SYNOPSIS: + f->parastate = PARA_HAVE; macro_line(f, "Ed"); break; + case NODE_TITLE: + case NODE_SUBTITLE: + f->parastate = PARA_WANT; + break; default: break; } @@ -1365,6 +1498,7 @@ ptree_print_mdoc(struct ptree *tree) formatter.level = 0; formatter.linestate = LINE_NEW; + formatter.parastate = PARA_HAVE; pnode_printprologue(&formatter, tree->root); pnode_print(&formatter, tree->root); if (formatter.linestate != LINE_NEW)