fixref.gawk 3.6 KB

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