summaryrefslogtreecommitdiff
path: root/web/noweb/contrib/rsc/rc/noindex.nw
diff options
context:
space:
mode:
Diffstat (limited to 'web/noweb/contrib/rsc/rc/noindex.nw')
-rw-r--r--web/noweb/contrib/rsc/rc/noindex.nw194
1 files changed, 194 insertions, 0 deletions
diff --git a/web/noweb/contrib/rsc/rc/noindex.nw b/web/noweb/contrib/rsc/rc/noindex.nw
new file mode 100644
index 0000000000..193f2c6429
--- /dev/null
+++ b/web/noweb/contrib/rsc/rc/noindex.nw
@@ -0,0 +1,194 @@
+This program is similar to [[makeindex]] in that it grovels through [[.aux]]
+files looking for index information, which it writes to a [[.nwi]] file.
+It's used when [[noweave -indexfrom]] is used on many files separately;
+it combines the separate indices into a single, correctly sorted index.
+That index file is read by [[\nowebindex*]].
+<<noindex>>=
+#!/bin/rc
+#
+# Translated to rc by Russ Cox
+# bugs -> rsc@plan9.bell-labs.com
+
+if(! ~ $#* 1) {
+ echo 'Usage: '^`{basename $0}^' file[.tex]' >[1=2]
+ exit usage
+}
+
+awk -f /sys/lib/noweb/noindex.awk >[1=2]
+
+<<noindex.awk>>=
+BEGIN { infile="'"$1"'"
+ <<main code>>
+ exit
+}
+<<functions>>
+<<main code>>=
+if (infile ~ /\.tex$/) {
+ infile = substr(infile, 1, length(infile)-4) ".aux"
+} else if (infile !~ /\.aux$/) {
+ infile = infile ".aux"
+}
+idx[0] = ""
+delete idx[0]
+gobble(infile)
+alphasort(idx)
+outname = substr(infile, 1, length(infile)-4) ".nwi"
+last = ""
+for (i = 0; i < count; i++) {
+ out = stripcount(sorted[i])
+ if (last != out) {
+ print out > outname
+ last = out
+# <show sort key [[i]]>
+ }
+}
+<<show sort key [[i]]>>=
+key = sortkeys[i]
+sub(/^\n+/, "", key)
+sub(/\n.*$/, "", key)
+print "% " key > outname
+<<functions>>=
+function gobble(name, infile, rc, tag) {
+ for (rc = (getline line < name); rc > 0; rc = (getline line < name)) {
+ if (line ~ /^\\@input{[^}]*}$/)
+ gobble(substr(line, 9, length(line)-9))
+ else if (line ~ /^\\nwixadds{/) {
+ count++
+ tag = "000000" count
+ tag = substr(tag, length(tag)-6+1)
+ idx[count] = tag " " substr(line, 11)
+ }
+ }
+ if (rc < 0) print "No file " name "."
+ else close(name)
+ return
+}
+<<functions>>=
+function stripcount(s) {
+ sub(/^[0-9]+/, "", s)
+ sub(/ +/, "", s)
+ return "\\nwixaddsx{" s
+}
+<<functions>>=
+function alphasort(a, x, n) {
+ n = 0
+ for (x in a)
+ n = insertitem(a[x], n)
+ finish_sorting(n)
+ return n
+}
+function insertitem(x, n, i, tmp) {
+ sorted[n] = x
+ sortkeys[n] = sortkey(x)
+ return n+1
+}
+<<functions>>=
+function finish_sorting(n) {
+ firstwork = nextwork = 0
+ addquick(0, n)
+ while(nextwork > firstwork)
+ qsort()
+}
+<<functions>>=
+function addquick(l, r) {
+ workq[nextwork++] = l
+ workq[nextwork++] = r
+}
+<<get [[l]] and [[r]] out of work queue>>=
+l = workq[firstwork]
+delete workq[firstwork]
+firstwork++
+r = workq[firstwork]
+delete workq[firstwork]
+firstwork++
+<<functions>>=
+function qsort(l, r, mid, i, last) {
+ <<get [[l]] and [[r]] out of work queue>>
+ if (r - l < 10)
+ isort(l, r)
+ else {
+ mid = l + int((r - l) * rand())
+ swap(l, mid)
+ last = l
+ for (i = l+1; i < r; i++)
+ if (sortkeys[i] < sortkeys[l] ||
+ sortkeys[i] == sortkeys[l] && sorted[i] < sorted[l])
+ swap(++last, i)
+ swap(l, last)
+ addquick(l, last)
+ addquick(last+1, r)
+ }
+}
+<<functions>>=
+function isort(l, r, n) {
+ for (n = l + 1; n < r; n++)
+ for (i = n; i > l && (sortkeys[i] < sortkeys[i-1] ||
+ sortkeys[i] == sortkeys[i-1] && sorted[i] < sorted[i
+1]); i--)
+ swap(i, i-1)
+}
+<<functions>>=
+function swap(i, j, tmp) {
+ tmp = sortkeys [i]; sortkeys [i] = sortkeys [j]; sortkeys [j] = tmp
+ tmp = sorted[i]; sorted[i] = sorted[j]; sorted[j] = tmp
+}
+<<functions>>=
+function sortkey(s, count) {
+ match(s, /^[0-9]+/)
+ count = substr(s, RSTART, RLENGTH)
+ sub(/^[0-9]+ */, "", s)
+ if (s ~ /c}/) {
+ return firstkey(substr(s, 3)) "\n" count
+ } else if (s ~ /i}/) {
+ return firstkey(substr(s, 3)) "\n" count
+ } else {
+ print "sortkey handed non-chunk and non-index: " s
+ exit 1
+ }
+}
+<<functions>>=
+function firstkey(s, r, openbrace) {
+ if (s !~ /^{{/) {
+ <<complain about format and exit>>
+ }
+ sub (/^{{/, "", s)
+ gsub(/\\([a-zA-Z]+|.) */, "", s) # kill control sequences
+ openbrace = 1
+ r = ""
+ while (openbrace > 0)
+ if (match(s, /^[^{}]*/) <= 0)
+ openbrace--
+ else {
+ r = r substr(s, RSTART, RLENGTH)
+ c = substr(s, RSTART+RLENGTH, 1)
+ s = substr(s, RSTART+RLENGTH+1)
+ if (c == "}") openbrace--
+ else openbrace++
+ if (openbrace > 0) r = r c
+ }
+ return alphabet(r) "\n" r
+}
+<<complain about format and exit>>=
+print "key \"" substr(s, 1, 6) "...\" is ill-formatted"
+exit 1
+<<functions>>=
+function alphabet(s, r) {
+ r = ""
+ while (match(s, /[a-zA-Z \t]/) > 0) {
+ s = substr(s, RSTART)
+ c = substr(s, 1, 1)
+ if (c == " " || c == "\t") {
+ r = r " "
+ sub(/^[ \t]+/, "", s)
+ } else {
+ match(s, /^[a-zA-Z]+/)
+ r = r substr(s, RSTART, RLENGTH)
+ s = substr(s, RSTART+RLENGTH)
+ }
+ }
+ sub(/^ +/, "", r)
+ return r
+}
+@
+\section{Index}
+\nowebindex