357 lines
8.1 KiB
Awk
357 lines
8.1 KiB
Awk
#! /usr/local/bin/gawk -f
|
|
|
|
# prepinfo.awk --- fix node lines and menus
|
|
#
|
|
# Copyright, 1998, Arnold Robbins, arnold@gnu.org
|
|
#
|
|
# PREPINFO is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# PREPINFO is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
|
|
BEGIN \
|
|
{
|
|
# manifest constants
|
|
TRUE = 1
|
|
FALSE = 0
|
|
|
|
# Levels at which different nodes can be
|
|
Level["@top"] = 0
|
|
Level["@appendix"] = 1
|
|
Level["@chapter"] = 1
|
|
Level["@majorheading"] = 1
|
|
Level["@unnumbered"] = 1
|
|
Level["@appendixsec"] = 2
|
|
Level["@heading"] = 2
|
|
Level["@section"] = 2
|
|
Level["@unnumberedsec"] = 2
|
|
Level["@unnumberedsubsec"] = 3
|
|
Level["@appendixsubsec"] = 3
|
|
Level["@subheading"] = 3
|
|
Level["@subsection"] = 3
|
|
Level["@appendixsubsubsec"] = 4
|
|
Level["@subsubheading"] = 4
|
|
Level["@subsubsection"] = 4
|
|
Level["@unnumberedsubsubsec"] = 4
|
|
|
|
# Length of menus
|
|
Menumargin = 78
|
|
|
|
# Length of menu item
|
|
Min_menitem_length = 29
|
|
|
|
# insure that we were called correctly
|
|
if (ARGC != 2) {
|
|
printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr"
|
|
exit 1
|
|
}
|
|
|
|
# Arrange for two passes over input file
|
|
Pass = 1
|
|
ARGV[2] = "Pass=2"
|
|
ARGV[3] = ARGV[1]
|
|
ARGC = 4
|
|
Lastlevel = -1
|
|
|
|
# Initialize stacks
|
|
Up[-1] = "(dir)"
|
|
Prev[0] = "(dir)"
|
|
|
|
if (Debug == "args") {
|
|
for (i = 0; i < ARGC; i++)
|
|
printf("ARGV[%d] = %s\n", i, ARGV[i]) > "/dev/stderr"
|
|
}
|
|
}
|
|
|
|
$1 == "@node" \
|
|
{
|
|
Name = getnodename($0)
|
|
Nodeseen = TRUE
|
|
|
|
if ((l = length(Name)) > Maxlen)
|
|
Maxlen = l
|
|
|
|
if (Debug == "nodenames")
|
|
printf("Name = %s\n", Name) > "/dev/stderr"
|
|
|
|
if (Pass == 1)
|
|
next
|
|
}
|
|
|
|
Pass == 1 && /^@c(omment)?[ \t]+fakenode/ \
|
|
{
|
|
if (Debug == "fakenodes")
|
|
printf("fakenode at %d\n", FNR) > "/dev/stderr"
|
|
Fakenode = TRUE
|
|
next
|
|
}
|
|
|
|
Pass == 1 && ($1 in Level) \
|
|
{
|
|
# skip fake nodes --- titles without associated @node lines
|
|
if (Fakenode) {
|
|
if (Debug == "fakenodes")
|
|
printf("%s at %d is a fakenode\n", $1, FNR) > "/dev/stderr"
|
|
Fakenode = FALSE
|
|
next
|
|
}
|
|
|
|
if (Debug == "titles")
|
|
printf("Processing %s: Name = %s\n", $1, Name) > "/dev/stderr"
|
|
|
|
# save type
|
|
type = $1
|
|
|
|
if (! Nodeseen) {
|
|
err_prefix()
|
|
printf("%s line with no @node or fakenode line\n",
|
|
type) > "/dev/stderr"
|
|
Badheading[FNR] = 1
|
|
# ??? used ???
|
|
next
|
|
} else
|
|
Nodeseen = FALSE # reset it
|
|
|
|
# Squirrel away the info
|
|
levelnum = Level[type]
|
|
Node[Name ".level"] = levelnum
|
|
Node[Name ".name"] = Name
|
|
if (Debug == "titles") {
|
|
printf("Node[%s\".level\"] = %s\n", Name, Node[Name ".level"]) > "/dev/stderr"
|
|
printf("Node[%s\".name\"] = %s\n", Name, Node[Name ".name"]) > "/dev/stderr"
|
|
}
|
|
|
|
if (levelnum == Lastlevel) { # e.g., two sections in a row
|
|
Node[Name ".up"] = Up[levelnum - 1]
|
|
if (levelnum in Prev) {
|
|
Node[Prev[levelnum] ".next"] = Name
|
|
Node[Name ".prev"] = Prev[levelnum]
|
|
}
|
|
Prev[levelnum] = Name
|
|
Up[levelnum] = Name # ???
|
|
} else if (levelnum < Lastlevel) { # section, now chapter
|
|
Lastlevel = levelnum
|
|
Node[Name ".up"] = Up[levelnum - 1]
|
|
if (levelnum in Prev) {
|
|
Node[Name ".prev"] = Prev[levelnum]
|
|
Node[Prev[levelnum] ".next"] = Name
|
|
}
|
|
Prev[levelnum] = Name
|
|
Up[levelnum] = Name
|
|
} else { # chapter, now section, levelnum > Lastlevel
|
|
Node[Name ".up"] = Up[levelnum - 1]
|
|
Node[Up[Lastlevel] ".child"] = Name
|
|
Up[levelnum] = Name
|
|
Prev[levelnum] = Name
|
|
Lastlevel = levelnum
|
|
}
|
|
|
|
# For master menu
|
|
if (Level[$1] >= 2)
|
|
List[++Sequence] = Name
|
|
|
|
if (Debug == "titles") {
|
|
printf("Node[%s\".prev\"] = %s\n", Name, Node[Name ".prev"]) > "/dev/stderr"
|
|
printf("Node[%s\".up\"] = %s\n", Name, Node[Name ".up"]) > "/dev/stderr"
|
|
printf("Node[%s\".child\"] = %s\n", Name, Node[Name ".child"]) > "/dev/stderr"
|
|
}
|
|
}
|
|
|
|
Pass == 2 && Debug == "dumptitles" && FNR <= 1 \
|
|
{
|
|
for (i in Node)
|
|
printf("Node[%s] = %s\n", i, Node[i]) | "sort 1>&2"
|
|
close("sort 1>&2")
|
|
}
|
|
|
|
/^@menu/ && Pass == 1, /^@end[ \t]+menu/ && Pass == 1 \
|
|
{
|
|
if (/^@menu/ || /^@end[ \t]+menu/)
|
|
next
|
|
|
|
# if (Debug == "menu")
|
|
# printf("processing: %s\n", $0) > "/dev/stderr"
|
|
|
|
if (/^\*/) {
|
|
if (In_menitem) { # file away info from previousline
|
|
Node[node ".mendesc"] = desc
|
|
Node[node ".longdesc"] = longdesc
|
|
if (Debug == "mendesc") {
|
|
printf("Node[%s.mendesc] = %s\n",
|
|
node, Node[node ".mendesc"]) > "/dev/stderr"
|
|
printf("Node[%s.longdesc] = %s\n",
|
|
node, Node[node ".longdesc"]) > "/dev/stderr"
|
|
}
|
|
}
|
|
In_menitem = TRUE
|
|
|
|
# pull apart menu item
|
|
$1 = "" # nuke ``*''
|
|
$0 = $0 # reparse line
|
|
i1 = index($0, ":")
|
|
if (i1 <= 0) {
|
|
err_prefix()
|
|
printf("badly formed menu item") > "/dev/stderr"
|
|
next
|
|
}
|
|
if (substr($0, i1+1, 1) != ":") { # desc: node. long desc
|
|
i2 = index($0, ".")
|
|
if (i2 <= 0) {
|
|
err_prefix()
|
|
printf("badly formed menu item") > "/dev/stderr"
|
|
next
|
|
}
|
|
desc = substr($0, 1, i1 - 1)
|
|
sub(/^[ \t]+/, "", node)
|
|
sub(/[ \t]+$/, "", node)
|
|
longdesc = substr($0, i2 + 1)
|
|
} else { # nodname:: long desc
|
|
desc = ""
|
|
node = substr($0, 1, i1 - 1)
|
|
sub(/^[ \t]+/, "", node)
|
|
sub(/[ \t]+$/, "", node)
|
|
longdesc = substr($0, i1 + 2)
|
|
}
|
|
} else if (In_menitem) { # continuation line
|
|
longdesc = longdesc " " $0
|
|
} else
|
|
In_menitem = FALSE
|
|
|
|
Node[node ".mendesc"] = desc
|
|
Node[node ".longdesc"] = longdesc
|
|
if (Debug == "mendesc") {
|
|
printf("Node[%s.mendesc] = %s\n",
|
|
node, Node[node ".mendesc"]) > "/dev/stderr"
|
|
printf("Node[%s.longdesc] = %s\n",
|
|
node, Node[node ".longdesc"]) > "/dev/stderr"
|
|
}
|
|
|
|
if (Debug == "menu")
|
|
printf("Menu:: Name %s: desc %s: longdesc %s\n",
|
|
node, desc, longdesc) > "/dev/stderr"
|
|
}
|
|
|
|
function err_prefix()
|
|
{
|
|
printf("%s: %s: %d: ", ARGV[0], FILENAME, FNR) > "/dev/stderr"
|
|
}
|
|
|
|
function getnodename(str)
|
|
{
|
|
sub(/@node[ \t]+/, "", str)
|
|
sub(/,.*/, "", str)
|
|
if (Debug == "nodenames")
|
|
printf("getnodename: return %s\n", str) > "/dev/stderr"
|
|
return str
|
|
}
|
|
|
|
Pass == 2 && /^@node/ \
|
|
{
|
|
Name = getnodename($0)
|
|
|
|
# Top node is special. It's next is the first child
|
|
n = Node[Name ".next"]
|
|
if (Node[Name ".level"] == 0 && n == "")
|
|
n = Node[Name ".child"]
|
|
|
|
printf("@node %s, %s, %s, %s\n", Name, n,
|
|
Node[Name ".prev"] ? Node[Name ".prev"] : Node[Name ".up"],
|
|
Node[Name ".up"])
|
|
next
|
|
}
|
|
|
|
Pass == 2 && /^@menu/ \
|
|
{
|
|
# First, nuke current contents of menu
|
|
do {
|
|
if ((getline) <= 0) {
|
|
err_prefix()
|
|
printf("unexpected EOF inside menu\n") > "/dev/stderr"
|
|
exit 1
|
|
}
|
|
} while (! /^@end[ \t]+menu/)
|
|
|
|
# next, compute maximum length of a node name
|
|
max = 0
|
|
for (n = Node[Name ".child"]; (n ".next") in Node; n = Node[n ".next"]) {
|
|
if ((n ".desc") in Node)
|
|
s = Node[n ".desc"] ": " n "."
|
|
else
|
|
s = n "::"
|
|
l = length(s)
|
|
if (l > max)
|
|
max = l
|
|
}
|
|
if (max < Min_menitem_length)
|
|
max = Min_menitem_length
|
|
|
|
# now dump the menu
|
|
print "@menu"
|
|
|
|
for (n = Node[Name ".child"]; (n ".next") in Node; n = Node[n ".next"]) {
|
|
print_menuitem(n, max)
|
|
}
|
|
print_menuitem(n, max)
|
|
|
|
if (Name == "Top") { # Master Menu
|
|
if (Maxlen < Min_menitem_length)
|
|
Maxlen = Min_menitem_length
|
|
print ""
|
|
for (i = 1; i <= Sequence; i++)
|
|
print_menuitem(List[i], Maxlen)
|
|
print ""
|
|
}
|
|
print "@end menu"
|
|
next
|
|
}
|
|
|
|
Pass == 2 # print
|
|
|
|
|
|
function print_menuitem(n, max, nodesc, i, dwords, count, p)
|
|
{
|
|
nodesc = FALSE
|
|
if (! ((n ".longdesc") in Node)) {
|
|
err_prefix()
|
|
printf("warning: %s: no long description\n", n) > "/dev/stderr"
|
|
nodesc = TRUE
|
|
} else {
|
|
for (i in dwords)
|
|
delete dwords[i]
|
|
count = split(Node[n ".longdesc"], dwords, "[ \t\n]+")
|
|
}
|
|
if ((n ".desc") in Node)
|
|
s = Node[n ".desc"] ": " n "."
|
|
else
|
|
s = n "::"
|
|
printf("* %-*s", max, s)
|
|
|
|
if (Debug == "mendescitem")
|
|
printf("<* %-*s>\n", max, s) > "/dev/stderr"
|
|
|
|
p = max + 2
|
|
if (! nodesc) {
|
|
for (i = 1; i <= count; i++) {
|
|
l = length(dwords[i])
|
|
if (l == 0)
|
|
continue
|
|
if (p + l + 1 > Menumargin) {
|
|
printf("\n%*s", max + 2, " ")
|
|
p = max + 2
|
|
}
|
|
printf(" %s", dwords[i])
|
|
p += l + 1
|
|
}
|
|
}
|
|
print ""
|
|
}
|