source: trunk/essentials/sys-apps/texinfo/util/prepinfo.awk

Last change on this file was 2617, checked in by bird, 19 years ago

GNU Texinfo 4.8

File size: 8.1 KB
Line 
1#! /usr/local/bin/gawk -f
2
3# prepinfo.awk --- fix node lines and menus
4#
5# Copyright, 1998, Arnold Robbins, arnold@gnu.org
6#
7# PREPINFO is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# PREPINFO is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20
21BEGIN \
22{
23 # manifest constants
24 TRUE = 1
25 FALSE = 0
26
27 # Levels at which different nodes can be
28 Level["@top"] = 0
29 Level["@appendix"] = 1
30 Level["@chapter"] = 1
31 Level["@majorheading"] = 1
32 Level["@unnumbered"] = 1
33 Level["@appendixsec"] = 2
34 Level["@heading"] = 2
35 Level["@section"] = 2
36 Level["@unnumberedsec"] = 2
37 Level["@unnumberedsubsec"] = 3
38 Level["@appendixsubsec"] = 3
39 Level["@subheading"] = 3
40 Level["@subsection"] = 3
41 Level["@appendixsubsubsec"] = 4
42 Level["@subsubheading"] = 4
43 Level["@subsubsection"] = 4
44 Level["@unnumberedsubsubsec"] = 4
45
46 # Length of menus
47 Menumargin = 78
48
49 # Length of menu item
50 Min_menitem_length = 29
51
52 # insure that we were called correctly
53 if (ARGC != 2) {
54 printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr"
55 exit 1
56 }
57
58 # Arrange for two passes over input file
59 Pass = 1
60 ARGV[2] = "Pass=2"
61 ARGV[3] = ARGV[1]
62 ARGC = 4
63 Lastlevel = -1
64
65 # Initialize stacks
66 Up[-1] = "(dir)"
67 Prev[0] = "(dir)"
68
69 if (Debug == "args") {
70 for (i = 0; i < ARGC; i++)
71 printf("ARGV[%d] = %s\n", i, ARGV[i]) > "/dev/stderr"
72 }
73}
74
75$1 == "@node" \
76{
77 Name = getnodename($0)
78 Nodeseen = TRUE
79
80 if ((l = length(Name)) > Maxlen)
81 Maxlen = l
82
83 if (Debug == "nodenames")
84 printf("Name = %s\n", Name) > "/dev/stderr"
85
86 if (Pass == 1)
87 next
88}
89
90Pass == 1 && /^@c(omment)?[ \t]+fakenode/ \
91{
92 if (Debug == "fakenodes")
93 printf("fakenode at %d\n", FNR) > "/dev/stderr"
94 Fakenode = TRUE
95 next
96}
97
98Pass == 1 && ($1 in Level) \
99{
100 # skip fake nodes --- titles without associated @node lines
101 if (Fakenode) {
102 if (Debug == "fakenodes")
103 printf("%s at %d is a fakenode\n", $1, FNR) > "/dev/stderr"
104 Fakenode = FALSE
105 next
106 }
107
108 if (Debug == "titles")
109 printf("Processing %s: Name = %s\n", $1, Name) > "/dev/stderr"
110
111 # save type
112 type = $1
113
114 if (! Nodeseen) {
115 err_prefix()
116 printf("%s line with no @node or fakenode line\n",
117 type) > "/dev/stderr"
118 Badheading[FNR] = 1
119 # ??? used ???
120 next
121 } else
122 Nodeseen = FALSE # reset it
123
124 # Squirrel away the info
125 levelnum = Level[type]
126 Node[Name ".level"] = levelnum
127 Node[Name ".name"] = Name
128 if (Debug == "titles") {
129 printf("Node[%s\".level\"] = %s\n", Name, Node[Name ".level"]) > "/dev/stderr"
130 printf("Node[%s\".name\"] = %s\n", Name, Node[Name ".name"]) > "/dev/stderr"
131 }
132
133 if (levelnum == Lastlevel) { # e.g., two sections in a row
134 Node[Name ".up"] = Up[levelnum - 1]
135 if (levelnum in Prev) {
136 Node[Prev[levelnum] ".next"] = Name
137 Node[Name ".prev"] = Prev[levelnum]
138 }
139 Prev[levelnum] = Name
140 Up[levelnum] = Name # ???
141 } else if (levelnum < Lastlevel) { # section, now chapter
142 Lastlevel = levelnum
143 Node[Name ".up"] = Up[levelnum - 1]
144 if (levelnum in Prev) {
145 Node[Name ".prev"] = Prev[levelnum]
146 Node[Prev[levelnum] ".next"] = Name
147 }
148 Prev[levelnum] = Name
149 Up[levelnum] = Name
150 } else { # chapter, now section, levelnum > Lastlevel
151 Node[Name ".up"] = Up[levelnum - 1]
152 Node[Up[Lastlevel] ".child"] = Name
153 Up[levelnum] = Name
154 Prev[levelnum] = Name
155 Lastlevel = levelnum
156 }
157
158 # For master menu
159 if (Level[$1] >= 2)
160 List[++Sequence] = Name
161
162 if (Debug == "titles") {
163 printf("Node[%s\".prev\"] = %s\n", Name, Node[Name ".prev"]) > "/dev/stderr"
164 printf("Node[%s\".up\"] = %s\n", Name, Node[Name ".up"]) > "/dev/stderr"
165 printf("Node[%s\".child\"] = %s\n", Name, Node[Name ".child"]) > "/dev/stderr"
166 }
167}
168
169Pass == 2 && Debug == "dumptitles" && FNR <= 1 \
170{
171 for (i in Node)
172 printf("Node[%s] = %s\n", i, Node[i]) | "sort 1>&2"
173 close("sort 1>&2")
174}
175
176/^@menu/ && Pass == 1, /^@end[ \t]+menu/ && Pass == 1 \
177{
178 if (/^@menu/ || /^@end[ \t]+menu/)
179 next
180
181# if (Debug == "menu")
182# printf("processing: %s\n", $0) > "/dev/stderr"
183
184 if (/^\*/) {
185 if (In_menitem) { # file away info from previousline
186 Node[node ".mendesc"] = desc
187 Node[node ".longdesc"] = longdesc
188 if (Debug == "mendesc") {
189 printf("Node[%s.mendesc] = %s\n",
190 node, Node[node ".mendesc"]) > "/dev/stderr"
191 printf("Node[%s.longdesc] = %s\n",
192 node, Node[node ".longdesc"]) > "/dev/stderr"
193 }
194 }
195 In_menitem = TRUE
196
197 # pull apart menu item
198 $1 = "" # nuke ``*''
199 $0 = $0 # reparse line
200 i1 = index($0, ":")
201 if (i1 <= 0) {
202 err_prefix()
203 printf("badly formed menu item") > "/dev/stderr"
204 next
205 }
206 if (substr($0, i1+1, 1) != ":") { # desc: node. long desc
207 i2 = index($0, ".")
208 if (i2 <= 0) {
209 err_prefix()
210 printf("badly formed menu item") > "/dev/stderr"
211 next
212 }
213 desc = substr($0, 1, i1 - 1)
214 sub(/^[ \t]+/, "", node)
215 sub(/[ \t]+$/, "", node)
216 longdesc = substr($0, i2 + 1)
217 } else { # nodname:: long desc
218 desc = ""
219 node = substr($0, 1, i1 - 1)
220 sub(/^[ \t]+/, "", node)
221 sub(/[ \t]+$/, "", node)
222 longdesc = substr($0, i1 + 2)
223 }
224 } else if (In_menitem) { # continuation line
225 longdesc = longdesc " " $0
226 } else
227 In_menitem = FALSE
228
229 Node[node ".mendesc"] = desc
230 Node[node ".longdesc"] = longdesc
231 if (Debug == "mendesc") {
232 printf("Node[%s.mendesc] = %s\n",
233 node, Node[node ".mendesc"]) > "/dev/stderr"
234 printf("Node[%s.longdesc] = %s\n",
235 node, Node[node ".longdesc"]) > "/dev/stderr"
236 }
237
238 if (Debug == "menu")
239 printf("Menu:: Name %s: desc %s: longdesc %s\n",
240 node, desc, longdesc) > "/dev/stderr"
241}
242
243function err_prefix()
244{
245 printf("%s: %s: %d: ", ARGV[0], FILENAME, FNR) > "/dev/stderr"
246}
247
248function getnodename(str)
249{
250 sub(/@node[ \t]+/, "", str)
251 sub(/,.*/, "", str)
252 if (Debug == "nodenames")
253 printf("getnodename: return %s\n", str) > "/dev/stderr"
254 return str
255}
256
257Pass == 2 && /^@node/ \
258{
259 Name = getnodename($0)
260
261 # Top node is special. It's next is the first child
262 n = Node[Name ".next"]
263 if (Node[Name ".level"] == 0 && n == "")
264 n = Node[Name ".child"]
265
266 printf("@node %s, %s, %s, %s\n", Name, n,
267 Node[Name ".prev"] ? Node[Name ".prev"] : Node[Name ".up"],
268 Node[Name ".up"])
269 next
270}
271
272Pass == 2 && /^@menu/ \
273{
274 # First, nuke current contents of menu
275 do {
276 if ((getline) <= 0) {
277 err_prefix()
278 printf("unexpected EOF inside menu\n") > "/dev/stderr"
279 exit 1
280 }
281 } while (! /^@end[ \t]+menu/)
282
283 # next, compute maximum length of a node name
284 max = 0
285 for (n = Node[Name ".child"]; (n ".next") in Node; n = Node[n ".next"]) {
286 if ((n ".desc") in Node)
287 s = Node[n ".desc"] ": " n "."
288 else
289 s = n "::"
290 l = length(s)
291 if (l > max)
292 max = l
293 }
294 if (max < Min_menitem_length)
295 max = Min_menitem_length
296
297 # now dump the menu
298 print "@menu"
299
300 for (n = Node[Name ".child"]; (n ".next") in Node; n = Node[n ".next"]) {
301 print_menuitem(n, max)
302 }
303 print_menuitem(n, max)
304
305 if (Name == "Top") { # Master Menu
306 if (Maxlen < Min_menitem_length)
307 Maxlen = Min_menitem_length
308 print ""
309 for (i = 1; i <= Sequence; i++)
310 print_menuitem(List[i], Maxlen)
311 print ""
312 }
313 print "@end menu"
314 next
315}
316
317Pass == 2 # print
318
319
320function print_menuitem(n, max, nodesc, i, dwords, count, p)
321{
322 nodesc = FALSE
323 if (! ((n ".longdesc") in Node)) {
324 err_prefix()
325 printf("warning: %s: no long description\n", n) > "/dev/stderr"
326 nodesc = TRUE
327 } else {
328 for (i in dwords)
329 delete dwords[i]
330 count = split(Node[n ".longdesc"], dwords, "[ \t\n]+")
331 }
332 if ((n ".desc") in Node)
333 s = Node[n ".desc"] ": " n "."
334 else
335 s = n "::"
336 printf("* %-*s", max, s)
337
338 if (Debug == "mendescitem")
339 printf("<* %-*s>\n", max, s) > "/dev/stderr"
340
341 p = max + 2
342 if (! nodesc) {
343 for (i = 1; i <= count; i++) {
344 l = length(dwords[i])
345 if (l == 0)
346 continue
347 if (p + l + 1 > Menumargin) {
348 printf("\n%*s", max + 2, " ")
349 p = max + 2
350 }
351 printf(" %s", dwords[i])
352 p += l + 1
353 }
354 }
355 print ""
356}
Note: See TracBrowser for help on using the repository browser.