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