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

Annotation of docbook2mdoc/reorg.c, Revision 1.4

1.4     ! schwarze    1: /* $Id: reorg.c,v 1.3 2019/04/28 19:59:01 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.4     ! schwarze   29:        struct pnode    *date, *info, *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 &&
1.4     ! schwarze   66:            ((info = pnode_findfirst(root, NODE_BOOKINFO)) != NULL ||
        !            67:             (info = pnode_findfirst(root, NODE_REFENTRYINFO)) != NULL)) {
        !            68:                if ((nc = pnode_takefirst(info, NODE_ABSTRACT)) != NULL)
        !            69:                        TAILQ_INSERT_HEAD(&root->childq, nc, child);
        !            70:                if ((nc = pnode_takefirst(info, NODE_TITLE)) != NULL)
        !            71:                        TAILQ_INSERT_HEAD(&root->childq, nc, child);
        !            72:        }
1.1       schwarze   73:        TAILQ_INSERT_HEAD(&root->childq, vol, child);
                     74:        TAILQ_INSERT_HEAD(&root->childq, name, child);
                     75:        TAILQ_INSERT_HEAD(&root->childq, date, child);
1.2       schwarze   76: }
                     77:
                     78: static void
1.3       schwarze   79: reorg_refentry(struct pnode *n)
                     80: {
                     81:        struct pnode    *info, *meta, *nc, *title;
                     82:        struct pnode    *match, *later;
                     83:
                     84:        /* Collect nodes that remained behind from the prologue. */
                     85:
                     86:        meta = NULL;
                     87:        info = pnode_takefirst(n, NODE_BOOKINFO);
                     88:        if (info != NULL && TAILQ_FIRST(&info->childq) == NULL) {
                     89:                pnode_unlink(info);
                     90:                info = NULL;
                     91:        }
                     92:        if (info == NULL) {
                     93:                info = pnode_takefirst(n, NODE_REFENTRYINFO);
                     94:                if (info != NULL && TAILQ_FIRST(&info->childq) == NULL) {
                     95:                        pnode_unlink(info);
                     96:                        info = NULL;
                     97:                }
                     98:                if (info == NULL)
                     99:                        info = pnode_takefirst(n, NODE_INFO);
                    100:                meta = pnode_takefirst(n, NODE_REFMETA);
                    101:                if (meta != NULL && TAILQ_FIRST(&meta->childq) == NULL) {
                    102:                        pnode_unlink(meta);
                    103:                        meta = NULL;
                    104:                }
                    105:        }
                    106:        if (info == NULL && meta == NULL)
                    107:                return;
                    108:
                    109:        /*
                    110:         * Find the best place to put this information.
                    111:         * Use the last existing AUTHORS node, if any.
                    112:         * Otherwise, put it behind all standard sections that
                    113:         * conventionally precede AUTHORS, and also behind any
                    114:         * non-standard sections that follow the last of these,
                    115:         * but before the next standard section.
                    116:         */
                    117:
                    118:        match = later = NULL;
                    119:        TAILQ_FOREACH(nc, &n->childq, child) {
                    120:                switch (nc->node) {
                    121:                case NODE_REFENTRY:
                    122:                case NODE_REFNAMEDIV:
                    123:                case NODE_REFSYNOPSISDIV:
                    124:                        later = NULL;
                    125:                        continue;
                    126:                case NODE_APPENDIX:
                    127:                case NODE_INDEX:
                    128:                        if (later == NULL)
                    129:                                later = nc;
                    130:                        continue;
                    131:                default:
                    132:                        break;
                    133:                }
                    134:                if ((title = pnode_findfirst(nc, NODE_TITLE)) == NULL ||
                    135:                    (title = TAILQ_FIRST(&title->childq)) == NULL ||
                    136:                    title->node != NODE_TEXT)
                    137:                        continue;
                    138:                if (strcasecmp(title->b, "AUTHORS") == 0 ||
                    139:                    strcasecmp(title->b, "AUTHOR") == 0)
                    140:                        match = nc;
                    141:                else if (strcasecmp(title->b, "NAME") == 0 ||
                    142:                    strcasecmp(title->b, "SYNOPSIS") == 0 ||
                    143:                    strcasecmp(title->b, "DESCRIPTION") == 0 ||
                    144:                    strcasecmp(title->b, "RETURN VALUES") == 0 ||
                    145:                    strcasecmp(title->b, "ENVIRONMENT") == 0 ||
                    146:                    strcasecmp(title->b, "FILES") == 0 ||
                    147:                    strcasecmp(title->b, "EXIT STATUS") == 0 ||
                    148:                    strcasecmp(title->b, "EXAMPLES") == 0 ||
                    149:                    strcasecmp(title->b, "DIAGNOSTICS") == 0 ||
                    150:                    strcasecmp(title->b, "ERRORS") == 0 ||
                    151:                    strcasecmp(title->b, "SEE ALSO") == 0 ||
                    152:                    strcasecmp(title->b, "STANDARDS") == 0 ||
                    153:                    strcasecmp(title->b, "HISTORY") == 0)
                    154:                        later = NULL;
                    155:                else if ((strcasecmp(title->b, "CAVEATS") == 0 ||
                    156:                    strcasecmp(title->b, "BUGS") == 0) &&
                    157:                    later == NULL)
                    158:                        later = nc;
                    159:        }
                    160:
                    161:        /*
                    162:         * If no AUTHORS section was found, create one from scratch,
                    163:         * and insert that at the place selected earlier.
                    164:         */
                    165:
                    166:        if (match == NULL) {
                    167:                match = pnode_alloc(NULL);
                    168:                match->node = NODE_SECTION;
                    169:                match->flags |= NFLAG_SPC;
                    170:                match->parent = n;
                    171:                nc = pnode_alloc(match);
                    172:                nc->node = NODE_TITLE;
                    173:                nc->flags |= NFLAG_SPC;
                    174:                nc = pnode_alloc_text(nc, "AUTHORS");
                    175:                nc->flags |= NFLAG_SPC;
                    176:                if (later == NULL)
                    177:                        TAILQ_INSERT_TAIL(&n->childq, match, child);
                    178:                else
                    179:                        TAILQ_INSERT_BEFORE(later, match, child);
                    180:        }
                    181:
                    182:        /*
                    183:         * Dump the stuff excised at the beginning
                    184:         * into this AUTHORS section.
                    185:         */
                    186:
                    187:        if (info != NULL)
                    188:                TAILQ_INSERT_TAIL(&match->childq, info, child);
                    189:        if (meta != NULL)
                    190:                TAILQ_INSERT_TAIL(&match->childq, meta, child);
                    191: }
                    192:
                    193: static void
1.2       schwarze  194: default_title(struct pnode *n, const char *title)
                    195: {
                    196:        struct pnode    *nc;
                    197:
                    198:        if (n->parent == NULL)
                    199:                return;
                    200:
                    201:        TAILQ_FOREACH(nc, &n->childq, child)
                    202:                if (nc->node == NODE_TITLE)
                    203:                        return;
                    204:
                    205:        nc = pnode_alloc(NULL);
                    206:        nc->node = NODE_TITLE;
                    207:        nc->parent = n;
                    208:        TAILQ_INSERT_HEAD(&n->childq, nc, child);
                    209:        pnode_alloc_text(nc, title);
                    210: }
                    211:
                    212: static void
                    213: reorg_recurse(struct pnode *n)
                    214: {
                    215:        struct pnode    *nc;
                    216:
                    217:        if (n == NULL)
                    218:                return;
                    219:
                    220:        switch (n->node) {
1.4     ! schwarze  221:        case NODE_ABSTRACT:
        !           222:                default_title(n, "Abstract");
        !           223:                n->node = NODE_SECTION;
        !           224:                break;
1.2       schwarze  225:        case NODE_APPENDIX:
1.3       schwarze  226:                if (n->parent == NULL)
                    227:                        reorg_refentry(n);
1.2       schwarze  228:                default_title(n, "Appendix");
                    229:                break;
                    230:        case NODE_CAUTION:
                    231:                default_title(n, "Caution");
                    232:                n->node = NODE_NOTE;
                    233:                break;
                    234:        case NODE_LEGALNOTICE:
                    235:                default_title(n, "Legal Notice");
                    236:                n->node = NODE_SIMPLESECT;
                    237:                break;
                    238:        case NODE_NOTE:
                    239:                default_title(n, "Note");
                    240:                break;
                    241:        case NODE_PREFACE:
1.3       schwarze  242:                if (n->parent == NULL)
                    243:                        reorg_refentry(n);
1.2       schwarze  244:                default_title(n, "Preface");
                    245:                n->node = NODE_SECTION;
                    246:                break;
1.3       schwarze  247:        case NODE_REFENTRY:
                    248:                reorg_refentry(n);
                    249:                break;
1.2       schwarze  250:        case NODE_SECTION:
1.3       schwarze  251:                if (n->parent == NULL)
                    252:                        reorg_refentry(n);
                    253:                /* FALLTHROUGH */
1.2       schwarze  254:        case NODE_SIMPLESECT:
                    255:                default_title(n, "Untitled");
                    256:                break;
                    257:        case NODE_TIP:
                    258:                default_title(n, "Tip");
                    259:                n->node = NODE_NOTE;
                    260:                break;
                    261:        case NODE_WARNING:
                    262:                default_title(n, "Warning");
                    263:                n->node = NODE_NOTE;
                    264:                break;
                    265:        default:
                    266:                break;
                    267:        }
                    268:
                    269:        TAILQ_FOREACH(nc, &n->childq, child)
                    270:                reorg_recurse(nc);
                    271: }
                    272:
                    273: void
                    274: ptree_reorg(struct ptree *tree)
                    275: {
1.3       schwarze  276:        reorg_root(tree->root);
1.2       schwarze  277:        reorg_recurse(tree->root);
1.1       schwarze  278: }

CVSweb