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