summaryrefslogtreecommitdiff
path: root/web/noweb/src/icon/disambiguate.nw
blob: 8f23d515b19ff057e520255fdb975869725b1b27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
\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
@