home *** CD-ROM | disk | FTP | other *** search
- ############################################################################
- #
- # File: kwic.icn
- #
- # Subject: Program to produce keywords in context
- #
- # Author: Stephen B. Wampler, modified by Ralph E. Griswold
- #
- # Date: September 14, 1992
- #
- ###########################################################################
- #
- # This is a simple keyword-in-context (KWIC) program. It reads from
- # standard input and writes to standard output. The "key" words are
- # aligned in column 40, with the text shifted as necessary. Text shifted
- # left is truncated at the left. Tabs and other characters whose "print width"
- # is less than one may not be handled properly.
- #
- # If an integer is given on the command line, it overrides the default
- # 40.
- #
- # Some noise words are omitted (see "exceptions" in the program text).
- # If a file named except.wrd is open and readable in the current directory,
- # the words in it are used instead.
- #
- # This program is pretty simple. Possible extensions include ways
- # of specifying words to be omitted, more flexible output formatting, and
- # so on. Another "embellisher's delight".
- #
- ############################################################################
-
- global line, loc, exceptions, width
-
- procedure main(args)
- local exceptfile
-
- width := integer(args[1]) | 40
-
- if exceptfile := open("except.wrd") then {
- exceptions := set()
- every insert(exceptions, lcword(exceptfile))
- close(exceptfile)
- }
- else
- exceptions := set(["or", "in", "the", "to", "of", "on", "a",
- "an", "at", "and", "i", "it", "by", "for"])
-
- every write(kwic(&input))
-
- end
-
- procedure kwic(file)
- local index, word
-
- # Each word, in lowercase form, is a key in the table "index".
- # The corresponding values are lists of the positioned lines
- # for that word. This method may use an impractically large
- # amount of space for large input files.
-
- index := table()
- every word := lcword(file) do {
- if not member(exceptions,word) then {
- /index[word] := []
- index[word] := put(index[word],position())
- }
- }
-
- # Before the new sort options, it was done this way -- the code preserved
- # as an example of "generators in action".
-
- # suspend !((!sort(index,1))[2])
-
- index := sort(index,3)
- while get(index) do
- suspend !get(index)
- end
-
- procedure lcword(file)
- static chars
- initial chars := &ucase ++ &lcase ++ '\''
- every line := !file do
- line ? while tab(loc := upto(chars)) do
- suspend map(tab(many(chars)) \ 1)
- end
-
- procedure position()
- local offset
-
- # Note that "line" and ""loc" are global.
-
- offset := width - loc
- if offset >= 0 then return repl(" ",offset) || line
- else return line[-offset + 1:0]
- end
-