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 139aaf94 for ; Tue, 26 Mar 2019 14:17:59 -0500 (EST) Date: Tue, 26 Mar 2019 14:17:59 -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: The file docbook2mdoc.c is still large, so split out the X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Message-ID: Log Message: ----------- The file docbook2mdoc.c is still large, so split out the macro line formatter, which is quite self-contained. Modified Files: -------------- docbook2mdoc: Makefile docbook2mdoc.c Added Files: ----------- docbook2mdoc: macro.c macro.h Revision Data ------------- --- /dev/null +++ macro.h @@ -0,0 +1,48 @@ +/* $Id: macro.h,v 1.1 2019/03/26 19:17:29 schwarze Exp $ */ +/* + * Copyright (c) 2019 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * The interface of the macro line formatter, + * a part of the mdoc(7) formatter. + */ + +enum linestate { + LINE_NEW = 0, /* At the beginning of a new line. */ + LINE_TEXT, /* In the middle of a text line. */ + LINE_MACRO /* In the middle of a macro line. */ +}; + +struct format { + int level; /* Header level, starting at 1. */ + enum linestate linestate; +}; + +#define ARG_SPACE 1 /* Insert whitespace before this argument. */ +#define ARG_SINGLE 2 /* Quote argument if it contains whitespace. */ +#define ARG_QUOTED 4 /* We are already in a quoted argument. */ +#define ARG_UPPER 8 /* Covert argument to upper case. */ + + +void macro_open(struct format *, const char *); +void macro_close(struct format *); +void macro_line(struct format *, const char *); +void macro_closepunct(struct format *, struct pnode *); + +void macro_addarg(struct format *, const char *, int); +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); Index: docbook2mdoc.c =================================================================== RCS file: /home/cvs/mdocml/docbook2mdoc/docbook2mdoc.c,v retrieving revision 1.74 retrieving revision 1.75 diff -Ldocbook2mdoc.c -Ldocbook2mdoc.c -u -p -r1.74 -r1.75 --- docbook2mdoc.c +++ docbook2mdoc.c @@ -21,215 +21,15 @@ #include #include "node.h" +#include "macro.h" #include "format.h" /* * The implementation of the mdoc(7) formatter. */ -enum linestate { - LINE_NEW = 0, - LINE_TEXT, - LINE_MACRO -}; - -struct format { - int level; /* Header level, starting at 1. */ - enum linestate linestate; -}; - static void pnode_print(struct format *, struct pnode *); - -static void -macro_open(struct format *p, const char *name) -{ - switch (p->linestate) { - case LINE_TEXT: - putchar('\n'); - /* FALLTHROUGH */ - case LINE_NEW: - putchar('.'); - p->linestate = LINE_MACRO; - break; - case LINE_MACRO: - putchar(' '); - break; - } - fputs(name, stdout); -} - -static void -macro_close(struct format *p) -{ - assert(p->linestate == LINE_MACRO); - putchar('\n'); - p->linestate = LINE_NEW; -} - -static void -macro_line(struct format *p, const char *name) -{ - macro_open(p, name); - macro_close(p); -} - -#define ARG_SPACE 1 /* Insert whitespace before this argument. */ -#define ARG_SINGLE 2 /* Quote argument if it contains whitespace. */ -#define ARG_QUOTED 4 /* We are already in a quoted argument. */ -#define ARG_UPPER 8 /* Covert argument to upper case. */ -/* - * Print an argument string on a macro line, collapsing whitespace. - */ -static void -macro_addarg(struct format *p, const char *arg, int flags) -{ - const char *cp; - - assert(p->linestate == LINE_MACRO); - - /* Quote if requested and necessary. */ - - if ((flags & (ARG_SINGLE | ARG_QUOTED)) == ARG_SINGLE) { - for (cp = arg; *cp != '\0'; cp++) - if (isspace((unsigned char)*cp)) - break; - if (*cp != '\0') { - if (flags & ARG_SPACE) { - putchar(' '); - flags &= ~ ARG_SPACE; - } - putchar('"'); - flags = ARG_QUOTED; - } - } - - for (cp = arg; *cp != '\0'; cp++) { - - /* Collapse whitespace. */ - - if (isspace((unsigned char)*cp)) { - flags |= ARG_SPACE; - continue; - } else if (flags & ARG_SPACE) { - putchar(' '); - flags &= ~ ARG_SPACE; - } - - /* Escape us if we look like a macro. */ - - if ((flags & ARG_QUOTED) == 0 && - (cp == arg || isspace((unsigned char)cp[-1])) && - isupper((unsigned char)cp[0]) && - islower((unsigned char)cp[1]) && - (cp[2] == '\0' || cp[2] == ' ' || - (islower((unsigned char)cp[2]) && - (cp[3] == '\0' || cp[3] == ' ')))) - fputs("\\&", stdout); - - if (*cp == '"') - fputs("\\(dq", stdout); - else if (flags & ARG_UPPER) - putchar(toupper((unsigned char)*cp)); - else - putchar(*cp); - if (*cp == '\\') - putchar('e'); - } -} - -static void -macro_argline(struct format *p, const char *name, const char *arg) -{ - macro_open(p, name); - macro_addarg(p, arg, ARG_SPACE); - macro_close(p); -} - -/* - * Recursively append text from the children of a node to a macro line. - */ -static void -macro_addnode(struct format *p, struct pnode *pn, int flags) -{ - int quote_now; - - assert(p->linestate == LINE_MACRO); - - /* - * If the 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) { - macro_addarg(p, pn->b, flags); - return; - } - - /* - * If we want the argument quoted and are not already - * in a quoted context, quote now. - */ - - quote_now = 0; - if (flags & ARG_SINGLE) { - if ((flags & ARG_QUOTED) == 0) { - if (flags & ARG_SPACE) { - putchar(' '); - flags &= ~ARG_SPACE; - } - putchar('"'); - flags |= ARG_QUOTED; - quote_now = 1; - } - flags &= ~ARG_SINGLE; - } - - /* - * Iterate to child and sibling nodes, - * inserting whitespace between nodes. - */ - - while (pn != NULL) { - if (pn->node == NODE_TEXT) - macro_addarg(p, pn->b, flags); - else - macro_addnode(p, pn, flags); - pn = TAILQ_NEXT(pn, child); - flags |= ARG_SPACE; - } - if (quote_now) - putchar('"'); -} - -static void -macro_nodeline(struct format *p, const char *name, struct pnode *pn, int flags) -{ - macro_open(p, name); - macro_addnode(p, pn, ARG_SPACE | flags); - macro_close(p); -} - -/* - * If the next node is a text node starting with closing punctuation, - * emit the closing punctuation as a trailing macro argument. - */ -static void -macro_closepunct(struct format *p, struct pnode *pn) -{ - if ((pn = TAILQ_NEXT(pn, child)) != NULL && - pn->node == NODE_TEXT && pn->bsz > 0 && - (pn->b[0] == ',' || pn->b[0] == '.') && - (pn->bsz == 1 || isspace((unsigned char)pn->b[1]))) { - putchar(' '); - putchar(pn->b[0]); - pn->b++; - pn->bsz--; - } - macro_close(p); -} static void print_text(struct format *p, const char *word) Index: Makefile =================================================================== RCS file: /home/cvs/mdocml/docbook2mdoc/Makefile,v retrieving revision 1.18 retrieving revision 1.19 diff -LMakefile -LMakefile -u -p -r1.18 -r1.19 --- Makefile +++ Makefile @@ -3,9 +3,9 @@ CFLAGS += -g -W -Wall -Wstrict-prototype WWWPREFIX = /usr/vhosts/mdocml.bsd.lv/www/htdocs/docbook2mdoc PREFIX = /usr/local -HEADS = node.h parse.h format.h -SRCS = node.c parse.c docbook2mdoc.c main.c -OBJS = node.o parse.o docbook2mdoc.o main.o +HEADS = node.h parse.h macro.h format.h +SRCS = node.c parse.c macro.c docbook2mdoc.c main.c +OBJS = node.o parse.o macro.o docbook2mdoc.o main.o all: docbook2mdoc --- /dev/null +++ macro.c @@ -0,0 +1,213 @@ +/* $Id: macro.c,v 1.1 2019/03/26 19:17:29 schwarze Exp $ */ +/* + * Copyright (c) 2019 Ingo Schwarze + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include + +#include "node.h" +#include "macro.h" + +/* + * The implementation of the macro line formatter, + * a part of the mdoc(7) formatter. + */ + +void +macro_open(struct format *f, const char *name) +{ + switch (f->linestate) { + case LINE_TEXT: + putchar('\n'); + /* FALLTHROUGH */ + case LINE_NEW: + putchar('.'); + f->linestate = LINE_MACRO; + break; + case LINE_MACRO: + putchar(' '); + break; + } + fputs(name, stdout); +} + +void +macro_close(struct format *f) +{ + assert(f->linestate == LINE_MACRO); + putchar('\n'); + f->linestate = LINE_NEW; +} + +void +macro_line(struct format *f, const char *name) +{ + macro_open(f, name); + macro_close(f); +} + +/* + * If the next node is a text node starting with closing punctuation, + * emit the closing punctuation as a trailing macro argument. + */ +void +macro_closepunct(struct format *f, struct pnode *pn) +{ + if ((pn = TAILQ_NEXT(pn, child)) != NULL && + pn->node == NODE_TEXT && pn->bsz > 0 && + (pn->b[0] == ',' || pn->b[0] == '.') && + (pn->bsz == 1 || isspace((unsigned char)pn->b[1]))) { + putchar(' '); + putchar(pn->b[0]); + pn->b++; + pn->bsz--; + } + macro_close(f); +} + +/* + * Print an argument string on a macro line, collapsing whitespace. + */ +void +macro_addarg(struct format *f, const char *arg, int flags) +{ + const char *cp; + + assert(f->linestate == LINE_MACRO); + + /* Quote if requested and necessary. */ + + if ((flags & (ARG_SINGLE | ARG_QUOTED)) == ARG_SINGLE) { + for (cp = arg; *cp != '\0'; cp++) + if (isspace((unsigned char)*cp)) + break; + if (*cp != '\0') { + if (flags & ARG_SPACE) { + putchar(' '); + flags &= ~ ARG_SPACE; + } + putchar('"'); + flags = ARG_QUOTED; + } + } + + for (cp = arg; *cp != '\0'; cp++) { + + /* Collapse whitespace. */ + + if (isspace((unsigned char)*cp)) { + flags |= ARG_SPACE; + continue; + } else if (flags & ARG_SPACE) { + putchar(' '); + flags &= ~ ARG_SPACE; + } + + /* Escape us if we look like a macro. */ + + if ((flags & ARG_QUOTED) == 0 && + (cp == arg || isspace((unsigned char)cp[-1])) && + isupper((unsigned char)cp[0]) && + islower((unsigned char)cp[1]) && + (cp[2] == '\0' || cp[2] == ' ' || + (islower((unsigned char)cp[2]) && + (cp[3] == '\0' || cp[3] == ' ')))) + fputs("\\&", stdout); + + if (*cp == '"') + fputs("\\(dq", stdout); + else if (flags & ARG_UPPER) + putchar(toupper((unsigned char)*cp)); + else + putchar(*cp); + if (*cp == '\\') + putchar('e'); + } +} + +void +macro_argline(struct format *f, const char *name, const char *arg) +{ + macro_open(f, name); + macro_addarg(f, arg, ARG_SPACE); + macro_close(f); +} + +/* + * Recursively append text from the children of a node to a macro line. + */ +void +macro_addnode(struct format *f, struct pnode *pn, int flags) +{ + int quote_now; + + assert(f->linestate == LINE_MACRO); + + /* + * If the 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) { + macro_addarg(f, pn->b, flags); + return; + } + + /* + * If we want the argument quoted and are not already + * in a quoted context, quote now. + */ + + quote_now = 0; + if (flags & ARG_SINGLE) { + if ((flags & ARG_QUOTED) == 0) { + if (flags & ARG_SPACE) { + putchar(' '); + flags &= ~ARG_SPACE; + } + putchar('"'); + flags |= ARG_QUOTED; + quote_now = 1; + } + flags &= ~ARG_SINGLE; + } + + /* + * Iterate to child and sibling nodes, + * inserting whitespace between nodes. + */ + + while (pn != NULL) { + if (pn->node == NODE_TEXT) + macro_addarg(f, pn->b, flags); + else + macro_addnode(f, pn, flags); + pn = TAILQ_NEXT(pn, child); + flags |= ARG_SPACE; + } + if (quote_now) + putchar('"'); +} + +void +macro_nodeline(struct format *f, const char *name, struct pnode *pn, int flags) +{ + macro_open(f, name); + macro_addnode(f, pn, ARG_SPACE | flags); + macro_close(f); +} -- To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv