[net.sources.bugs] one way to get an index in troff

lee@rochester.UUCP (Lee Moore) (09/05/85)

This is a follow-up to the troff indexing article I posted last month.
A couple people have had some problems with it.  The major problem is
that the Icon programs were written in an older version of the language.
I have updated these programs so that they will compile under the most recent
version.  They are included below.  The other problem is a typo in 
the sort command.  Where I said:
	sort +1n +0n -1n ....
I should have said:
	sort +1 +0n -1n
Now, it won't try to sort the index items numerically, only the
page numbers.

lee

------------------------------------------



#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	block.icn
#	fixindex.icn
# This archive created: Thu Sep  5 15:06:55 1985
export PATH; PATH=/bin:$PATH
if test -f 'block.icn'
then
	echo shar: over-writing existing file "'block.icn'"
fi
cat << \SHAR_EOF > 'block.icn'
#
#   Seperate index entries where the first letter of the entry
#	changes.  Produce a ".LB" at the break point.  Provide
#	the macro with the new letter
#	

procedure main()
	local doubleQuote,
	      line,
	      oldFirstChar,
	      firstChar

	doubleQuote := cset("\"")
	oldFirstChar := ""

	# read until end of file
	while line := read() do  {
		line ? {
			tab(upto(doubleQuote)) | write("can't find double q")
			move(1)
			firstChar :=  &subject[&pos] }
	
		# are the first two letters different?
		if firstChar ~== oldFirstChar then {
			write(".LB ", firstChar) }

		oldFirstChar := firstChar
		write(line) }
	end
SHAR_EOF
if test -f 'fixindex.icn'
then
	echo shar: over-writing existing file "'fixindex.icn'"
fi
cat << \SHAR_EOF > 'fixindex.icn'
# transform raw index entries into new macros
#
#	features include:  merging page numbers and suppressing duplicates
#			   sorting out major headings from minor
#
# the (pre-sorted) input is of the form
#	<page-number><tab><major name><tab><minor name>
#


record LineState(PageNum, Major, Minor)

procedure main()
	local pageList, old, new

	old := LineState()
	new := LineState()
	split(old) | return
	pageList := old.PageNum

	if old.Minor ~== "" then
	    write(".Ib \"", old.Major, "\"")

	while split(new) do {
	    if old.Major == new.Major then
		if old.Minor == new.Minor then {
		    if old.PageNum ~= new.PageNum then
			pageList ||:= "," || new.PageNum }
		else {
		    WriteEntry(old, pageList)
		    pageList := new.PageNum }
	    else {
		WriteEntry(old, pageList)
		pageList := new.PageNum

		if new.Minor ~== "" then 
		    write(".Ib \"", new.Major, "\"") }

	    AssignRecord(new, old) }		# new -> old

	WriteEntry(old, pageList)
 end


procedure split(state)
	static tabChar,
	       digits
	initial { tabChar := cset("\t");
		  digits := cset("0123456789") }

	read() | fail ? {
	    state.PageNum := tab(many(digits))
	    tab(many(tabChar))
	    state.Major := tab(upto(tabChar)) | tab(0)
	    tab(many(tabChar))
	    state.Minor := tab(0) }

	return
end


procedure WriteEntry(state, pageList)
	if state.Minor == "" then
	    write(".I> \"", state.Major, "\" \"", pageList, "\"")
	else
	    write(".I< \"", state.Major, "\" \"", state.Minor, 
					"\" \"", pageList, "\"")
 end


procedure AssignRecord(a, b)
	b.Major := a.Major
	b.Minor := a.Minor
	b.PageNum := a.PageNum
end
SHAR_EOF
#	End of shell archive
exit 0



-- 
TCP/IP:		lee@rochester.arpa
UUCP:		{decvax, allegra, seismo, cmcl2}!rochester!lee
XNS:		Lee Moore:CS:Univ Rochester
Phone:		+1 (716) 275-7747, -5671
Physical:	43 01' 40'' N, 77 37' 49'' W