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