Blame test/funstack.awk

Packit 575503
### ====================================================================
Packit 575503
###  @Awk-file{
Packit 575503
###     author          = "Nelson H. F. Beebe",
Packit 575503
###     version         = "1.00",
Packit 575503
###     date            = "09 October 1996",
Packit 575503
###     time            = "15:57:06 MDT",
Packit 575503
###     filename        = "journal-toc.awk",
Packit 575503
###     address         = "Center for Scientific Computing
Packit 575503
###                        Department of Mathematics
Packit 575503
###                        University of Utah
Packit 575503
###                        Salt Lake City, UT 84112
Packit 575503
###                        USA",
Packit 575503
###     telephone       = "+1 801 581 5254",
Packit 575503
###     FAX             = "+1 801 581 4148",
Packit 575503
###     URL             = "http://www.math.utah.edu/~beebe",
Packit 575503
###     checksum        = "25092 977 3357 26493",
Packit 575503
###     email           = "beebe@math.utah.edu (Internet)",
Packit 575503
###     codetable       = "ISO/ASCII",
Packit 575503
###     keywords        = "BibTeX, bibliography, HTML, journal table of
Packit 575503
###                        contents",
Packit 575503
###     supported       = "yes",
Packit 575503
###     docstring       = "Create a journal cover table of contents from
Packit 575503
###                        <at>Article{...} entries in a journal BibTeX
Packit 575503
###                        .bib file for checking the bibliography
Packit 575503
###                        database against the actual journal covers.
Packit 575503
###                        The output can be either plain text, or HTML.
Packit 575503
###
Packit 575503
###                        Usage:
Packit 575503
###                            bibclean -max-width 0 BibTeX-file(s) | \
Packit 575503
###                                bibsort -byvolume | \
Packit 575503
###                                awk -f journal-toc.awk \
Packit 575503
###                                    [-v HTML=nnn] [-v INDENT=nnn] \
Packit 575503
###                                    [-v BIBFILEURL=url] >foo.toc
Packit 575503
###
Packit 575503
###                            or if the bibliography is already sorted
Packit 575503
###                            by volume,
Packit 575503
###
Packit 575503
###                            bibclean -max-width 0 BibTeX-file(s) | \
Packit 575503
###                                awk -f journal-toc.awk \
Packit 575503
###                                    [-v HTML=nnn] [-v INDENT=nnn] \
Packit 575503
###                                    [-v BIBFILEURL=url] >foo.toc
Packit 575503
###
Packit 575503
###                        A non-zero value of the command-line option,
Packit 575503
###                        HTML=nnn, results in HTML output instead of
Packit 575503
###                        the default plain ASCII text (corresponding
Packit 575503
###                        to HTML=0).  The
Packit 575503
###
Packit 575503
###                        The INDENT=nnn command-line option specifies
Packit 575503
###                        the number of blanks to indent each logical
Packit 575503
###                        level of HTML.  The default is INDENT=4.
Packit 575503
###                        INDENT=0 suppresses indentation.  The INDENT
Packit 575503
###                        option has no effect when the default HTML=0
Packit 575503
###                        (plain text output) option is in effect.
Packit 575503
###
Packit 575503
###                        When HTML output is selected, the
Packit 575503
###                        BIBFILEURL=url command-line option provides a
Packit 575503
###                        way to request hypertext links from table of
Packit 575503
###                        contents page numbers to the complete BibTeX
Packit 575503
###                        entry for the article.  These links are
Packit 575503
###                        created by appending a sharp (#) and the
Packit 575503
###                        citation label to the BIBFILEURL value, which
Packit 575503
###                        conforms with the practice of
Packit 575503
###                        bibtex-to-html.awk.
Packit 575503
###
Packit 575503
###                        The HTML output form may be useful as a more
Packit 575503
###                        compact representation of journal article
Packit 575503
###                        bibliography data than the original BibTeX
Packit 575503
###                        file provides.  Of course, the
Packit 575503
###                        table-of-contents format provides less
Packit 575503
###                        information, and is considerably more
Packit 575503
###                        troublesome for a computer program to parse.
Packit 575503
###
Packit 575503
###                        When URL key values are provided, they will
Packit 575503
###                        be used to create hypertext links around
Packit 575503
###                        article titles.  This supports journals that
Packit 575503
###                        provide article contents on the World-Wide
Packit 575503
###                        Web.
Packit 575503
###
Packit 575503
###                        For parsing simplicity, this program requires
Packit 575503
###                        that BibTeX
Packit 575503
###
Packit 575503
###                            key = "value"
Packit 575503
###
Packit 575503
###                        and
Packit 575503
###
Packit 575503
###                            @String{name = "value"}
Packit 575503
###
Packit 575503
###                        specifications be entirely contained on
Packit 575503
###                        single lines, which is readily provided by
Packit 575503
###                        the `bibclean -max-width 0' filter.  It also
Packit 575503
###                        requires that bibliography entries begin and
Packit 575503
###                        end at the start of a line, and that
Packit 575503
###                        quotation marks, rather than balanced braces,
Packit 575503
###                        delimit string values.  This is a
Packit 575503
###                        conventional format that again can be
Packit 575503
###                        guaranteed by bibclean.
Packit 575503
###
Packit 575503
###                        This program requires `new' awk, as described
Packit 575503
###                        in the book
Packit 575503
###
Packit 575503
###                            Alfred V. Aho, Brian W. Kernighan, and
Packit 575503
###                            Peter J. Weinberger,
Packit 575503
###                            ``The AWK Programming Language'',
Packit 575503
###                            Addison-Wesley (1988), ISBN
Packit 575503
###                            0-201-07981-X,
Packit 575503
###
Packit 575503
###                        such as provided by programs named (GNU)
Packit 575503
###                        gawk, nawk, and recent AT&T awk.
Packit 575503
###
Packit 575503
###                        The checksum field above contains a CRC-16
Packit 575503
###                        checksum as the first value, followed by the
Packit 575503
###                        equivalent of the standard UNIX wc (word
Packit 575503
###                        count) utility output of lines, words, and
Packit 575503
###                        characters.  This is produced by Robert
Packit 575503
###                        Solovay's checksum utility.",
Packit 575503
###  }
Packit 575503
### ====================================================================
Packit 575503
Packit 575503
BEGIN						{ initialize() }
Packit 575503
Packit 575503
/^ *@ *[Ss][Tt][Rr][Ii][Nn][Gg] *\{/		{ do_String(); next }
Packit 575503
Packit 575503
/^ *@ *[Pp][Rr][Ee][Aa][Mm][Bb][Ll][Ee]/	{ next }
Packit 575503
Packit 575503
/^ *@ *[Aa][Rr][Tt][Ii][Cc][Ll][Ee]/		{ do_Article(); next }
Packit 575503
Packit 575503
/^ *@/						{ do_Other(); next }
Packit 575503
Packit 575503
/^ *author *= *\"/ 				{ do_author(); next }
Packit 575503
Packit 575503
/^ *journal *= */				{ do_journal(); next }
Packit 575503
Packit 575503
/^ *volume *= *\"/				{ do_volume(); next }
Packit 575503
Packit 575503
/^ *number *= *\"/				{ do_number(); next }
Packit 575503
Packit 575503
/^ *year *= *\"/				{ do_year(); next }
Packit 575503
Packit 575503
/^ *month *= */					{ do_month(); next }
Packit 575503
Packit 575503
/^ *title *= *\"/				{ do_title(); next }
Packit 575503
Packit 575503
/^ *pages *= *\"/				{ do_pages(); next }
Packit 575503
Packit 575503
/^ *URL *= *\"/					{ do_URL(); next }
Packit 575503
Packit 575503
/^ *} *$/					{ if (In_Article) do_end_entry(); next }
Packit 575503
Packit 575503
END						{ terminate() }
Packit 575503
Packit 575503
Packit 575503
########################################################################
Packit 575503
# NB: The programming conventions for variables in this program are:   #
Packit 575503
#	UPPERCASE		global constants and user options      #
Packit 575503
#	Initialuppercase	global variables                       #
Packit 575503
#	lowercase		local variables                        #
Packit 575503
# Any deviation is an error!                                           #
Packit 575503
########################################################################
Packit 575503
Packit 575503
Packit 575503
function do_Article()
Packit 575503
{
Packit 575503
	In_Article = 1
Packit 575503
Packit 575503
	Citation_label = $0
Packit 575503
	sub(/^[^\{]*\{/,"",Citation_label)
Packit 575503
	sub(/ *, *$/,"",Citation_label)
Packit 575503
Packit 575503
	Author = ""
Packit 575503
        Title = ""
Packit 575503
        Journal = ""
Packit 575503
        Volume = ""
Packit 575503
        Number = ""
Packit 575503
        Month = ""
Packit 575503
        Year = ""
Packit 575503
        Pages = ""
Packit 575503
        Url = ""
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_author()
Packit 575503
{
Packit 575503
	Author = TeX_to_HTML(get_value($0))
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_end_entry( k,n,parts)
Packit 575503
{
Packit 575503
	n = split(Author,parts," and ")
Packit 575503
	if (Last_number != Number)
Packit 575503
		do_new_issue()
Packit 575503
	for (k = 1; k < n; ++k)
Packit 575503
		print_toc_line(parts[k] " and", "", "")
Packit 575503
	Title_prefix = html_begin_title()
Packit 575503
	Title_suffix = html_end_title()
Packit 575503
	if (html_length(Title) <= (MAX_TITLE_CHARS + MIN_LEADERS)) # complete title fits on line
Packit 575503
		print_toc_line(parts[n], Title, html_begin_pages() Pages html_end_pages())
Packit 575503
	else			# need to split long title over multiple lines
Packit 575503
		do_long_title(parts[n], Title, html_begin_pages() Pages html_end_pages())
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_journal()
Packit 575503
{
Packit 575503
	if ($0 ~ /[=] *"/)	# have journal = "quoted journal name",
Packit 575503
		Journal = get_value($0)
Packit 575503
	else			# have journal = journal-abbreviation,
Packit 575503
	{
Packit 575503
        	Journal = get_abbrev($0)
Packit 575503
		if (Journal in String) # replace abbrev by its expansion
Packit 575503
			Journal = String[Journal]
Packit 575503
	}
Packit 575503
	gsub(/\\-/,"",Journal)	# remove discretionary hyphens
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_long_title(author,title,pages, last_title,n)
Packit 575503
{
Packit 575503
	title = trim(title)			# discard leading and trailing space
Packit 575503
	while (length(title) > 0)
Packit 575503
	{
Packit 575503
		n = html_breakpoint(title,MAX_TITLE_CHARS+MIN_LEADERS)
Packit 575503
		last_title = substr(title,1,n)
Packit 575503
		title = substr(title,n+1)
Packit 575503
		sub(/^ +/,"",title)		# discard any leading space
Packit 575503
		print_toc_line(author, last_title, (length(title) == 0) ? pages : "")
Packit 575503
		author = ""
Packit 575503
	}
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_month( k,n,parts)
Packit 575503
{
Packit 575503
	Month = ($0 ~ /[=] *"/) ? get_value($0) : get_abbrev($0)
Packit 575503
	gsub(/[\"]/,"",Month)
Packit 575503
	gsub(/ *# *\\slash *# */," / ",Month)
Packit 575503
	gsub(/ *# *-+ *# */," / ",Month)
Packit 575503
	n = split(Month,parts," */ *")
Packit 575503
	Month = ""
Packit 575503
	for (k = 1; k <= n; ++k)
Packit 575503
		Month = Month ((k > 1) ? " / " : "") \
Packit 575503
			((parts[k] in Month_expansion) ? Month_expansion[parts[k]] : parts[k])
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_new_issue()
Packit 575503
{
Packit 575503
	Last_number = Number
Packit 575503
	if (HTML)
Packit 575503
	{
Packit 575503
		if (Last_volume != Volume)
Packit 575503
		{
Packit 575503
			Last_volume = Volume
Packit 575503
			print_line(prefix(2) "
")
Packit 575503
		}
Packit 575503
		html_end_toc()
Packit 575503
		html_begin_issue()
Packit 575503
		print_line(prefix(2) Journal "
")
Packit 575503
	}
Packit 575503
	else
Packit 575503
	{
Packit 575503
		print_line("")
Packit 575503
		print_line(Journal)
Packit 575503
	}
Packit 575503
Packit 575503
	print_line(strip_html(vol_no_month_year()))
Packit 575503
Packit 575503
	if (HTML)
Packit 575503
	{
Packit 575503
		html_end_issue()
Packit 575503
		html_toc_entry()
Packit 575503
		html_begin_toc()
Packit 575503
	}
Packit 575503
	else
Packit 575503
		print_line("")
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_number()
Packit 575503
{
Packit 575503
	Number = get_value($0)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_Other()
Packit 575503
{
Packit 575503
	In_Article = 0
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_pages()
Packit 575503
{
Packit 575503
	Pages = get_value($0)
Packit 575503
	sub(/--[?][?]/,"",Pages)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_String()
Packit 575503
{
Packit 575503
	sub(/^[^\{]*\{/,"",$0)	# discard up to and including open brace
Packit 575503
	sub(/\} *$/,"",$0)	# discard from optional whitespace and trailing brace to end of line
Packit 575503
	String[get_key($0)] = get_value($0)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_title()
Packit 575503
{
Packit 575503
	Title = TeX_to_HTML(get_value($0))
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_URL( parts)
Packit 575503
{
Packit 575503
	Url = get_value($0)
Packit 575503
	split(Url,parts,"[,;]")			# in case we have multiple URLs
Packit 575503
	Url = trim(parts[1])
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_volume()
Packit 575503
{
Packit 575503
	Volume = get_value($0)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function do_year()
Packit 575503
{
Packit 575503
	Year = get_value($0)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function get_abbrev(s)
Packit 575503
{	# return abbrev from ``key = abbrev,''
Packit 575503
	sub(/^[^=]*= */,"",s)	# discard text up to start of non-blank value
Packit 575503
	sub(/ *,? *$/,"",s)	# discard trailing optional whitspace, quote,
Packit 575503
				# optional comma, and optional space
Packit 575503
	return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function get_key(s)
Packit 575503
{	# return kay from ``key = "value",''
Packit 575503
	sub(/^ */,"",s)		# discard leading space
Packit 575503
	sub(/ *=.*$/,"",s)	# discard everthing after key
Packit 575503
Packit 575503
	return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function get_value(s)
Packit 575503
{	# return value from ``key = "value",''
Packit 575503
	sub(/^[^\"]*\" */,"",s)	# discard text up to start of non-blank value
Packit 575503
	sub(/ *\",? *$/,"",s)	# discard trailing optional whitspace, quote,
Packit 575503
				# optional comma, and optional space
Packit 575503
	return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_accents(s)
Packit 575503
{
Packit 575503
	if (index(s,"\\") > 0)			# important optimization
Packit 575503
	{
Packit 575503
		# Convert common lower-case accented letters according to the
Packit 575503
		# table on p. 169 of in Peter Flynn's ``The World Wide Web
Packit 575503
		# Handbook'', International Thomson Computer Press, 1995, ISBN
Packit 575503
		# 1-85032-205-8.  The official table of ISO Latin 1 SGML
Packit 575503
		# entities used in HTML can be found in the file
Packit 575503
		# /usr/local/lib/html-check/lib/ISOlat1.sgml (your path
Packit 575503
		# may differ).
Packit 575503
Packit 575503
		gsub(/{\\\a}/,	"\\à",	s)
Packit 575503
		gsub(/{\\'a}/,	"\\á",	s)
Packit 575503
		gsub(/{\\[\^]a}/,"\\â",	s)
Packit 575503
		gsub(/{\\~a}/,	"\\ã",	s)
Packit 575503
		gsub(/{\\\"a}/,	"\\ä",	s)
Packit 575503
		gsub(/{\\aa}/,	"\\å",	s)
Packit 575503
		gsub(/{\\ae}/,	"\\æ",	s)
Packit 575503
Packit 575503
		gsub(/\{\\c\{c\}\}/,"\\ç",	s)
Packit 575503
Packit 575503
		gsub(/\{\\\e\}/,	"\\è",	s)
Packit 575503
		gsub(/\{\\'e\}/,	"\\é",	s)
Packit 575503
		gsub(/\{\\[\^]e\}/,"\\ê",	s)
Packit 575503
		gsub(/\{\\\"e\}/,	"\\ë",	s)
Packit 575503
Packit 575503
		gsub(/\{\\\i\}/,	"\\ì",	s)
Packit 575503
		gsub(/\{\\'i\}/,	"\\í",	s)
Packit 575503
		gsub(/\{\\[\^]i\}/,"\\î",	s)
Packit 575503
		gsub(/\{\\\"i\}/,	"\\ï",	s)
Packit 575503
Packit 575503
		# ignore eth and thorn
Packit 575503
Packit 575503
		gsub(/\{\\~n\}/,	"\\ñ",	s)
Packit 575503
Packit 575503
		gsub(/\{\\\o\}/,	"\\ò",	s)
Packit 575503
		gsub(/\{\\'o\}/,	"\\ó",	s)
Packit 575503
		gsub(/\{\\[\^]o\}/, "\\ô",	s)
Packit 575503
		gsub(/\{\\~o\}/,	"\\õ",	s)
Packit 575503
		gsub(/\{\\\"o\}/,	"\\ö",	s)
Packit 575503
		gsub(/\{\\o\}/,	"\\ø",	s)
Packit 575503
Packit 575503
		gsub(/\{\\\u\}/,	"\\ù",	s)
Packit 575503
		gsub(/\{\\'u\}/,	"\\ú",	s)
Packit 575503
		gsub(/\{\\[\^]u\}/,"\\û",	s)
Packit 575503
		gsub(/\{\\\"u\}/,	"\\ü",	s)
Packit 575503
Packit 575503
		gsub(/\{\\'y\}/,	"\\ý",	s)
Packit 575503
		gsub(/\{\\\"y\}/,	"\\ÿ",	s)
Packit 575503
Packit 575503
		# Now do the same for upper-case accents
Packit 575503
Packit 575503
		gsub(/\{\\\A\}/,	"\\À",	s)
Packit 575503
		gsub(/\{\\'A\}/,	"\\Á",	s)
Packit 575503
		gsub(/\{\\[\^]A\}/,	"\\Â",	s)
Packit 575503
		gsub(/\{\\~A\}/,	"\\Ã",	s)
Packit 575503
		gsub(/\{\\\"A\}/,	"\\Ä",	s)
Packit 575503
		gsub(/\{\\AA\}/,	"\\Å",	s)
Packit 575503
		gsub(/\{\\AE\}/,	"\\Æ",	s)
Packit 575503
Packit 575503
		gsub(/\{\\c\{C\}\}/,"\\Ç",	s)
Packit 575503
Packit 575503
		gsub(/\{\\\e\}/,	"\\È",	s)
Packit 575503
		gsub(/\{\\'E\}/,	"\\É",	s)
Packit 575503
		gsub(/\{\\[\^]E\}/,	"\\Ê",	s)
Packit 575503
		gsub(/\{\\\"E\}/,	"\\Ë",	s)
Packit 575503
Packit 575503
		gsub(/\{\\\I\}/,	"\\Ì",	s)
Packit 575503
		gsub(/\{\\'I\}/,	"\\Í",	s)
Packit 575503
		gsub(/\{\\[\^]I\}/,	"\\Î",	s)
Packit 575503
		gsub(/\{\\\"I\}/,	"\\Ï",	s)
Packit 575503
Packit 575503
		# ignore eth and thorn
Packit 575503
Packit 575503
		gsub(/\{\\~N\}/,	"\\Ñ",	s)
Packit 575503
Packit 575503
		gsub(/\{\\\O\}/,	"\\Ò",	s)
Packit 575503
		gsub(/\{\\'O\}/,	"\\Ó",	s)
Packit 575503
		gsub(/\{\\[\^]O\}/,	"\\Ô",	s)
Packit 575503
		gsub(/\{\\~O\}/,	"\\Õ",	s)
Packit 575503
		gsub(/\{\\\"O\}/,	"\\Ö",	s)
Packit 575503
		gsub(/\{\\O\}/,	"\\Ø",	s)
Packit 575503
Packit 575503
		gsub(/\{\\\U\}/,	"\\Ù",	s)
Packit 575503
		gsub(/\{\\'U\}/,	"\\Ú",	s)
Packit 575503
		gsub(/\{\\[\^]U\}/,	"\\Û",	s)
Packit 575503
		gsub(/\{\\\"U\}/,	"\\Ü",	s)
Packit 575503
Packit 575503
		gsub(/\{\\'Y\}/,	"\\Ý",	s)
Packit 575503
Packit 575503
		gsub(/\{\\ss\}/,	"\\ß",	s)
Packit 575503
Packit 575503
		# Others not mentioned in Flynn's book
Packit 575503
		gsub(/\{\\'\\i\}/,"\\í",	s)
Packit 575503
		gsub(/\{\\'\\j\}/,"j",		s)
Packit 575503
	}
Packit 575503
	return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_begin_issue()
Packit 575503
{
Packit 575503
	print_line("")
Packit 575503
	print_line(prefix(2) "
")
Packit 575503
	print_line("")
Packit 575503
	print_line(prefix(2) "

")

Packit 575503
	print_line(prefix(3) "")
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_begin_pages()
Packit 575503
{
Packit 575503
	return ((HTML && (BIBFILEURL != "")) ? ("") : "")
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_begin_pre()
Packit 575503
{
Packit 575503
	In_PRE = 1
Packit 575503
	print_line("
")
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_begin_title()
Packit 575503
{
Packit 575503
	return ((HTML && (Url != "")) ? ("") : "")
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_begin_toc()
Packit 575503
{
Packit 575503
	html_end_toc()
Packit 575503
	html_begin_pre()
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_body( k)
Packit 575503
{
Packit 575503
	for (k = 1; k <= BodyLines; ++k)
Packit 575503
		print Body[k]
Packit 575503
}
Packit 575503
Packit 575503
function html_breakpoint(title,maxlength, break_after,k)
Packit 575503
{
Packit 575503
	# Return the largest character position in title AFTER which we
Packit 575503
	# can break the title across lines, without exceeding maxlength
Packit 575503
	# visible characters.
Packit 575503
	if (html_length(title) > maxlength)	# then need to split title across lines
Packit 575503
	{
Packit 575503
		# In the presence of HTML markup, the initialization of
Packit 575503
		# k here is complicated, because we need to advance it
Packit 575503
		# until html_length(title) is at least maxlength,
Packit 575503
		# without invoking the expensive html_length() function
Packit 575503
		# too frequently.  The need to split the title makes the
Packit 575503
		# alternative of delayed insertion of HTML markup much
Packit 575503
		# more complicated.
Packit 575503
		break_after = 0
Packit 575503
		for (k = min(maxlength,length(title)); k < length(title); ++k)
Packit 575503
		{
Packit 575503
			if (substr(title,k+1,1) == " ")
Packit 575503
			{		# could break after position k
Packit 575503
				if (html_length(substr(title,1,k)) <= maxlength)
Packit 575503
					break_after = k
Packit 575503
				else	# advanced too far, retreat back to last break_after
Packit 575503
					break
Packit 575503
			}
Packit 575503
		}
Packit 575503
		if (break_after == 0)		# no breakpoint found by forward scan
Packit 575503
		{				# so switch to backward scan
Packit 575503
			for (k = min(maxlength,length(title)) - 1; \
Packit 575503
				(k > 0) && (substr(title,k+1,1) != " "); --k)
Packit 575503
				;		# find space at which to break title
Packit 575503
			if (k < 1)		# no break point found
Packit 575503
				k = length(title) # so must print entire string
Packit 575503
		}
Packit 575503
		else
Packit 575503
			k = break_after
Packit 575503
	}
Packit 575503
	else					# title fits on one line
Packit 575503
		k = length(title)
Packit 575503
	return (k)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
Packit 575503
function html_end_issue()
Packit 575503
{
Packit 575503
	print_line(prefix(3) "")
Packit 575503
	print_line(prefix(2) "")
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_end_pages()
Packit 575503
{
Packit 575503
	return ((HTML && (BIBFILEURL != "")) ? "" : "")
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_end_pre()
Packit 575503
{
Packit 575503
	if (In_PRE)
Packit 575503
	{
Packit 575503
		print_line("")
Packit 575503
		In_PRE = 0
Packit 575503
	}
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_end_title()
Packit 575503
{
Packit 575503
	return ((HTML && (Url != "")) ? "" : "")
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_end_toc()
Packit 575503
{
Packit 575503
	html_end_pre()
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_fonts(s, arg,control_word,k,level,n,open_brace)
Packit 575503
{
Packit 575503
	open_brace = index(s,"{")
Packit 575503
	if (open_brace > 0)			# important optimization
Packit 575503
	{
Packit 575503
		level = 1
Packit 575503
		for (k = open_brace + 1; (level != 0) && (k <= length(s)); ++k)
Packit 575503
		{
Packit 575503
			if (substr(s,k,1) == "{")
Packit 575503
				level++
Packit 575503
			else if (substr(s,k,1) == "}")
Packit 575503
				level--
Packit 575503
		}
Packit 575503
Packit 575503
		# {...} is now found at open_brace ... (k-1)
Packit 575503
		for (control_word in Font_decl_map)	# look for {\xxx ...}
Packit 575503
		{
Packit 575503
			if (substr(s,open_brace+1,length(control_word)+1) ~ \
Packit 575503
				("\\" control_word "[^A-Za-z]"))
Packit 575503
			{
Packit 575503
				n = open_brace + 1 + length(control_word)
Packit 575503
				arg = trim(substr(s,n,k - n))
Packit 575503
				if (Font_decl_map[control_word] == "toupper") # arg -> ARG
Packit 575503
					arg = toupper(arg)
Packit 575503
				else if (Font_decl_map[control_word] != "") # arg -> <TAG>arg</TAG>
Packit 575503
					arg = "<" Font_decl_map[control_word] ">" arg "</" Font_decl_map[control_word] ">"
Packit 575503
				return (substr(s,1,open_brace-1) arg html_fonts(substr(s,k)))
Packit 575503
			}
Packit 575503
		}
Packit 575503
		for (control_word in Font_cmd_map)	# look for \xxx{...}
Packit 575503
		{
Packit 575503
			if (substr(s,open_brace - length(control_word),length(control_word)) ~ \
Packit 575503
				("\\" control_word))
Packit 575503
			{
Packit 575503
				n = open_brace + 1
Packit 575503
				arg = trim(substr(s,n,k - n))
Packit 575503
				if (Font_cmd_map[control_word] == "toupper") # arg -> ARG
Packit 575503
					arg = toupper(arg)
Packit 575503
				else if (Font_cmd_map[control_word] != "") # arg -> <TAG>arg</TAG>
Packit 575503
					arg = "<" Font_cmd_map[control_word] ">" arg "</" Font_cmd_map[control_word] ">"
Packit 575503
				n = open_brace - length(control_word) - 1
Packit 575503
				return (substr(s,1,n) arg html_fonts(substr(s,k)))
Packit 575503
			}
Packit 575503
		}
Packit 575503
	}
Packit 575503
	return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_header()
Packit 575503
{
Packit 575503
	USER = ENVIRON["USER"]
Packit 575503
	if (USER == "")
Packit 575503
	    USER = ENVIRON["LOGNAME"]
Packit 575503
	if (USER == "")
Packit 575503
	    USER = "????"
Packit 575503
	"hostname" | getline HOSTNAME
Packit 575503
	"date" | getline DATE
Packit 575503
	("ypcat passwd | grep '^" USER ":' | awk -F: '{print $5}'") | getline PERSONAL_NAME
Packit 575503
	if (PERSONAL_NAME == "")
Packit 575503
	    ("grep  '^" USER ":' /etc/passwd | awk -F: '{print $5}'") | getline PERSONAL_NAME
Packit 575503
Packit 575503
Packit 575503
	print ""
Packit 575503
	print ""
Packit 575503
	print ""
Packit 575503
	print ""
Packit 575503
	print ""
Packit 575503
	print ""
Packit 575503
	print ""
Packit 575503
	print ""
Packit 575503
	print "<HTML>"
Packit 575503
	print prefix(1) "<HEAD>"
Packit 575503
	print prefix(2) "<TITLE>"
Packit 575503
	print prefix(3)  Journal
Packit 575503
	print prefix(2) "</TITLE>"
Packit 575503
	print prefix(2) "<LINK REV=\"made\" HREF=\"mailto:" USER "@" HOSTNAME "\">"
Packit 575503
	print prefix(1) "</HEAD>"
Packit 575503
	print ""
Packit 575503
	print prefix(1) "<BODY>"
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_label( label)
Packit 575503
{
Packit 575503
	label = Volume "(" Number "):" Month ":" Year
Packit 575503
	# gsub(/[^A-Za-z0-9():,;.\/\-]/,"",label)
Packit 575503
	gsub(/[^[:alnum:]():,;.\/\-]/,"",label)
Packit 575503
	return (label)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_length(s)
Packit 575503
{	# Return visible length of s, ignoring any HTML markup
Packit 575503
	if (HTML)
Packit 575503
	{
Packit 575503
		gsub(/<\/?[^>]*>/,"",s)		# remove SGML tags
Packit 575503
		# gsub(/&[A-Za-z0-9]+;/,"",s)	# remove SGML entities
Packit 575503
		gsub(/&[[:alnum:]]+;/,"",s)	# remove SGML entities
Packit 575503
	}
Packit 575503
	return (length(s))
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_toc()
Packit 575503
{
Packit 575503
	print prefix(2) "

"

Packit 575503
	print prefix(3) "Table of contents for issues of " Journal
Packit 575503
	print prefix(2) ""
Packit 575503
	print HTML_TOC
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_toc_entry()
Packit 575503
{
Packit 575503
	HTML_TOC = HTML_TOC "        "
Packit 575503
	HTML_TOC = HTML_TOC vol_no_month_year()
Packit 575503
	HTML_TOC = HTML_TOC "
" "\n"
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function html_trailer()
Packit 575503
{
Packit 575503
	html_end_pre()
Packit 575503
	print prefix(1) "</BODY>"
Packit 575503
	print "</HTML>"
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function initialize()
Packit 575503
{
Packit 575503
	# NB: Update these when the program changes
Packit 575503
	VERSION_DATE = "[09-Oct-1996]"
Packit 575503
	VERSION_NUMBER = "1.00"
Packit 575503
Packit 575503
	HTML = (HTML == "") ? 0 : (0 + HTML)
Packit 575503
Packit 575503
	if (INDENT == "")
Packit 575503
		INDENT = 4
Packit 575503
Packit 575503
	if (HTML == 0)
Packit 575503
		INDENT = 0	# indentation suppressed in ASCII mode
Packit 575503
Packit 575503
	LEADERS = " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ."
Packit 575503
Packit 575503
	MAX_TITLE_CHARS = 36	# 36 produces a 79-char output line when there is
Packit 575503
				# just an initial page number.  If this is
Packit 575503
				# increased, the LEADERS string may need to be
Packit 575503
				# lengthened.
Packit 575503
Packit 575503
	MIN_LEADERS = 4		# Minimum number of characters from LEADERS
Packit 575503
				# required when leaders are used.  The total
Packit 575503
				# number of characters that can appear in a
Packit 575503
				# title line is MAX_TITLE_CHARS + MIN_LEADERS.
Packit 575503
				# Leaders are omitted when the title length is
Packit 575503
				# between MAX_TITLE_CHARS and this sum.
Packit 575503
Packit 575503
	MIN_LEADERS_SPACE = "        "	# must be at least MIN_LEADERS characters long
Packit 575503
Packit 575503
	Month_expansion["jan"]	= "January"
Packit 575503
	Month_expansion["feb"]	= "February"
Packit 575503
	Month_expansion["mar"]	= "March"
Packit 575503
	Month_expansion["apr"]	= "April"
Packit 575503
	Month_expansion["may"]	= "May"
Packit 575503
	Month_expansion["jun"]	= "June"
Packit 575503
	Month_expansion["jul"]	= "July"
Packit 575503
	Month_expansion["aug"]	= "August"
Packit 575503
	Month_expansion["sep"]	= "September"
Packit 575503
	Month_expansion["oct"]	= "October"
Packit 575503
	Month_expansion["nov"]	= "November"
Packit 575503
	Month_expansion["dec"]	= "December"
Packit 575503
Packit 575503
	Font_cmd_map["\\emph"]		= "EM"
Packit 575503
	Font_cmd_map["\\textbf"]	= "B"
Packit 575503
	Font_cmd_map["\\textit"]	= "I"
Packit 575503
	Font_cmd_map["\\textmd"]	= ""
Packit 575503
	Font_cmd_map["\\textrm"]	= ""
Packit 575503
	Font_cmd_map["\\textsc"]	= "toupper"
Packit 575503
	Font_cmd_map["\\textsl"]	= "I"
Packit 575503
	Font_cmd_map["\\texttt"]	= "t"
Packit 575503
	Font_cmd_map["\\textup"]	= ""
Packit 575503
Packit 575503
	Font_decl_map["\\bf"]		= "B"
Packit 575503
	Font_decl_map["\\em"]		= "EM"
Packit 575503
	Font_decl_map["\\it"]		= "I"
Packit 575503
	Font_decl_map["\\rm"]		= ""
Packit 575503
	Font_decl_map["\\sc"]		= "toupper"
Packit 575503
	Font_decl_map["\\sf"]		= ""
Packit 575503
	Font_decl_map["\\tt"]		= "TT"
Packit 575503
	Font_decl_map["\\itshape"]	= "I"
Packit 575503
	Font_decl_map["\\upshape"]	= ""
Packit 575503
	Font_decl_map["\\slshape"]	= "I"
Packit 575503
	Font_decl_map["\\scshape"]	= "toupper"
Packit 575503
	Font_decl_map["\\mdseries"]	= ""
Packit 575503
	Font_decl_map["\\bfseries"]	= "B"
Packit 575503
	Font_decl_map["\\rmfamily"]	= ""
Packit 575503
	Font_decl_map["\\sffamily"]	= ""
Packit 575503
	Font_decl_map["\\ttfamily"]	= "TT"
Packit 575503
}
Packit 575503
Packit 575503
function min(a,b)
Packit 575503
{
Packit 575503
	return (a < b) ? a : b
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function prefix(level)
Packit 575503
{
Packit 575503
	# Return a prefix of up to 60 blanks
Packit 575503
Packit 575503
	if (In_PRE)
Packit 575503
		return ("")
Packit 575503
	else
Packit 575503
		return (substr("                                                            ", \
Packit 575503
			1, INDENT * level))
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function print_line(line)
Packit 575503
{
Packit 575503
	if (HTML)		# must buffer in memory so that we can accumulate TOC
Packit 575503
		Body[++BodyLines] = line
Packit 575503
	else
Packit 575503
		print line
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function print_toc_line(author,title,pages, extra,leaders,n,t)
Packit 575503
{
Packit 575503
	# When we have a multiline title, the hypertext link goes only
Packit 575503
	# on the first line.  A multiline hypertext link looks awful
Packit 575503
	# because of long underlines under the leading indentation.
Packit 575503
Packit 575503
	if (pages == "")	# then no leaders needed in title lines other than last one
Packit 575503
		t = sprintf("%31s   %s%s%s", author, Title_prefix, title, Title_suffix)
Packit 575503
	else					# last title line, with page number
Packit 575503
	{
Packit 575503
		n = html_length(title)		# potentially expensive
Packit 575503
		extra = n % 2			# extra space for aligned leader dots
Packit 575503
		if (n <= MAX_TITLE_CHARS) 	# then need leaders
Packit 575503
			leaders = substr(LEADERS, 1, MAX_TITLE_CHARS + MIN_LEADERS - extra - \
Packit 575503
				   min(MAX_TITLE_CHARS,n))
Packit 575503
		else				# title (almost) fills line, so no leaders
Packit 575503
			leaders = substr(MIN_LEADERS_SPACE,1, \
Packit 575503
					 (MAX_TITLE_CHARS + MIN_LEADERS - extra - n))
Packit 575503
		t = sprintf("%31s   %s%s%s%s%s %4s", \
Packit 575503
			    author, Title_prefix, title, Title_suffix, \
Packit 575503
			    (extra ? " " : ""), leaders, pages)
Packit 575503
	}
Packit 575503
Packit 575503
	Title_prefix = ""	# forget any hypertext
Packit 575503
	Title_suffix = ""	# link material
Packit 575503
Packit 575503
	# Efficency note: an earlier version accumulated the body in a
Packit 575503
	# single scalar like this: "Body = Body t".  Profiling revealed
Packit 575503
	# this statement as the major hot spot, and the change to array
Packit 575503
	# storage made the program more than twice as fast.  This
Packit 575503
	# suggests that awk might benefit from an optimization of
Packit 575503
	# "s = s t" that uses realloc() instead of malloc().
Packit 575503
	if (HTML)
Packit 575503
		Body[++BodyLines] = t
Packit 575503
	else
Packit 575503
		print t
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function protect_SGML_characters(s)
Packit 575503
{
Packit 575503
    gsub(/&/,"\\&",s)	# NB: this one MUST be first
Packit 575503
    gsub(/</,"\\<",s)
Packit 575503
    gsub(/>/,"\\>",s)
Packit 575503
    gsub(/\"/,"\\"",s)
Packit 575503
    return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function strip_braces(s, k)
Packit 575503
{	# strip non-backslashed braces from s and return the result
Packit 575503
Packit 575503
	return (strip_char(strip_char(s,"{"),"}"))
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function strip_char(s,c, k)
Packit 575503
{	# strip non-backslashed instances of c from s, and return the result
Packit 575503
	k = index(s,c)
Packit 575503
	if (k > 0)		# then found the character
Packit 575503
	{
Packit 575503
		if (substr(s,k-1,1) != "\\") # then not backslashed char
Packit 575503
			s = substr(s,1,k-1) strip_char(substr(s,k+1),c) # so remove it (recursively)
Packit 575503
		else		# preserve backslashed char
Packit 575503
			s = substr(s,1,k) strip_char(s,k+1,c)
Packit 575503
	}
Packit 575503
	return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function strip_html(s)
Packit 575503
{
Packit 575503
	gsub(/<\/?[^>]*>/,"",s)
Packit 575503
	return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function terminate()
Packit 575503
{
Packit 575503
	if (HTML)
Packit 575503
	{
Packit 575503
		html_end_pre()
Packit 575503
Packit 575503
		HTML = 0	# NB: stop line buffering
Packit 575503
		html_header()
Packit 575503
		html_toc()
Packit 575503
		html_body()
Packit 575503
		html_trailer()
Packit 575503
	}
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function TeX_to_HTML(s, k,n,parts)
Packit 575503
{
Packit 575503
	# First convert the four SGML reserved characters to SGML entities
Packit 575503
	if (HTML)
Packit 575503
	{
Packit 575503
	    gsub(/>/,	"\\>",	s)
Packit 575503
	    gsub(/</,	"\\<",	s)
Packit 575503
	    gsub(/"/,	"\\"",	s)
Packit 575503
	}
Packit 575503
Packit 575503
	gsub(/[$][$]/,"$$",s)	# change display math to triple dollars for split
Packit 575503
	n = split(s,parts,/[$]/)# split into non-math (odd) and math (even) parts
Packit 575503
Packit 575503
	s = ""
Packit 575503
	for (k = 1; k <= n; ++k) # unbrace non-math part, leaving math mode intact
Packit 575503
		s = s ((k > 1) ? "$" : "") \
Packit 575503
			((k % 2) ? strip_braces(TeX_to_HTML_nonmath(parts[k])) : \
Packit 575503
			TeX_to_HTML_math(parts[k]))
Packit 575503
Packit 575503
	gsub(/[$][$][$]/,"$$",s) # restore display math
Packit 575503
Packit 575503
	return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function TeX_to_HTML_math(s)
Packit 575503
{
Packit 575503
	# Mostly a dummy for now, but HTML 3 could support some math translation
Packit 575503
Packit 575503
	gsub(/\\&/,"\\&",s)	# reduce TeX ampersands to SGML entities
Packit 575503
Packit 575503
	return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function TeX_to_HTML_nonmath(s)
Packit 575503
{
Packit 575503
	if (index(s,"\\") > 0)			# important optimization
Packit 575503
	{
Packit 575503
		gsub(/\\slash +/,"/",s)		# replace TeX slashes with conventional ones
Packit 575503
		gsub(/ *\\emdash +/," --- ",s)	# replace BibNet emdashes with conventional ones
Packit 575503
		gsub(/\\%/,"%",s)		# reduce TeX percents to conventional ones
Packit 575503
		gsub(/\\[$]/,"$",s)		# reduce TeX dollars to conventional ones
Packit 575503
		gsub(/\\#/,"#",s)		# reduce TeX sharps to conventional ones
Packit 575503
Packit 575503
		if (HTML)			# translate TeX markup to HTML
Packit 575503
		{
Packit 575503
			gsub(/\\&/,"\\&",s)	# reduce TeX ampersands to SGML entities
Packit 575503
			s = html_accents(s)
Packit 575503
			s = html_fonts(s)
Packit 575503
		}
Packit 575503
		else				# plain ASCII text output: discard all TeX markup
Packit 575503
		{
Packit 575503
			gsub(/\\\&/, "\\&", s)	# reduce TeX ampersands to conventional ones
Packit 575503
Packit 575503
			#gsub(/\\[a-z][a-z] +/,"",s) # remove TeX font changes
Packit 575503
			gsub(/\\[[:lower:]][[:lower:]] +/,"",s) # remove TeX font changes
Packit 575503
			#gsub(/\\[^A-Za-z]/,"",s) # remove remaining TeX control symbols
Packit 575503
			gsub(/\\[^[:alpha:]]/,"",s) # remove remaining TeX control symbols
Packit 575503
		}
Packit 575503
	}
Packit 575503
	return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function trim(s)
Packit 575503
{
Packit 575503
    gsub(/^[ \t]+/,"",s)
Packit 575503
    gsub(/[ \t]+$/,"",s)
Packit 575503
    return (s)
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function vol_no_month_year()
Packit 575503
{
Packit 575503
	return ("Volume " wrap(Volume)  ",  Number " wrap(Number) ", " wrap(Month) ", " wrap(Year))
Packit 575503
}
Packit 575503
Packit 575503
Packit 575503
function wrap(value)
Packit 575503
{
Packit 575503
	return (HTML ? ("" value "") : value)
Packit 575503
}