[BACK]Return to reorg.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / docbook2mdoc

Annotation of docbook2mdoc/reorg.c, Revision 1.3

1.3     ! schwarze    1: /* $Id: reorg.c,v 1.2 2019/04/28 19:05:11 schwarze Exp $ */
1.1       schwarze    2: /*
                      3:  * Copyright (c) 2019 Ingo Schwarze <schwarze@openbsd.org>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
1.3     ! schwarze   17: #include "string.h"
1.1       schwarze   18:
                     19: #include "node.h"
                     20: #include "reorg.h"
                     21:
                     22: /*
                     23:  * The implementation of the tree reorganizer.
                     24:  */
                     25:
1.2       schwarze   26: static void
                     27: reorg_root(struct pnode *root)
1.1       schwarze   28: {
1.2       schwarze   29:        struct pnode    *date, *descr, *name, *vol, *nc;
1.1       schwarze   30:
1.2       schwarze   31:        if (root == NULL)
1.1       schwarze   32:                return;
                     33:
                     34:        /* Collect prologue information. */
                     35:
                     36:        if ((date = pnode_takefirst(root, NODE_PUBDATE)) == NULL &&
                     37:            (date = pnode_takefirst(root, NODE_DATE)) == NULL) {
                     38:                date = pnode_alloc(NULL);
                     39:                pnode_alloc_text(date, "$Mdocdate" "$");
                     40:        }
                     41:        date->node = NODE_DATE;
                     42:        date->parent = root;
                     43:
                     44:        name = vol = NULL;
                     45:        if ((nc = pnode_findfirst(root, NODE_REFMETA)) != NULL) {
                     46:                name = pnode_takefirst(nc, NODE_REFENTRYTITLE);
                     47:                vol = pnode_takefirst(nc, NODE_MANVOLNUM);
                     48:        }
                     49:        if (name == NULL) {
                     50:                name = pnode_alloc(NULL);
                     51:                name->node = NODE_REFENTRYTITLE;
                     52:                name->parent = root;
                     53:                pnode_alloc_text(name,
                     54:                    pnode_getattr_raw(root, ATTRKEY_ID, "UNKNOWN"));
                     55:        }
                     56:        if (vol == NULL) {
                     57:                vol = pnode_alloc(NULL);
                     58:                vol->node = NODE_MANVOLNUM;
                     59:                vol->parent = root;
                     60:                pnode_alloc_text(vol, "1");
                     61:        }
                     62:
                     63:        /* Insert prologue information at the beginning. */
                     64:
                     65:        if (pnode_findfirst(root, NODE_REFNAMEDIV) == NULL &&
                     66:            ((nc = pnode_findfirst(root, NODE_BOOKINFO)) != NULL ||
                     67:             (nc = pnode_findfirst(root, NODE_REFENTRYINFO)) != NULL) &&
                     68:            (descr = pnode_takefirst(nc, NODE_TITLE)) != NULL)
                     69:                TAILQ_INSERT_HEAD(&root->childq, descr, child);
                     70:        TAILQ_INSERT_HEAD(&root->childq, vol, child);
                     71:        TAILQ_INSERT_HEAD(&root->childq, name, child);
                     72:        TAILQ_INSERT_HEAD(&root->childq, date, child);
1.2       schwarze   73: }
                     74:
                     75: static void
1.3     ! schwarze   76: reorg_refentry(struct pnode *n)
        !            77: {
        !            78:        struct pnode    *info, *meta, *nc, *title;
        !            79:        struct pnode    *match, *later;
        !            80:
        !            81:        /* Collect nodes that remained behind from the prologue. */
        !            82:
        !            83:        meta = NULL;
        !            84:        info = pnode_takefirst(n, NODE_BOOKINFO);
        !            85:        if (info != NULL && TAILQ_FIRST(&info->childq) == NULL) {
        !            86:                pnode_unlink(info);
        !            87:                info = NULL;
        !            88:        }
        !            89:        if (info == NULL) {
        !            90:                info = pnode_takefirst(n, NODE_REFENTRYINFO);
        !            91:                if (info != NULL && TAILQ_FIRST(&info->childq) == NULL) {
        !            92:                        pnode_unlink(info);
        !            93:                        info = NULL;
        !            94:                }
        !            95:                if (info == NULL)
        !            96:                        info = pnode_takefirst(n, NODE_INFO);
        !            97:                meta = pnode_takefirst(n, NODE_REFMETA);
        !            98:                if (meta != NULL && TAILQ_FIRST(&meta->childq) == NULL) {
        !            99:                        pnode_unlink(meta);
        !           100:                        meta = NULL;
        !           101:                }
        !           102:        }
        !           103:        if (info == NULL && meta == NULL)
        !           104:                return;
        !           105:
        !           106:        /*
        !           107:         * Find the best place to put this information.
        !           108:         * Use the last existing AUTHORS node, if any.
        !           109:         * Otherwise, put it behind all standard sections that
        !           110:         * conventionally precede AUTHORS, and also behind any
        !           111:         * non-standard sections that follow the last of these,
        !           112:         * but before the next standard section.
        !           113:         */
        !           114:
        !           115:        match = later = NULL;
        !           116:        TAILQ_FOREACH(nc, &n->childq, child) {
        !           117:                switch (nc->node) {
        !           118:                case NODE_REFENTRY:
        !           119:                case NODE_REFNAMEDIV:
        !           120:                case NODE_REFSYNOPSISDIV:
        !           121:                        later = NULL;
        !           122:                        continue;
        !           123:                case NODE_APPENDIX:
        !           124:                case NODE_INDEX:
        !           125:                        if (later == NULL)
        !           126:                                later = nc;
        !           127:                        continue;
        !           128:                default:
        !           129:                        break;
        !           130:                }
        !           131:                if ((title = pnode_findfirst(nc, NODE_TITLE)) == NULL ||
        !           132:                    (title = TAILQ_FIRST(&title->childq)) == NULL ||
        !           133:                    title->node != NODE_TEXT)
        !           134:                        continue;
        !           135:                if (strcasecmp(title->b, "AUTHORS") == 0 ||
        !           136:                    strcasecmp(title->b, "AUTHOR") == 0)
        !           137:                        match = nc;
        !           138:                else if (strcasecmp(title->b, "NAME") == 0 ||
        !           139:                    strcasecmp(title->b, "SYNOPSIS") == 0 ||
        !           140:                    strcasecmp(title->b, "DESCRIPTION") == 0 ||
        !           141:                    strcasecmp(title->b, "RETURN VALUES") == 0 ||
        !           142:                    strcasecmp(title->b, "ENVIRONMENT") == 0 ||
        !           143:                    strcasecmp(title->b, "FILES") == 0 ||
        !           144:                    strcasecmp(title->b, "EXIT STATUS") == 0 ||
        !           145:                    strcasecmp(title->b, "EXAMPLES") == 0 ||
        !           146:                    strcasecmp(title->b, "DIAGNOSTICS") == 0 ||
        !           147:                    strcasecmp(title->b, "ERRORS") == 0 ||
        !           148:                    strcasecmp(title->b, "SEE ALSO") == 0 ||
        !           149:                    strcasecmp(title->b, "STANDARDS") == 0 ||
        !           150:                    strcasecmp(title->b, "HISTORY") == 0)
        !           151:                        later = NULL;
        !           152:                else if ((strcasecmp(title->b, "CAVEATS") == 0 ||
        !           153:                    strcasecmp(title->b, "BUGS") == 0) &&
        !           154:                    later == NULL)
        !           155:                        later = nc;
        !           156:        }
        !           157:
        !           158:        /*
        !           159:         * If no AUTHORS section was found, create one from scratch,
        !           160:         * and insert that at the place selected earlier.
        !           161:         */
        !           162:
        !           163:        if (match == NULL) {
        !           164:                match = pnode_alloc(NULL);
        !           165:                match->node = NODE_SECTION;
        !           166:                match->flags |= NFLAG_SPC;
        !           167:                match->parent = n;
        !           168:                nc = pnode_alloc(match);
        !           169:                nc->node = NODE_TITLE;
        !           170:                nc->flags |= NFLAG_SPC;
        !           171:                nc = pnode_alloc_text(nc, "AUTHORS");
        !           172:                nc->flags |= NFLAG_SPC;
        !           173:                if (later == NULL)
        !           174:                        TAILQ_INSERT_TAIL(&n->childq, match, child);
        !           175:                else
        !           176:                        TAILQ_INSERT_BEFORE(later, match, child);
        !           177:        }
        !           178:
        !           179:        /*
        !           180:         * Dump the stuff excised at the beginning
        !           181:         * into this AUTHORS section.
        !           182:         */
        !           183:
        !           184:        if (info != NULL)
        !           185:                TAILQ_INSERT_TAIL(&match->childq, info, child);
        !           186:        if (meta != NULL)
        !           187:                TAILQ_INSERT_TAIL(&match->childq, meta, child);
        !           188: }
        !           189:
        !           190: static void
1.2       schwarze  191: default_title(struct pnode *n, const char *title)
                    192: {
                    193:        struct pnode    *nc;
                    194:
                    195:        if (n->parent == NULL)
                    196:                return;
                    197:
                    198:        TAILQ_FOREACH(nc, &n->childq, child)
                    199:                if (nc->node == NODE_TITLE)
                    200:                        return;
                    201:
                    202:        nc = pnode_alloc(NULL);
                    203:        nc->node = NODE_TITLE;
                    204:        nc->parent = n;
                    205:        TAILQ_INSERT_HEAD(&n->childq, nc, child);
                    206:        pnode_alloc_text(nc, title);
                    207: }
                    208:
                    209: static void
                    210: reorg_recurse(struct pnode *n)
                    211: {
                    212:        struct pnode    *nc;
                    213:
                    214:        if (n == NULL)
                    215:                return;
                    216:
                    217:        switch (n->node) {
                    218:        case NODE_APPENDIX:
1.3     ! schwarze  219:                if (n->parent == NULL)
        !           220:                        reorg_refentry(n);
1.2       schwarze  221:                default_title(n, "Appendix");
                    222:                break;
                    223:        case NODE_CAUTION:
                    224:                default_title(n, "Caution");
                    225:                n->node = NODE_NOTE;
                    226:                break;
                    227:        case NODE_LEGALNOTICE:
                    228:                default_title(n, "Legal Notice");
                    229:                n->node = NODE_SIMPLESECT;
                    230:                break;
                    231:        case NODE_NOTE:
                    232:                default_title(n, "Note");
                    233:                break;
                    234:        case NODE_PREFACE:
1.3     ! schwarze  235:                if (n->parent == NULL)
        !           236:                        reorg_refentry(n);
1.2       schwarze  237:                default_title(n, "Preface");
                    238:                n->node = NODE_SECTION;
                    239:                break;
1.3     ! schwarze  240:        case NODE_REFENTRY:
        !           241:                reorg_refentry(n);
        !           242:                break;
1.2       schwarze  243:        case NODE_SECTION:
1.3     ! schwarze  244:                if (n->parent == NULL)
        !           245:                        reorg_refentry(n);
        !           246:                /* FALLTHROUGH */
1.2       schwarze  247:        case NODE_SIMPLESECT:
                    248:                default_title(n, "Untitled");
                    249:                break;
                    250:        case NODE_TIP:
                    251:                default_title(n, "Tip");
                    252:                n->node = NODE_NOTE;
                    253:                break;
                    254:        case NODE_WARNING:
                    255:                default_title(n, "Warning");
                    256:                n->node = NODE_NOTE;
                    257:                break;
                    258:        default:
                    259:                break;
                    260:        }
                    261:
                    262:        TAILQ_FOREACH(nc, &n->childq, child)
                    263:                reorg_recurse(nc);
                    264: }
                    265:
                    266: void
                    267: ptree_reorg(struct ptree *tree)
                    268: {
1.3     ! schwarze  269:        reorg_root(tree->root);
1.2       schwarze  270:        reorg_recurse(tree->root);
1.1       schwarze  271: }

CVSweb