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