xref: /netbsd-src/external/gpl2/texinfo/dist/util/fixref.gawk (revision 29619d2afe564e54d657b83e5a3ae89584f83720)
1*29619d2aSchristos#! /usr/local/bin/gawk -f
2*29619d2aSchristos
3*29619d2aSchristos# fixref.awk --- fix xrefs in texinfo documents
4*29619d2aSchristos# Copyright, 1991, Arnold David Robbins, arnold@skeeve.atl.ga.us
5*29619d2aSchristos# Copyright, 1998, Arnold David Robbins, arnold@gnu.org
6*29619d2aSchristos
7*29619d2aSchristos# FIXREF is free software; you can redistribute it and/or modify
8*29619d2aSchristos# it under the terms of the GNU General Public License as published by
9*29619d2aSchristos# the Free Software Foundation; either version 2 of the License, or
10*29619d2aSchristos# (at your option) any later version.
11*29619d2aSchristos#
12*29619d2aSchristos# FIXREF is distributed in the hope that it will be useful,
13*29619d2aSchristos# but WITHOUT ANY WARRANTY; without even the implied warranty of
14*29619d2aSchristos# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*29619d2aSchristos# GNU General Public License for more details.
16*29619d2aSchristos#
17*29619d2aSchristos# You should have received a copy of the GNU General Public License
18*29619d2aSchristos# along with this program; if not, write to the Free Software
19*29619d2aSchristos# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
20*29619d2aSchristos
21*29619d2aSchristos# Updated: Jul 21  1992	--- change unknown
22*29619d2aSchristos# Updated: Jul 18  1997 --- bug fix
23*29619d2aSchristos
24*29619d2aSchristos# usage:		gawk -f fixref.awk input-file > output-file
25*29619d2aSchristos# or if you have #!:	fixref.awk input-file > output-file
26*29619d2aSchristos
27*29619d2aSchristos# Limitations:
28*29619d2aSchristos#	1. no more than one cross reference on a line
29*29619d2aSchristos#	2. cross references may not cross a newline
30*29619d2aSchristos
31*29619d2aSchristosBEGIN	\
32*29619d2aSchristos{
33*29619d2aSchristos	# we make two passes over the file.  To do that we artificially
34*29619d2aSchristos	# tweak the argument vector to do a variable assignment
35*29619d2aSchristos
36*29619d2aSchristos	if (ARGC != 2) {
37*29619d2aSchristos		printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr"
38*29619d2aSchristos		exit 1
39*29619d2aSchristos	}
40*29619d2aSchristos	ARGV[2] = "pass=2"
41*29619d2aSchristos	ARGV[3] = ARGV[1]
42*29619d2aSchristos	ARGC = 4
43*29619d2aSchristos
44*29619d2aSchristos	# examine paragraphs
45*29619d2aSchristos	RS = ""
46*29619d2aSchristos
47*29619d2aSchristos	heading = "@(chapter|appendix|unnumbered|(appendix(sec|subsec|subsubsec))|section|subsection|subsubsection|unnumberedsec|heading|top)"
48*29619d2aSchristos
49*29619d2aSchristos	pass = 1
50*29619d2aSchristos
51*29619d2aSchristos	# put space between paragraphs on output
52*29619d2aSchristos	ORS = "\n\n"
53*29619d2aSchristos}
54*29619d2aSchristos
55*29619d2aSchristospass == 1 && NF == 0	{ next }
56*29619d2aSchristos
57*29619d2aSchristos# pass == 1 && /@node/	\
58*29619d2aSchristos# bug fix 7/18/96
59*29619d2aSchristospass == 1 && /^@node/	\
60*29619d2aSchristos{
61*29619d2aSchristos	lname = name = ""
62*29619d2aSchristos	n = split($0, lines, "\n")
63*29619d2aSchristos	for (i = 1; i <= n; i++) {
64*29619d2aSchristos		if (lines[i] ~ ("^" heading)) {
65*29619d2aSchristos			sub(heading, "", lines[i])
66*29619d2aSchristos			sub(/^[ \t]*/, "", lines[i])
67*29619d2aSchristos			lname = lines[i]
68*29619d2aSchristos#			printf "long name is '%s'\n", lines[i]
69*29619d2aSchristos		} else if (lines[i] ~ /@node/) {
70*29619d2aSchristos			sub(/@node[ \t]*/, "", lines[i])
71*29619d2aSchristos			sub(/[ \t]*,.*$/, "", lines[i])
72*29619d2aSchristos			name = lines[i]
73*29619d2aSchristos#			printf "node name is '%s'\n", lines[i]
74*29619d2aSchristos		}
75*29619d2aSchristos	}
76*29619d2aSchristos	if (name && lname)
77*29619d2aSchristos		names[name] = lname
78*29619d2aSchristos	else if (lname)
79*29619d2aSchristos		printf("node name for %s missing!\n", lname) > "/dev/stderr"
80*29619d2aSchristos	else
81*29619d2aSchristos		printf("long name for %s missing!\n", name) > "/dev/stderr"
82*29619d2aSchristos
83*29619d2aSchristos	if (name ~ /:/)
84*29619d2aSchristos		printf("node `%s' contains a `:'\n", name) > "/dev/stderr"
85*29619d2aSchristos
86*29619d2aSchristos	if (lname) {
87*29619d2aSchristos		if (lname ~ /:/)
88*29619d2aSchristos			printf("name `%s' contains a `:'\n", lname) > "/dev/stderr"
89*29619d2aSchristos		else if (lname ~ /,/) {
90*29619d2aSchristos			printf("name `%s' contains a `,'\n", lname) > "/dev/stderr"
91*29619d2aSchristos			gsub(/,/, " ", lname)
92*29619d2aSchristos			names[name] = lname	# added 7/18/97
93*29619d2aSchristos		}
94*29619d2aSchristos	}
95*29619d2aSchristos}
96*29619d2aSchristos
97*29619d2aSchristospass == 2 && /@(x|px)?ref{/	\
98*29619d2aSchristos{
99*29619d2aSchristos	# split the paragraph into lines
100*29619d2aSchristos	# write them out one by one after fixing them
101*29619d2aSchristos	n = split($0, lines, "\n")
102*29619d2aSchristos	for (i = 1; i <= n; i++)
103*29619d2aSchristos		if (lines[i] ~ /@(x|px)?ref{/) {
104*29619d2aSchristos			res = updateref(lines[i])
105*29619d2aSchristos			printf "%s\n", res
106*29619d2aSchristos		} else
107*29619d2aSchristos			printf "%s\n", lines[i]
108*29619d2aSchristos
109*29619d2aSchristos	printf "\n"	# avoid ORS
110*29619d2aSchristos	next
111*29619d2aSchristos}
112*29619d2aSchristos
113*29619d2aSchristosfunction updateref(orig,	refkind, line)
114*29619d2aSchristos{
115*29619d2aSchristos	line = orig	# work on a copy
116*29619d2aSchristos
117*29619d2aSchristos	# find the beginning of the reference
118*29619d2aSchristos	match(line, "@(x|px)?ref{")
119*29619d2aSchristos	refkind = substr(line, RSTART, RLENGTH)
120*29619d2aSchristos
121*29619d2aSchristos	# pull out just the node name
122*29619d2aSchristos	sub(/.*ref{/, "", line)
123*29619d2aSchristos	sub(/}.*$/, "", line)
124*29619d2aSchristos	sub(/,.*/, "", line)
125*29619d2aSchristos
126*29619d2aSchristos#	debugging
127*29619d2aSchristos#	printf("found ref to node '%s'\n", line) > "/dev/stderr"
128*29619d2aSchristos
129*29619d2aSchristos	# If the node name and the section name are the same
130*29619d2aSchristos	# we don't want to bother doing this.
131*29619d2aSchristos
132*29619d2aSchristos	if (! (line in names))	# sanity checking
133*29619d2aSchristos		printf("no long name for %s\n", line) > "/dev/stderr"
134*29619d2aSchristos	else if (names[line] != line && names[line] !~ /[:,]/) {
135*29619d2aSchristos		# build up new ref
136*29619d2aSchristos		newref = refkind line ", ," names[line] "}"
137*29619d2aSchristos		pat = refkind line "[^}]*}"
138*29619d2aSchristos
139*29619d2aSchristos		sub(pat, newref, orig)
140*29619d2aSchristos	}
141*29619d2aSchristos
142*29619d2aSchristos	return orig
143*29619d2aSchristos}
144*29619d2aSchristos
145*29619d2aSchristospass == 2	{ print }
146