\section{Disambiguating abbreviated chunk names} This code disambiguates chunk names ending in [[...]]. If used, it belongs right after [[markup]] in the pipeline. The first pass calls [[remember]] on each name {\em not} ending in dots. For efficiency, I keep a table of sets indexed by the first character of the name. <<*>>= global chunknames procedure remember(name) initial chunknames := table() if *name = 0 then fail /chunknames[name[1]] := set() insert(chunknames[name[1]], name) return end @ The second pass calls [[disambiguate]] on each name that {\em does} end in dots. <<*>>= procedure disambiguate(arg) local s if *arg = 0 then fail search := chunknames[arg[1]] if /search then fatal("Can't resolve ", arg, "...") every match(arg, n := !search) do if /s then s := n else fatal("Ambiguous abbreviation: @<<", arg, "...@>> could denote\n\t@<<", s, "@>> or\n\t@<<", n, "@>>") if *s = 0 then fatal("Can't resolve ", arg, "...") return s end @ The <<*>>= global lines, defns, uses, names, firstdefnout procedure main(args) lines := [] while put(lines, line := read()) do apply(pass1, line) every apply(pass2, !lines) end procedure apply(pass, line) line ? (="@" & pass(tab(upto(' ')|0), if =" " then tab(0) else &null)) end procedure pass1(name, chunkname) initial chunknames := set() case name of { "defn" | "use" : if chunkname[0-:3] ~== "..." then remember(chunkname) } return end procedure pass2(name, arg) case name of { "defn" | "use" : if arg[0:-3] == "..." then arg := disambiguate(arg[1:-3]) } write("@", name, (" " || \arg) | "") if name == "fatal" then exit(1) return end @ <<*>>= procedure fatal(L[]) write!(["@fatal disambiguate "] ||| L) write!([&errout, "noweb error in disambiguate: "] ||| L) exit(1) end <<*>>= procedure rcsinfo () return "$Id: disambiguate.nw,v 1.18 2008/10/06 01:03:05 nr Exp nr $" || "$Name: v2_12 $" end @