=================================================================== RCS file: /cvs/docbook2mdoc/docbook2mdoc.c,v retrieving revision 1.105 retrieving revision 1.115 diff -u -p -r1.105 -r1.115 --- docbook2mdoc/docbook2mdoc.c 2019/04/12 04:17:11 1.105 +++ docbook2mdoc/docbook2mdoc.c 2019/04/12 21:37:07 1.115 @@ -1,4 +1,4 @@ -/* $Id: docbook2mdoc.c,v 1.105 2019/04/12 04:17:11 schwarze Exp $ */ +/* $Id: docbook2mdoc.c,v 1.115 2019/04/12 21:37:07 schwarze Exp $ */ /* * Copyright (c) 2014 Kristaps Dzonsons * Copyright (c) 2019 Ingo Schwarze @@ -38,11 +38,10 @@ pnode_printtext(struct format *f, struct pnode *n) struct pnode *nn; char *cp; int accept_arg; - char last; cp = n->b; accept_arg = f->flags & FMT_ARG; - if (f->linestate == LINE_MACRO && n->spc == 0 && !accept_arg) { + if (f->linestate == LINE_MACRO && !n->spc && !accept_arg) { for (;;) { if (*cp == '\0') return; @@ -71,42 +70,43 @@ pnode_printtext(struct format *f, struct pnode *n) */ if (f->linestate != LINE_MACRO && - (nn = TAILQ_NEXT(n, child)) != NULL && nn->spc == 0 && - (nn->node != NODE_TEXT && nn->node != NODE_ESCAPE)) { - macro_open(f, "Pf"); - accept_arg = 1; - f->flags |= FMT_CHILD; - nn->spc = 1; + (nn = TAILQ_NEXT(n, child)) != NULL && nn->spc == 0) { + switch (pnode_class(nn->node)) { + case CLASS_LINE: + case CLASS_ENCL: + macro_open(f, "Pf"); + accept_arg = 1; + f->flags |= FMT_CHILD; + nn->spc = 1; + break; + default: + break; + } } switch (f->linestate) { + case LINE_NEW: + break; case LINE_TEXT: if (n->spc) { - if (n->node == NODE_TEXT) { - putchar('\n'); - last = '\n'; - break; - } - putchar(' '); + if (n->node == NODE_TEXT) + macro_close(f); + else + putchar(' '); } - last = ' '; break; case LINE_MACRO: - if (accept_arg) { + if (accept_arg) putchar(' '); - last = ' '; - break; - } - macro_close(f); - /* FALLTHROUGH */ - case LINE_NEW: - f->linestate = LINE_TEXT; - last = '\n'; + else + macro_close(f); break; } if (n->node == NODE_ESCAPE) { fputs(n->b, stdout); + if (f->linestate == LINE_NEW) + f->linestate = LINE_TEXT; return; } @@ -118,23 +118,10 @@ pnode_printtext(struct format *f, struct pnode *n) if (n->parent != NULL && n->parent->node == NODE_OPTION && *cp == '-') cp++; - /* - * Print the text, skipping whitespace on new lines, - * escaping control characters on new lines, - * and escaping backslashes. - */ - - for (; *cp != '\0'; cp++) { - if (last == '\n') { - if (isspace((unsigned char)*cp)) - continue; - if (*cp == '\'' || *cp == '.') - fputs("\\&", stdout); - } - putchar(last = *cp); - if (last == '\\') - putchar('e'); - } + if (f->linestate == LINE_MACRO) + macro_addarg(f, cp, 0); + else + print_text(f, cp, 0); } static void @@ -169,6 +156,27 @@ pnode_printpara(struct format *f, struct pnode *n) macro_line(f, "Pp"); } +static void +pnode_printrefnamediv(struct format *f, struct pnode *n) +{ + struct pnode *nc, *nn; + int comma; + + macro_line(f, "Sh NAME"); + comma = 0; + TAILQ_FOREACH_SAFE(nc, &n->childq, child, nn) { + if (nc->node != NODE_REFNAME) + continue; + if (comma) + macro_addarg(f, ",", ARG_SPACE); + macro_open(f, "Nm"); + macro_addnode(f, nc, ARG_SPACE); + pnode_unlink(nc); + comma = 1; + } + macro_close(f); +} + /* * If the SYNOPSIS macro has a superfluous title, kill it. */ @@ -190,7 +198,7 @@ pnode_printrefsynopsisdiv(struct format *f, struct pno static void pnode_printrefsect(struct format *f, struct pnode *n) { - struct pnode *nc; + struct pnode *nc, *ncc; const char *title; int flags, level; @@ -262,12 +270,24 @@ pnode_printrefsect(struct format *f, struct pnode *n) break; } - if (nc != NULL) { + if (nc != NULL) macro_addnode(f, nc, flags); - pnode_unlink(nc); - } else + else macro_addarg(f, title, flags | ARG_QUOTED); macro_close(f); + + /* + * DocBook has no equivalent for -split mode, + * so just switch the default in the AUTHORS section. + */ + + if (nc != NULL) { + ncc = TAILQ_FIRST(&nc->childq); + if (ncc != NULL && ncc->node == NODE_TEXT && + strcasecmp(ncc->b, "AUTHORS") == 0) + macro_line(f, "An -nosplit"); + pnode_unlink(nc); + } } /* @@ -573,7 +593,8 @@ pnode_printauthor(struct format *f, struct pnode *n) if ((nc = pnode_findfirst(n, NODE_EMAIL)) != NULL) { f->flags |= FMT_CHILD; - pnode_print(f, nc); + macro_open(f, "Aq Mt"); + macro_addnode(f, nc, ARG_SPACE); pnode_unlink(nc); } @@ -592,24 +613,34 @@ pnode_printauthor(struct format *f, struct pnode *n) static void pnode_printlink(struct format *f, struct pnode *n) { + struct pnode *nc; const char *uri, *text; uri = pnode_getattr_raw(n, ATTRKEY_LINKEND, NULL); if (uri != NULL) { if (TAILQ_FIRST(&n->childq) != NULL) { - print_textnode(f, n); + TAILQ_FOREACH(nc, &n->childq, child) + pnode_print(f, nc); text = ""; - } else { - text = pnode_getattr_raw(n, ATTRKEY_ENDTERM, NULL); - if (text != NULL) + } else if ((text = pnode_getattr_raw(n, + ATTRKEY_ENDTERM, NULL)) != NULL) { + if (f->linestate == LINE_MACRO && f->flags & FMT_ARG) + macro_addarg(f, text, ARG_SPACE); + else print_text(f, text, ARG_SPACE); } if (text != NULL) { - macro_open(f, "Pq"); - f->flags |= FMT_CHILD; + if (f->flags & FMT_IMPL) + macro_open(f, "Po"); + else { + macro_open(f, "Pq"); + f->flags |= FMT_CHILD; + } } macro_open(f, "Sx"); macro_addarg(f, uri, ARG_SPACE); + if (text != NULL && f->flags & FMT_IMPL) + macro_open(f, "Pc"); pnode_unlinksub(n); return; } @@ -645,12 +676,6 @@ pnode_printprologue(struct format *f, struct ptree *tr } else pnode_printrefmeta(f, refmeta); macro_line(f, "Os"); - - if (tree->flags & TREE_EQN) { - macro_line(f, "EQ"); - print_text(f, "delim $$", 0); - macro_line(f, "EN"); - } } /* @@ -660,25 +685,36 @@ pnode_printprologue(struct format *f, struct ptree *tr static void pnode_printvarlistentry(struct format *f, struct pnode *n) { - struct pnode *nc; + struct pnode *nc, *nn; int first = 1; - macro_close(f); macro_open(f, "It"); f->flags |= FMT_IMPL; - TAILQ_FOREACH(nc, &n->childq, child) { + TAILQ_FOREACH_SAFE(nc, &n->childq, child, nn) { if (nc->node != NODE_TERM && nc->node != NODE_GLOSSTERM) continue; - if ( ! first) - macro_addarg(f, ",", 0); + if (first == 0) { + switch (f->linestate) { + case LINE_NEW: + break; + case LINE_TEXT: + print_text(f, ",", 0); + break; + case LINE_MACRO: + macro_addarg(f, ",", 0); + break; + } + } pnode_print(f, nc); + pnode_unlink(nc); first = 0; } macro_close(f); - TAILQ_FOREACH(nc, &n->childq, child) - if (nc->node != NODE_TERM && nc->node != NODE_GLOSSTERM) - pnode_print(f, nc); - pnode_unlinksub(n); + while ((nc = TAILQ_FIRST(&n->childq)) != NULL) { + pnode_print(f, nc); + pnode_unlink(nc); + } + macro_close(f); } static void @@ -813,12 +849,12 @@ static void pnode_print(struct format *f, struct pnode *n) { struct pnode *nc, *nn; - enum linestate sv; + int was_impl; if (n == NULL) return; - sv = f->linestate; + was_impl = f->flags & FMT_IMPL; if (n->spc) f->flags &= ~FMT_NOSPC; else @@ -857,11 +893,15 @@ pnode_print(struct format *f, struct pnode *n) break; case NODE_EDITOR: print_text(f, "editor:", ARG_SPACE); - sv = LINE_TEXT; macro_open(f, "An"); break; case NODE_EMAIL: - macro_open(f, "Aq Mt"); + if (was_impl) + macro_open(f, "Ao Mt"); + else { + macro_open(f, "Aq Mt"); + f->flags |= FMT_IMPL; + } break; case NODE_EMPHASIS: case NODE_FIRSTTERM: @@ -887,13 +927,11 @@ pnode_print(struct format *f, struct pnode *n) macro_open(f, "Fd"); break; case NODE_INFORMALEQUATION: + macro_line(f, "Bd -ragged -offset indent"); + /* FALLTHROUGH */ + case NODE_INLINEEQUATION: macro_line(f, "EQ"); break; - case NODE_INLINEEQUATION: - if (f->linestate == LINE_NEW) - f->linestate = LINE_TEXT; - putchar('$'); - break; case NODE_ITEMIZEDLIST: pnode_printlist(f, n); break; @@ -907,13 +945,21 @@ pnode_print(struct format *f, struct pnode *n) pnode_printlink(f, n); break; case NODE_LITERAL: - macro_open(f, "Ql"); + if (was_impl) + macro_open(f, "So"); + else { + macro_open(f, "Ql"); + f->flags |= FMT_IMPL; + } break; case NODE_LITERALLAYOUT: macro_close(f); macro_argline(f, "Bd", pnode_getattr(n, ATTRKEY_CLASS) == ATTRVAL_MONOSPACED ? "-literal" : "-unfilled"); break; + case NODE_MARKUP: + macro_open(f, "Ic"); + break; case NODE_MML_MFENCED: pnode_printmathfenced(f, n); break; @@ -947,7 +993,12 @@ pnode_print(struct format *f, struct pnode *n) pnode_unlinksub(n); break; case NODE_QUOTE: - macro_open(f, "Qo"); + if (was_impl) + macro_open(f, "Do"); + else { + macro_open(f, "Dq"); + f->flags |= FMT_IMPL; + } break; case NODE_PROGRAMLISTING: case NODE_SCREEN: @@ -959,13 +1010,11 @@ pnode_print(struct format *f, struct pnode *n) pnode_unlinksub(n); break; case NODE_REFNAME: - /* Suppress non-text children... */ + /* More often, these appear inside NODE_REFNAMEDIV. */ macro_open(f, "Nm"); - macro_addnode(f, n, ARG_SPACE | ARG_SINGLE); - pnode_unlinksub(n); break; case NODE_REFNAMEDIV: - macro_line(f, "Sh NAME"); + pnode_printrefnamediv(f, n); break; case NODE_REFPURPOSE: macro_open(f, "Nd"); @@ -989,9 +1038,6 @@ pnode_print(struct format *f, struct pnode *n) case NODE_SBR: macro_line(f, "br"); break; - case NODE_SGMLTAG: - macro_open(f, "Ic"); - break; case NODE_TEXT: case NODE_ESCAPE: pnode_printtext(f, n); @@ -1026,6 +1072,13 @@ pnode_print(struct format *f, struct pnode *n) pnode_print(f, nc); switch (n->node) { + case NODE_EMAIL: + if (was_impl) { + f->flags &= ~FMT_NOSPC; + macro_open(f, "Ac"); + } else + f->flags &= ~FMT_IMPL; + break; case NODE_ESCAPE: case NODE_TERM: case NODE_TEXT: @@ -1033,11 +1086,18 @@ pnode_print(struct format *f, struct pnode *n) return; case NODE_INFORMALEQUATION: macro_line(f, "EN"); + macro_line(f, "Ed"); break; case NODE_INLINEEQUATION: - fputs("$ ", stdout); - f->linestate = sv; + macro_line(f, "EN"); break; + case NODE_LITERAL: + if (was_impl) { + f->flags &= ~FMT_NOSPC; + macro_open(f, "Sc"); + } else + f->flags &= ~FMT_IMPL; + break; case NODE_MEMBER: if ((nn = TAILQ_NEXT(n, child)) != NULL && nn->node != NODE_MEMBER) @@ -1065,27 +1125,12 @@ pnode_print(struct format *f, struct pnode *n) fputs(" } ", stdout); break; case NODE_QUOTE: - if (sv == LINE_NEW) - macro_close(f); - sv = f->linestate; - macro_open(f, "Qc"); - if (sv == LINE_NEW) - macro_close(f); + if (was_impl) { + f->flags &= ~FMT_NOSPC; + macro_open(f, "Dc"); + } else + f->flags &= ~FMT_IMPL; break; - case NODE_REFNAME: - /* - * If we're in the NAME macro and we have multiple - * macros in sequence, then print out a - * trailing comma before the newline. - */ - if (n->parent != NULL && - n->parent->node == NODE_REFNAMEDIV && - TAILQ_NEXT(n, child) != NULL && - TAILQ_NEXT(n, child)->node == NODE_REFNAME) - macro_addarg(f, ",", ARG_SPACE); - if (sv == LINE_NEW) - macro_close(f); - break; case NODE_PREFACE: case NODE_SECTION: case NODE_APPENDIX: @@ -1115,7 +1160,7 @@ pnode_print(struct format *f, struct pnode *n) } void -ptree_print(struct ptree *tree) +ptree_print_mdoc(struct ptree *tree) { struct format formatter;