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