############################################################################
#
#	File:     indxcomp.icn
#
#	Subject:  Program to assist in index compilation
#
#	Author:   Ralph E. Griswold
#
#	Date:     June 23, 2000
#
############################################################################
#
#   This file is in the public domain.
#
############################################################################
#
#  This program is designed to assist in the compilation of indexes.
#
#  It takes input from standard input and expects lines that either consist
#  of an integer (taken to be a page number) or text (to be indexed on
#  page of the last page number.
#
#  The idea is to go through the work to be indexed and create a file
#  in which the page number is entered followed by items to be indexed
#  on that page.  Page numbers (which need not be numeric) are prefixed
#  by "=".  For example, the file might consist of
#
#	=1
#	warts
#	moles
#	scratches
#	=2
#	scratches
#	dents
#	bumps
#	=3
#	hickies
#
#  The output of this program for that input is:
#
#	bumps, 2
#	dents, 2
#	hickies, 3
#	moles, 1
#	scratches, 1, 2
#	warts, 1
#
#  Leading blanks are stripped from index items.  Therefore to enter
#  an index item that begins with "=" start with " =" instead.
#
#  This program is unsophisticated.  It contains no provisions for
#  formatting index entries nor any way to indicated inclusive page
#  ranges.  Such things have to be done in post-processing.
#
#  non-numeric page "numbers" appear before numeric ones.
#
#  Obviously, there is room for improvement, embellishment, and creeping
#  featurism.
#
############################################################################

procedure main()
   local index, page, line, lines, temp1, temp2, x, xcase
   local lline

   index := table()
   xcase := table(" *** empty line")
   page := "<no page number>"  # in case file doesn't start with a page number

   while line := read() do {
      line ? {
         if ="=" then {
            page := tab(0)
            page := integer(page)	# for sorting; may fail
            if page === "" then page := "<empty page number>"
            next
            }
         }
      line ?:= (tab(many(' ')), tab(0))	# trim leading blanks
      if *line = 0 then next
      lline := map(line)
      xcase[lline] := line
      if lline == "" then lline := " *** empty line"
      /index[lline] := set()
      insert(index[lline], page)
      }

   index := sort(index, 3)

   while writes(xcase[get(index)]) do {
      lines := sort(get(index))
      temp1 := []
      temp2 := []
      while x := get(lines) do {
         if type(x) == "string" then put(temp1, x)
         else put(temp2, x)
         }
      lines := temp1 ||| temp2
      while writes(", ", get(lines))
      write()
      }

end
