xref: /aosp_15_r20/external/one-true-awk/testdir/funstack.awk (revision 9a7741de182b2776d7b30d6355f2585c0780a51b)
1*9a7741deSElliott Hughes### ====================================================================
2*9a7741deSElliott Hughes###  @Awk-file{
3*9a7741deSElliott Hughes###     author          = "Nelson H. F. Beebe",
4*9a7741deSElliott Hughes###     version         = "1.00",
5*9a7741deSElliott Hughes###     date            = "09 October 1996",
6*9a7741deSElliott Hughes###     time            = "15:57:06 MDT",
7*9a7741deSElliott Hughes###     filename        = "journal-toc.awk",
8*9a7741deSElliott Hughes###     address         = "Center for Scientific Computing
9*9a7741deSElliott Hughes###                        Department of Mathematics
10*9a7741deSElliott Hughes###                        University of Utah
11*9a7741deSElliott Hughes###                        Salt Lake City, UT 84112
12*9a7741deSElliott Hughes###                        USA",
13*9a7741deSElliott Hughes###     telephone       = "+1 801 581 5254",
14*9a7741deSElliott Hughes###     FAX             = "+1 801 581 4148",
15*9a7741deSElliott Hughes###     URL             = "http://www.math.utah.edu/~beebe",
16*9a7741deSElliott Hughes###     checksum        = "25092 977 3357 26493",
17*9a7741deSElliott Hughes###     email           = "[email protected] (Internet)",
18*9a7741deSElliott Hughes###     codetable       = "ISO/ASCII",
19*9a7741deSElliott Hughes###     keywords        = "BibTeX, bibliography, HTML, journal table of
20*9a7741deSElliott Hughes###                        contents",
21*9a7741deSElliott Hughes###     supported       = "yes",
22*9a7741deSElliott Hughes###     docstring       = "Create a journal cover table of contents from
23*9a7741deSElliott Hughes###                        <at>Article{...} entries in a journal BibTeX
24*9a7741deSElliott Hughes###                        .bib file for checking the bibliography
25*9a7741deSElliott Hughes###                        database against the actual journal covers.
26*9a7741deSElliott Hughes###                        The output can be either plain text, or HTML.
27*9a7741deSElliott Hughes###
28*9a7741deSElliott Hughes###                        Usage:
29*9a7741deSElliott Hughes###                            bibclean -max-width 0 BibTeX-file(s) | \
30*9a7741deSElliott Hughes###                                bibsort -byvolume | \
31*9a7741deSElliott Hughes###                                awk -f journal-toc.awk \
32*9a7741deSElliott Hughes###                                    [-v HTML=nnn] [-v INDENT=nnn] \
33*9a7741deSElliott Hughes###                                    [-v BIBFILEURL=url] >foo.toc
34*9a7741deSElliott Hughes###
35*9a7741deSElliott Hughes###                            or if the bibliography is already sorted
36*9a7741deSElliott Hughes###                            by volume,
37*9a7741deSElliott Hughes###
38*9a7741deSElliott Hughes###                            bibclean -max-width 0 BibTeX-file(s) | \
39*9a7741deSElliott Hughes###                                awk -f journal-toc.awk \
40*9a7741deSElliott Hughes###                                    [-v HTML=nnn] [-v INDENT=nnn] \
41*9a7741deSElliott Hughes###                                    [-v BIBFILEURL=url] >foo.toc
42*9a7741deSElliott Hughes###
43*9a7741deSElliott Hughes###                        A non-zero value of the command-line option,
44*9a7741deSElliott Hughes###                        HTML=nnn, results in HTML output instead of
45*9a7741deSElliott Hughes###                        the default plain ASCII text (corresponding
46*9a7741deSElliott Hughes###                        to HTML=0).  The
47*9a7741deSElliott Hughes###
48*9a7741deSElliott Hughes###                        The INDENT=nnn command-line option specifies
49*9a7741deSElliott Hughes###                        the number of blanks to indent each logical
50*9a7741deSElliott Hughes###                        level of HTML.  The default is INDENT=4.
51*9a7741deSElliott Hughes###                        INDENT=0 suppresses indentation.  The INDENT
52*9a7741deSElliott Hughes###                        option has no effect when the default HTML=0
53*9a7741deSElliott Hughes###                        (plain text output) option is in effect.
54*9a7741deSElliott Hughes###
55*9a7741deSElliott Hughes###                        When HTML output is selected, the
56*9a7741deSElliott Hughes###                        BIBFILEURL=url command-line option provides a
57*9a7741deSElliott Hughes###                        way to request hypertext links from table of
58*9a7741deSElliott Hughes###                        contents page numbers to the complete BibTeX
59*9a7741deSElliott Hughes###                        entry for the article.  These links are
60*9a7741deSElliott Hughes###                        created by appending a sharp (#) and the
61*9a7741deSElliott Hughes###                        citation label to the BIBFILEURL value, which
62*9a7741deSElliott Hughes###                        conforms with the practice of
63*9a7741deSElliott Hughes###                        bibtex-to-html.awk.
64*9a7741deSElliott Hughes###
65*9a7741deSElliott Hughes###                        The HTML output form may be useful as a more
66*9a7741deSElliott Hughes###                        compact representation of journal article
67*9a7741deSElliott Hughes###                        bibliography data than the original BibTeX
68*9a7741deSElliott Hughes###                        file provides.  Of course, the
69*9a7741deSElliott Hughes###                        table-of-contents format provides less
70*9a7741deSElliott Hughes###                        information, and is considerably more
71*9a7741deSElliott Hughes###                        troublesome for a computer program to parse.
72*9a7741deSElliott Hughes###
73*9a7741deSElliott Hughes###                        When URL key values are provided, they will
74*9a7741deSElliott Hughes###                        be used to create hypertext links around
75*9a7741deSElliott Hughes###                        article titles.  This supports journals that
76*9a7741deSElliott Hughes###                        provide article contents on the World-Wide
77*9a7741deSElliott Hughes###                        Web.
78*9a7741deSElliott Hughes###
79*9a7741deSElliott Hughes###                        For parsing simplicity, this program requires
80*9a7741deSElliott Hughes###                        that BibTeX
81*9a7741deSElliott Hughes###
82*9a7741deSElliott Hughes###                            key = "value"
83*9a7741deSElliott Hughes###
84*9a7741deSElliott Hughes###                        and
85*9a7741deSElliott Hughes###
86*9a7741deSElliott Hughes###                            @String{name = "value"}
87*9a7741deSElliott Hughes###
88*9a7741deSElliott Hughes###                        specifications be entirely contained on
89*9a7741deSElliott Hughes###                        single lines, which is readily provided by
90*9a7741deSElliott Hughes###                        the `bibclean -max-width 0' filter.  It also
91*9a7741deSElliott Hughes###                        requires that bibliography entries begin and
92*9a7741deSElliott Hughes###                        end at the start of a line, and that
93*9a7741deSElliott Hughes###                        quotation marks, rather than balanced braces,
94*9a7741deSElliott Hughes###                        delimit string values.  This is a
95*9a7741deSElliott Hughes###                        conventional format that again can be
96*9a7741deSElliott Hughes###                        guaranteed by bibclean.
97*9a7741deSElliott Hughes###
98*9a7741deSElliott Hughes###                        This program requires `new' awk, as described
99*9a7741deSElliott Hughes###                        in the book
100*9a7741deSElliott Hughes###
101*9a7741deSElliott Hughes###                            Alfred V. Aho, Brian W. Kernighan, and
102*9a7741deSElliott Hughes###                            Peter J. Weinberger,
103*9a7741deSElliott Hughes###                            ``The AWK Programming Language'',
104*9a7741deSElliott Hughes###                            Addison-Wesley (1988), ISBN
105*9a7741deSElliott Hughes###                            0-201-07981-X,
106*9a7741deSElliott Hughes###
107*9a7741deSElliott Hughes###                        such as provided by programs named (GNU)
108*9a7741deSElliott Hughes###                        gawk, nawk, and recent AT&T awk.
109*9a7741deSElliott Hughes###
110*9a7741deSElliott Hughes###                        The checksum field above contains a CRC-16
111*9a7741deSElliott Hughes###                        checksum as the first value, followed by the
112*9a7741deSElliott Hughes###                        equivalent of the standard UNIX wc (word
113*9a7741deSElliott Hughes###                        count) utility output of lines, words, and
114*9a7741deSElliott Hughes###                        characters.  This is produced by Robert
115*9a7741deSElliott Hughes###                        Solovay's checksum utility.",
116*9a7741deSElliott Hughes###  }
117*9a7741deSElliott Hughes### ====================================================================
118*9a7741deSElliott Hughes
119*9a7741deSElliott HughesBEGIN						{ initialize() }
120*9a7741deSElliott Hughes
121*9a7741deSElliott Hughes/^ *@ *[Ss][Tt][Rr][Ii][Nn][Gg] *{/		{ do_String(); next }
122*9a7741deSElliott Hughes
123*9a7741deSElliott Hughes/^ *@ *[Pp][Rr][Ee][Aa][Mm][Bb][Ll][Ee]/	{ next }
124*9a7741deSElliott Hughes
125*9a7741deSElliott Hughes/^ *@ *[Aa][Rr][Tt][Ii][Cc][Ll][Ee]/		{ do_Article(); next }
126*9a7741deSElliott Hughes
127*9a7741deSElliott Hughes/^ *@/						{ do_Other(); next }
128*9a7741deSElliott Hughes
129*9a7741deSElliott Hughes/^ *author *= *\"/ 				{ do_author(); next }
130*9a7741deSElliott Hughes
131*9a7741deSElliott Hughes/^ *journal *= */				{ do_journal(); next }
132*9a7741deSElliott Hughes
133*9a7741deSElliott Hughes/^ *volume *= *\"/				{ do_volume(); next }
134*9a7741deSElliott Hughes
135*9a7741deSElliott Hughes/^ *number *= *\"/				{ do_number(); next }
136*9a7741deSElliott Hughes
137*9a7741deSElliott Hughes/^ *year *= *\"/				{ do_year(); next }
138*9a7741deSElliott Hughes
139*9a7741deSElliott Hughes/^ *month *= */					{ do_month(); next }
140*9a7741deSElliott Hughes
141*9a7741deSElliott Hughes/^ *title *= *\"/				{ do_title(); next }
142*9a7741deSElliott Hughes
143*9a7741deSElliott Hughes/^ *pages *= *\"/				{ do_pages(); next }
144*9a7741deSElliott Hughes
145*9a7741deSElliott Hughes/^ *URL *= *\"/					{ do_URL(); next }
146*9a7741deSElliott Hughes
147*9a7741deSElliott Hughes/^ *} *$/					{ if (In_Article) do_end_entry(); next }
148*9a7741deSElliott Hughes
149*9a7741deSElliott HughesEND						{ terminate() }
150*9a7741deSElliott Hughes
151*9a7741deSElliott Hughes
152*9a7741deSElliott Hughes########################################################################
153*9a7741deSElliott Hughes# NB: The programming conventions for variables in this program are:   #
154*9a7741deSElliott Hughes#	UPPERCASE		global constants and user options      #
155*9a7741deSElliott Hughes#	Initialuppercase	global variables                       #
156*9a7741deSElliott Hughes#	lowercase		local variables                        #
157*9a7741deSElliott Hughes# Any deviation is an error!                                           #
158*9a7741deSElliott Hughes########################################################################
159*9a7741deSElliott Hughes
160*9a7741deSElliott Hughes
161*9a7741deSElliott Hughesfunction do_Article()
162*9a7741deSElliott Hughes{
163*9a7741deSElliott Hughes	In_Article = 1
164*9a7741deSElliott Hughes
165*9a7741deSElliott Hughes	Citation_label = $0
166*9a7741deSElliott Hughes	sub(/^[^\{]*{/,"",Citation_label)
167*9a7741deSElliott Hughes	sub(/ *, *$/,"",Citation_label)
168*9a7741deSElliott Hughes
169*9a7741deSElliott Hughes	Author = ""
170*9a7741deSElliott Hughes        Title = ""
171*9a7741deSElliott Hughes        Journal = ""
172*9a7741deSElliott Hughes        Volume = ""
173*9a7741deSElliott Hughes        Number = ""
174*9a7741deSElliott Hughes        Month = ""
175*9a7741deSElliott Hughes        Year = ""
176*9a7741deSElliott Hughes        Pages = ""
177*9a7741deSElliott Hughes        Url = ""
178*9a7741deSElliott Hughes}
179*9a7741deSElliott Hughes
180*9a7741deSElliott Hughes
181*9a7741deSElliott Hughesfunction do_author()
182*9a7741deSElliott Hughes{
183*9a7741deSElliott Hughes	Author = TeX_to_HTML(get_value($0))
184*9a7741deSElliott Hughes}
185*9a7741deSElliott Hughes
186*9a7741deSElliott Hughes
187*9a7741deSElliott Hughesfunction do_end_entry( k,n,parts)
188*9a7741deSElliott Hughes{
189*9a7741deSElliott Hughes	n = split(Author,parts," and ")
190*9a7741deSElliott Hughes	if (Last_number != Number)
191*9a7741deSElliott Hughes		do_new_issue()
192*9a7741deSElliott Hughes	for (k = 1; k < n; ++k)
193*9a7741deSElliott Hughes		print_toc_line(parts[k] " and", "", "")
194*9a7741deSElliott Hughes	Title_prefix = html_begin_title()
195*9a7741deSElliott Hughes	Title_suffix = html_end_title()
196*9a7741deSElliott Hughes	if (html_length(Title) <= (MAX_TITLE_CHARS + MIN_LEADERS)) # complete title fits on line
197*9a7741deSElliott Hughes		print_toc_line(parts[n], Title, html_begin_pages() Pages html_end_pages())
198*9a7741deSElliott Hughes	else			# need to split long title over multiple lines
199*9a7741deSElliott Hughes		do_long_title(parts[n], Title, html_begin_pages() Pages html_end_pages())
200*9a7741deSElliott Hughes}
201*9a7741deSElliott Hughes
202*9a7741deSElliott Hughes
203*9a7741deSElliott Hughesfunction do_journal()
204*9a7741deSElliott Hughes{
205*9a7741deSElliott Hughes	if ($0 ~ /[=] *"/)	# have journal = "quoted journal name",
206*9a7741deSElliott Hughes		Journal = get_value($0)
207*9a7741deSElliott Hughes	else			# have journal = journal-abbreviation,
208*9a7741deSElliott Hughes	{
209*9a7741deSElliott Hughes        	Journal = get_abbrev($0)
210*9a7741deSElliott Hughes		if (Journal in String) # replace abbrev by its expansion
211*9a7741deSElliott Hughes			Journal = String[Journal]
212*9a7741deSElliott Hughes	}
213*9a7741deSElliott Hughes	gsub(/\\-/,"",Journal)	# remove discretionary hyphens
214*9a7741deSElliott Hughes}
215*9a7741deSElliott Hughes
216*9a7741deSElliott Hughes
217*9a7741deSElliott Hughesfunction do_long_title(author,title,pages, last_title,n)
218*9a7741deSElliott Hughes{
219*9a7741deSElliott Hughes	title = trim(title)			# discard leading and trailing space
220*9a7741deSElliott Hughes	while (length(title) > 0)
221*9a7741deSElliott Hughes	{
222*9a7741deSElliott Hughes		n = html_breakpoint(title,MAX_TITLE_CHARS+MIN_LEADERS)
223*9a7741deSElliott Hughes		last_title = substr(title,1,n)
224*9a7741deSElliott Hughes		title = substr(title,n+1)
225*9a7741deSElliott Hughes		sub(/^ +/,"",title)		# discard any leading space
226*9a7741deSElliott Hughes		print_toc_line(author, last_title, (length(title) == 0) ? pages : "")
227*9a7741deSElliott Hughes		author = ""
228*9a7741deSElliott Hughes	}
229*9a7741deSElliott Hughes}
230*9a7741deSElliott Hughes
231*9a7741deSElliott Hughes
232*9a7741deSElliott Hughesfunction do_month( k,n,parts)
233*9a7741deSElliott Hughes{
234*9a7741deSElliott Hughes	Month = ($0 ~ /[=] *"/) ? get_value($0) : get_abbrev($0)
235*9a7741deSElliott Hughes	gsub(/[\"]/,"",Month)
236*9a7741deSElliott Hughes	gsub(/ *# *\\slash *# */," / ",Month)
237*9a7741deSElliott Hughes	gsub(/ *# *-+ *# */," / ",Month)
238*9a7741deSElliott Hughes	n = split(Month,parts," */ *")
239*9a7741deSElliott Hughes	Month = ""
240*9a7741deSElliott Hughes	for (k = 1; k <= n; ++k)
241*9a7741deSElliott Hughes		Month = Month ((k > 1) ? " / " : "") \
242*9a7741deSElliott Hughes			((parts[k] in Month_expansion) ? Month_expansion[parts[k]] : parts[k])
243*9a7741deSElliott Hughes}
244*9a7741deSElliott Hughes
245*9a7741deSElliott Hughes
246*9a7741deSElliott Hughesfunction do_new_issue()
247*9a7741deSElliott Hughes{
248*9a7741deSElliott Hughes	Last_number = Number
249*9a7741deSElliott Hughes	if (HTML)
250*9a7741deSElliott Hughes	{
251*9a7741deSElliott Hughes		if (Last_volume != Volume)
252*9a7741deSElliott Hughes		{
253*9a7741deSElliott Hughes			Last_volume = Volume
254*9a7741deSElliott Hughes			print_line(prefix(2) "<BR>")
255*9a7741deSElliott Hughes		}
256*9a7741deSElliott Hughes		html_end_toc()
257*9a7741deSElliott Hughes		html_begin_issue()
258*9a7741deSElliott Hughes		print_line(prefix(2) Journal "<BR>")
259*9a7741deSElliott Hughes	}
260*9a7741deSElliott Hughes	else
261*9a7741deSElliott Hughes	{
262*9a7741deSElliott Hughes		print_line("")
263*9a7741deSElliott Hughes		print_line(Journal)
264*9a7741deSElliott Hughes	}
265*9a7741deSElliott Hughes
266*9a7741deSElliott Hughes	print_line(strip_html(vol_no_month_year()))
267*9a7741deSElliott Hughes
268*9a7741deSElliott Hughes	if (HTML)
269*9a7741deSElliott Hughes	{
270*9a7741deSElliott Hughes		html_end_issue()
271*9a7741deSElliott Hughes		html_toc_entry()
272*9a7741deSElliott Hughes		html_begin_toc()
273*9a7741deSElliott Hughes	}
274*9a7741deSElliott Hughes	else
275*9a7741deSElliott Hughes		print_line("")
276*9a7741deSElliott Hughes}
277*9a7741deSElliott Hughes
278*9a7741deSElliott Hughes
279*9a7741deSElliott Hughesfunction do_number()
280*9a7741deSElliott Hughes{
281*9a7741deSElliott Hughes	Number = get_value($0)
282*9a7741deSElliott Hughes}
283*9a7741deSElliott Hughes
284*9a7741deSElliott Hughes
285*9a7741deSElliott Hughesfunction do_Other()
286*9a7741deSElliott Hughes{
287*9a7741deSElliott Hughes	In_Article = 0
288*9a7741deSElliott Hughes}
289*9a7741deSElliott Hughes
290*9a7741deSElliott Hughes
291*9a7741deSElliott Hughesfunction do_pages()
292*9a7741deSElliott Hughes{
293*9a7741deSElliott Hughes	Pages = get_value($0)
294*9a7741deSElliott Hughes	sub(/--[?][?]/,"",Pages)
295*9a7741deSElliott Hughes}
296*9a7741deSElliott Hughes
297*9a7741deSElliott Hughes
298*9a7741deSElliott Hughesfunction do_String()
299*9a7741deSElliott Hughes{
300*9a7741deSElliott Hughes	sub(/^[^\{]*\{/,"",$0)	# discard up to and including open brace
301*9a7741deSElliott Hughes	sub(/\} *$/,"",$0)	# discard from optional whitespace and trailing brace to end of line
302*9a7741deSElliott Hughes	String[get_key($0)] = get_value($0)
303*9a7741deSElliott Hughes}
304*9a7741deSElliott Hughes
305*9a7741deSElliott Hughes
306*9a7741deSElliott Hughesfunction do_title()
307*9a7741deSElliott Hughes{
308*9a7741deSElliott Hughes	Title = TeX_to_HTML(get_value($0))
309*9a7741deSElliott Hughes}
310*9a7741deSElliott Hughes
311*9a7741deSElliott Hughes
312*9a7741deSElliott Hughesfunction do_URL( parts)
313*9a7741deSElliott Hughes{
314*9a7741deSElliott Hughes	Url = get_value($0)
315*9a7741deSElliott Hughes	split(Url,parts,"[,;]")			# in case we have multiple URLs
316*9a7741deSElliott Hughes	Url = trim(parts[1])
317*9a7741deSElliott Hughes}
318*9a7741deSElliott Hughes
319*9a7741deSElliott Hughes
320*9a7741deSElliott Hughesfunction do_volume()
321*9a7741deSElliott Hughes{
322*9a7741deSElliott Hughes	Volume = get_value($0)
323*9a7741deSElliott Hughes}
324*9a7741deSElliott Hughes
325*9a7741deSElliott Hughes
326*9a7741deSElliott Hughesfunction do_year()
327*9a7741deSElliott Hughes{
328*9a7741deSElliott Hughes	Year = get_value($0)
329*9a7741deSElliott Hughes}
330*9a7741deSElliott Hughes
331*9a7741deSElliott Hughes
332*9a7741deSElliott Hughesfunction get_abbrev(s)
333*9a7741deSElliott Hughes{	# return abbrev from ``key = abbrev,''
334*9a7741deSElliott Hughes	sub(/^[^=]*= */,"",s)	# discard text up to start of non-blank value
335*9a7741deSElliott Hughes	sub(/ *,? *$/,"",s)	# discard trailing optional whitspace, quote,
336*9a7741deSElliott Hughes				# optional comma, and optional space
337*9a7741deSElliott Hughes	return (s)
338*9a7741deSElliott Hughes}
339*9a7741deSElliott Hughes
340*9a7741deSElliott Hughes
341*9a7741deSElliott Hughesfunction get_key(s)
342*9a7741deSElliott Hughes{	# return kay from ``key = "value",''
343*9a7741deSElliott Hughes	sub(/^ */,"",s)		# discard leading space
344*9a7741deSElliott Hughes	sub(/ *=.*$/,"",s)	# discard everthing after key
345*9a7741deSElliott Hughes
346*9a7741deSElliott Hughes	return (s)
347*9a7741deSElliott Hughes}
348*9a7741deSElliott Hughes
349*9a7741deSElliott Hughes
350*9a7741deSElliott Hughesfunction get_value(s)
351*9a7741deSElliott Hughes{	# return value from ``key = "value",''
352*9a7741deSElliott Hughes	sub(/^[^\"]*\" */,"",s)	# discard text up to start of non-blank value
353*9a7741deSElliott Hughes	sub(/ *\",? *$/,"",s)	# discard trailing optional whitspace, quote,
354*9a7741deSElliott Hughes				# optional comma, and optional space
355*9a7741deSElliott Hughes	return (s)
356*9a7741deSElliott Hughes}
357*9a7741deSElliott Hughes
358*9a7741deSElliott Hughes
359*9a7741deSElliott Hughesfunction html_accents(s)
360*9a7741deSElliott Hughes{
361*9a7741deSElliott Hughes	if (index(s,"\\") > 0)			# important optimization
362*9a7741deSElliott Hughes	{
363*9a7741deSElliott Hughes		# Convert common lower-case accented letters according to the
364*9a7741deSElliott Hughes		# table on p. 169 of in Peter Flynn's ``The World Wide Web
365*9a7741deSElliott Hughes		# Handbook'', International Thomson Computer Press, 1995, ISBN
366*9a7741deSElliott Hughes		# 1-85032-205-8.  The official table of ISO Latin 1 SGML
367*9a7741deSElliott Hughes		# entities used in HTML can be found in the file
368*9a7741deSElliott Hughes		# /usr/local/lib/html-check/lib/ISOlat1.sgml (your path
369*9a7741deSElliott Hughes		# may differ).
370*9a7741deSElliott Hughes
371*9a7741deSElliott Hughes		gsub(/{\\\a}/,	"\\&agrave;",	s)
372*9a7741deSElliott Hughes		gsub(/{\\'a}/,	"\\&aacute;",	s)
373*9a7741deSElliott Hughes		gsub(/{\\[\^]a}/,"\\&acirc;",	s)
374*9a7741deSElliott Hughes		gsub(/{\\~a}/,	"\\&atilde;",	s)
375*9a7741deSElliott Hughes		gsub(/{\\\"a}/,	"\\&auml;",	s)
376*9a7741deSElliott Hughes		gsub(/{\\aa}/,	"\\&aring;",	s)
377*9a7741deSElliott Hughes		gsub(/{\\ae}/,	"\\&aelig;",	s)
378*9a7741deSElliott Hughes
379*9a7741deSElliott Hughes		gsub(/{\\c{c}}/,"\\&ccedil;",	s)
380*9a7741deSElliott Hughes
381*9a7741deSElliott Hughes		gsub(/{\\\e}/,	"\\&egrave;",	s)
382*9a7741deSElliott Hughes		gsub(/{\\'e}/,	"\\&eacute;",	s)
383*9a7741deSElliott Hughes		gsub(/{\\[\^]e}/,"\\&ecirc;",	s)
384*9a7741deSElliott Hughes		gsub(/{\\\"e}/,	"\\&euml;",	s)
385*9a7741deSElliott Hughes
386*9a7741deSElliott Hughes		gsub(/{\\\i}/,	"\\&igrave;",	s)
387*9a7741deSElliott Hughes		gsub(/{\\'i}/,	"\\&iacute;",	s)
388*9a7741deSElliott Hughes		gsub(/{\\[\^]i}/,"\\&icirc;",	s)
389*9a7741deSElliott Hughes		gsub(/{\\\"i}/,	"\\&iuml;",	s)
390*9a7741deSElliott Hughes
391*9a7741deSElliott Hughes		# ignore eth and thorn
392*9a7741deSElliott Hughes
393*9a7741deSElliott Hughes		gsub(/{\\~n}/,	"\\&ntilde;",	s)
394*9a7741deSElliott Hughes
395*9a7741deSElliott Hughes		gsub(/{\\\o}/,	"\\&ograve;",	s)
396*9a7741deSElliott Hughes		gsub(/{\\'o}/,	"\\&oacute;",	s)
397*9a7741deSElliott Hughes		gsub(/{\\[\^]o}/, "\\&ocirc;",	s)
398*9a7741deSElliott Hughes		gsub(/{\\~o}/,	"\\&otilde;",	s)
399*9a7741deSElliott Hughes		gsub(/{\\\"o}/,	"\\&ouml;",	s)
400*9a7741deSElliott Hughes		gsub(/{\\o}/,	"\\&oslash;",	s)
401*9a7741deSElliott Hughes
402*9a7741deSElliott Hughes		gsub(/{\\\u}/,	"\\&ugrave;",	s)
403*9a7741deSElliott Hughes		gsub(/{\\'u}/,	"\\&uacute;",	s)
404*9a7741deSElliott Hughes		gsub(/{\\[\^]u}/,"\\&ucirc;",	s)
405*9a7741deSElliott Hughes		gsub(/{\\\"u}/,	"\\&uuml;",	s)
406*9a7741deSElliott Hughes
407*9a7741deSElliott Hughes		gsub(/{\\'y}/,	"\\&yacute;",	s)
408*9a7741deSElliott Hughes		gsub(/{\\\"y}/,	"\\&yuml;",	s)
409*9a7741deSElliott Hughes
410*9a7741deSElliott Hughes		# Now do the same for upper-case accents
411*9a7741deSElliott Hughes
412*9a7741deSElliott Hughes		gsub(/{\\\A}/,	"\\&Agrave;",	s)
413*9a7741deSElliott Hughes		gsub(/{\\'A}/,	"\\&Aacute;",	s)
414*9a7741deSElliott Hughes		gsub(/{\\[\^]A}/,	"\\&Acirc;",	s)
415*9a7741deSElliott Hughes		gsub(/{\\~A}/,	"\\&Atilde;",	s)
416*9a7741deSElliott Hughes		gsub(/{\\\"A}/,	"\\&Auml;",	s)
417*9a7741deSElliott Hughes		gsub(/{\\AA}/,	"\\&Aring;",	s)
418*9a7741deSElliott Hughes		gsub(/{\\AE}/,	"\\&AElig;",	s)
419*9a7741deSElliott Hughes
420*9a7741deSElliott Hughes		gsub(/{\\c{C}}/,"\\&Ccedil;",	s)
421*9a7741deSElliott Hughes
422*9a7741deSElliott Hughes		gsub(/{\\\e}/,	"\\&Egrave;",	s)
423*9a7741deSElliott Hughes		gsub(/{\\'E}/,	"\\&Eacute;",	s)
424*9a7741deSElliott Hughes		gsub(/{\\[\^]E}/,	"\\&Ecirc;",	s)
425*9a7741deSElliott Hughes		gsub(/{\\\"E}/,	"\\&Euml;",	s)
426*9a7741deSElliott Hughes
427*9a7741deSElliott Hughes		gsub(/{\\\I}/,	"\\&Igrave;",	s)
428*9a7741deSElliott Hughes		gsub(/{\\'I}/,	"\\&Iacute;",	s)
429*9a7741deSElliott Hughes		gsub(/{\\[\^]I}/,	"\\&Icirc;",	s)
430*9a7741deSElliott Hughes		gsub(/{\\\"I}/,	"\\&Iuml;",	s)
431*9a7741deSElliott Hughes
432*9a7741deSElliott Hughes		# ignore eth and thorn
433*9a7741deSElliott Hughes
434*9a7741deSElliott Hughes		gsub(/{\\~N}/,	"\\&Ntilde;",	s)
435*9a7741deSElliott Hughes
436*9a7741deSElliott Hughes		gsub(/{\\\O}/,	"\\&Ograve;",	s)
437*9a7741deSElliott Hughes		gsub(/{\\'O}/,	"\\&Oacute;",	s)
438*9a7741deSElliott Hughes		gsub(/{\\[\^]O}/,	"\\&Ocirc;",	s)
439*9a7741deSElliott Hughes		gsub(/{\\~O}/,	"\\&Otilde;",	s)
440*9a7741deSElliott Hughes		gsub(/{\\\"O}/,	"\\&Ouml;",	s)
441*9a7741deSElliott Hughes		gsub(/{\\O}/,	"\\&Oslash;",	s)
442*9a7741deSElliott Hughes
443*9a7741deSElliott Hughes		gsub(/{\\\U}/,	"\\&Ugrave;",	s)
444*9a7741deSElliott Hughes		gsub(/{\\'U}/,	"\\&Uacute;",	s)
445*9a7741deSElliott Hughes		gsub(/{\\[\^]U}/,	"\\&Ucirc;",	s)
446*9a7741deSElliott Hughes		gsub(/{\\\"U}/,	"\\&Uuml;",	s)
447*9a7741deSElliott Hughes
448*9a7741deSElliott Hughes		gsub(/{\\'Y}/,	"\\&Yacute;",	s)
449*9a7741deSElliott Hughes
450*9a7741deSElliott Hughes		gsub(/{\\ss}/,	"\\&szlig;",	s)
451*9a7741deSElliott Hughes
452*9a7741deSElliott Hughes		# Others not mentioned in Flynn's book
453*9a7741deSElliott Hughes		gsub(/{\\'\\i}/,"\\&iacute;",	s)
454*9a7741deSElliott Hughes		gsub(/{\\'\\j}/,"j",		s)
455*9a7741deSElliott Hughes	}
456*9a7741deSElliott Hughes	return (s)
457*9a7741deSElliott Hughes}
458*9a7741deSElliott Hughes
459*9a7741deSElliott Hughes
460*9a7741deSElliott Hughesfunction html_begin_issue()
461*9a7741deSElliott Hughes{
462*9a7741deSElliott Hughes	print_line("")
463*9a7741deSElliott Hughes	print_line(prefix(2) "<HR>")
464*9a7741deSElliott Hughes	print_line("")
465*9a7741deSElliott Hughes	print_line(prefix(2) "<H1>")
466*9a7741deSElliott Hughes	print_line(prefix(3) "<A NAME=\"" html_label() "\">")
467*9a7741deSElliott Hughes}
468*9a7741deSElliott Hughes
469*9a7741deSElliott Hughes
470*9a7741deSElliott Hughesfunction html_begin_pages()
471*9a7741deSElliott Hughes{
472*9a7741deSElliott Hughes	return ((HTML && (BIBFILEURL != "")) ? ("<A HREF=\"" BIBFILEURL "#" Citation_label "\">") : "")
473*9a7741deSElliott Hughes}
474*9a7741deSElliott Hughes
475*9a7741deSElliott Hughes
476*9a7741deSElliott Hughesfunction html_begin_pre()
477*9a7741deSElliott Hughes{
478*9a7741deSElliott Hughes	In_PRE = 1
479*9a7741deSElliott Hughes	print_line("<PRE>")
480*9a7741deSElliott Hughes}
481*9a7741deSElliott Hughes
482*9a7741deSElliott Hughes
483*9a7741deSElliott Hughesfunction html_begin_title()
484*9a7741deSElliott Hughes{
485*9a7741deSElliott Hughes	return ((HTML && (Url != "")) ? ("<A HREF=\"" Url "\">") : "")
486*9a7741deSElliott Hughes}
487*9a7741deSElliott Hughes
488*9a7741deSElliott Hughes
489*9a7741deSElliott Hughesfunction html_begin_toc()
490*9a7741deSElliott Hughes{
491*9a7741deSElliott Hughes	html_end_toc()
492*9a7741deSElliott Hughes	html_begin_pre()
493*9a7741deSElliott Hughes}
494*9a7741deSElliott Hughes
495*9a7741deSElliott Hughes
496*9a7741deSElliott Hughesfunction html_body( k)
497*9a7741deSElliott Hughes{
498*9a7741deSElliott Hughes	for (k = 1; k <= BodyLines; ++k)
499*9a7741deSElliott Hughes		print Body[k]
500*9a7741deSElliott Hughes}
501*9a7741deSElliott Hughes
502*9a7741deSElliott Hughesfunction html_breakpoint(title,maxlength, break_after,k)
503*9a7741deSElliott Hughes{
504*9a7741deSElliott Hughes	# Return the largest character position in title AFTER which we
505*9a7741deSElliott Hughes	# can break the title across lines, without exceeding maxlength
506*9a7741deSElliott Hughes	# visible characters.
507*9a7741deSElliott Hughes	if (html_length(title) > maxlength)	# then need to split title across lines
508*9a7741deSElliott Hughes	{
509*9a7741deSElliott Hughes		# In the presence of HTML markup, the initialization of
510*9a7741deSElliott Hughes		# k here is complicated, because we need to advance it
511*9a7741deSElliott Hughes		# until html_length(title) is at least maxlength,
512*9a7741deSElliott Hughes		# without invoking the expensive html_length() function
513*9a7741deSElliott Hughes		# too frequently.  The need to split the title makes the
514*9a7741deSElliott Hughes		# alternative of delayed insertion of HTML markup much
515*9a7741deSElliott Hughes		# more complicated.
516*9a7741deSElliott Hughes		break_after = 0
517*9a7741deSElliott Hughes		for (k = min(maxlength,length(title)); k < length(title); ++k)
518*9a7741deSElliott Hughes		{
519*9a7741deSElliott Hughes			if (substr(title,k+1,1) == " ")
520*9a7741deSElliott Hughes			{		# could break after position k
521*9a7741deSElliott Hughes				if (html_length(substr(title,1,k)) <= maxlength)
522*9a7741deSElliott Hughes					break_after = k
523*9a7741deSElliott Hughes				else	# advanced too far, retreat back to last break_after
524*9a7741deSElliott Hughes					break
525*9a7741deSElliott Hughes			}
526*9a7741deSElliott Hughes		}
527*9a7741deSElliott Hughes		if (break_after == 0)		# no breakpoint found by forward scan
528*9a7741deSElliott Hughes		{				# so switch to backward scan
529*9a7741deSElliott Hughes			for (k = min(maxlength,length(title)) - 1; \
530*9a7741deSElliott Hughes				(k > 0) && (substr(title,k+1,1) != " "); --k)
531*9a7741deSElliott Hughes				;		# find space at which to break title
532*9a7741deSElliott Hughes			if (k < 1)		# no break point found
533*9a7741deSElliott Hughes				k = length(title) # so must print entire string
534*9a7741deSElliott Hughes		}
535*9a7741deSElliott Hughes		else
536*9a7741deSElliott Hughes			k = break_after
537*9a7741deSElliott Hughes	}
538*9a7741deSElliott Hughes	else					# title fits on one line
539*9a7741deSElliott Hughes		k = length(title)
540*9a7741deSElliott Hughes	return (k)
541*9a7741deSElliott Hughes}
542*9a7741deSElliott Hughes
543*9a7741deSElliott Hughes
544*9a7741deSElliott Hughes
545*9a7741deSElliott Hughesfunction html_end_issue()
546*9a7741deSElliott Hughes{
547*9a7741deSElliott Hughes	print_line(prefix(3) "</A>")
548*9a7741deSElliott Hughes	print_line(prefix(2) "</H1>")
549*9a7741deSElliott Hughes}
550*9a7741deSElliott Hughes
551*9a7741deSElliott Hughes
552*9a7741deSElliott Hughesfunction html_end_pages()
553*9a7741deSElliott Hughes{
554*9a7741deSElliott Hughes	return ((HTML && (BIBFILEURL != "")) ? "</A>" : "")
555*9a7741deSElliott Hughes}
556*9a7741deSElliott Hughes
557*9a7741deSElliott Hughes
558*9a7741deSElliott Hughesfunction html_end_pre()
559*9a7741deSElliott Hughes{
560*9a7741deSElliott Hughes	if (In_PRE)
561*9a7741deSElliott Hughes	{
562*9a7741deSElliott Hughes		print_line("</PRE>")
563*9a7741deSElliott Hughes		In_PRE = 0
564*9a7741deSElliott Hughes	}
565*9a7741deSElliott Hughes}
566*9a7741deSElliott Hughes
567*9a7741deSElliott Hughes
568*9a7741deSElliott Hughesfunction html_end_title()
569*9a7741deSElliott Hughes{
570*9a7741deSElliott Hughes	return ((HTML && (Url != "")) ? "</A>" : "")
571*9a7741deSElliott Hughes}
572*9a7741deSElliott Hughes
573*9a7741deSElliott Hughes
574*9a7741deSElliott Hughesfunction html_end_toc()
575*9a7741deSElliott Hughes{
576*9a7741deSElliott Hughes	html_end_pre()
577*9a7741deSElliott Hughes}
578*9a7741deSElliott Hughes
579*9a7741deSElliott Hughes
580*9a7741deSElliott Hughesfunction html_fonts(s, arg,control_word,k,level,n,open_brace)
581*9a7741deSElliott Hughes{
582*9a7741deSElliott Hughes	open_brace = index(s,"{")
583*9a7741deSElliott Hughes	if (open_brace > 0)			# important optimization
584*9a7741deSElliott Hughes	{
585*9a7741deSElliott Hughes		level = 1
586*9a7741deSElliott Hughes		for (k = open_brace + 1; (level != 0) && (k <= length(s)); ++k)
587*9a7741deSElliott Hughes		{
588*9a7741deSElliott Hughes			if (substr(s,k,1) == "{")
589*9a7741deSElliott Hughes				level++
590*9a7741deSElliott Hughes			else if (substr(s,k,1) == "}")
591*9a7741deSElliott Hughes				level--
592*9a7741deSElliott Hughes		}
593*9a7741deSElliott Hughes
594*9a7741deSElliott Hughes		# {...} is now found at open_brace ... (k-1)
595*9a7741deSElliott Hughes		for (control_word in Font_decl_map)	# look for {\xxx ...}
596*9a7741deSElliott Hughes		{
597*9a7741deSElliott Hughes			if (substr(s,open_brace+1,length(control_word)+1) ~ \
598*9a7741deSElliott Hughes				("\\" control_word "[^A-Za-z]"))
599*9a7741deSElliott Hughes			{
600*9a7741deSElliott Hughes				n = open_brace + 1 + length(control_word)
601*9a7741deSElliott Hughes				arg = trim(substr(s,n,k - n))
602*9a7741deSElliott Hughes				if (Font_decl_map[control_word] == "toupper") # arg -> ARG
603*9a7741deSElliott Hughes					arg = toupper(arg)
604*9a7741deSElliott Hughes				else if (Font_decl_map[control_word] != "") # arg -> <TAG>arg</TAG>
605*9a7741deSElliott Hughes					arg = "<" Font_decl_map[control_word] ">" arg "</" Font_decl_map[control_word] ">"
606*9a7741deSElliott Hughes				return (substr(s,1,open_brace-1) arg html_fonts(substr(s,k)))
607*9a7741deSElliott Hughes			}
608*9a7741deSElliott Hughes		}
609*9a7741deSElliott Hughes		for (control_word in Font_cmd_map)	# look for \xxx{...}
610*9a7741deSElliott Hughes		{
611*9a7741deSElliott Hughes			if (substr(s,open_brace - length(control_word),length(control_word)) ~ \
612*9a7741deSElliott Hughes				("\\" control_word))
613*9a7741deSElliott Hughes			{
614*9a7741deSElliott Hughes				n = open_brace + 1
615*9a7741deSElliott Hughes				arg = trim(substr(s,n,k - n))
616*9a7741deSElliott Hughes				if (Font_cmd_map[control_word] == "toupper") # arg -> ARG
617*9a7741deSElliott Hughes					arg = toupper(arg)
618*9a7741deSElliott Hughes				else if (Font_cmd_map[control_word] != "") # arg -> <TAG>arg</TAG>
619*9a7741deSElliott Hughes					arg = "<" Font_cmd_map[control_word] ">" arg "</" Font_cmd_map[control_word] ">"
620*9a7741deSElliott Hughes				n = open_brace - length(control_word) - 1
621*9a7741deSElliott Hughes				return (substr(s,1,n) arg html_fonts(substr(s,k)))
622*9a7741deSElliott Hughes			}
623*9a7741deSElliott Hughes		}
624*9a7741deSElliott Hughes	}
625*9a7741deSElliott Hughes	return (s)
626*9a7741deSElliott Hughes}
627*9a7741deSElliott Hughes
628*9a7741deSElliott Hughes
629*9a7741deSElliott Hughesfunction html_header()
630*9a7741deSElliott Hughes{
631*9a7741deSElliott Hughes	USER = ENVIRON["USER"]
632*9a7741deSElliott Hughes	if (USER == "")
633*9a7741deSElliott Hughes	    USER = ENVIRON["LOGNAME"]
634*9a7741deSElliott Hughes	if (USER == "")
635*9a7741deSElliott Hughes	    USER = "????"
636*9a7741deSElliott Hughes	"hostname" | getline HOSTNAME
637*9a7741deSElliott Hughes	"date" | getline DATE
638*9a7741deSElliott Hughes	("ypcat passwd | grep '^" USER ":' | awk -F: '{print $5}'") | getline PERSONAL_NAME
639*9a7741deSElliott Hughes	if (PERSONAL_NAME == "")
640*9a7741deSElliott Hughes	    ("grep  '^" USER ":' /etc/passwd | awk -F: '{print $5}'") | getline PERSONAL_NAME
641*9a7741deSElliott Hughes
642*9a7741deSElliott Hughes
643*9a7741deSElliott Hughes	print "<!-- WARNING: Do NOT edit this file.  It was converted from -->"
644*9a7741deSElliott Hughes	print "<!-- BibTeX format to HTML by journal-toc.awk version " VERSION_NUMBER " " VERSION_DATE " -->"
645*9a7741deSElliott Hughes	print "<!-- on " DATE " -->"
646*9a7741deSElliott Hughes	print "<!-- for " PERSONAL_NAME " (" USER "@" HOSTNAME ") -->"
647*9a7741deSElliott Hughes	print ""
648*9a7741deSElliott Hughes	print ""
649*9a7741deSElliott Hughes	print "<!DOCTYPE HTML public \"-//IETF//DTD HTML//EN\">"
650*9a7741deSElliott Hughes	print ""
651*9a7741deSElliott Hughes	print "<HTML>"
652*9a7741deSElliott Hughes	print prefix(1) "<HEAD>"
653*9a7741deSElliott Hughes	print prefix(2) "<TITLE>"
654*9a7741deSElliott Hughes	print prefix(3)  Journal
655*9a7741deSElliott Hughes	print prefix(2) "</TITLE>"
656*9a7741deSElliott Hughes	print prefix(2) "<LINK REV=\"made\" HREF=\"mailto:" USER "@" HOSTNAME "\">"
657*9a7741deSElliott Hughes	print prefix(1) "</HEAD>"
658*9a7741deSElliott Hughes	print ""
659*9a7741deSElliott Hughes	print prefix(1) "<BODY>"
660*9a7741deSElliott Hughes}
661*9a7741deSElliott Hughes
662*9a7741deSElliott Hughes
663*9a7741deSElliott Hughesfunction html_label( label)
664*9a7741deSElliott Hughes{
665*9a7741deSElliott Hughes	label = Volume "(" Number "):" Month ":" Year
666*9a7741deSElliott Hughes	gsub(/[^A-Za-z0-9():,;.\/\-]/,"",label)
667*9a7741deSElliott Hughes	return (label)
668*9a7741deSElliott Hughes}
669*9a7741deSElliott Hughes
670*9a7741deSElliott Hughes
671*9a7741deSElliott Hughesfunction html_length(s)
672*9a7741deSElliott Hughes{	# Return visible length of s, ignoring any HTML markup
673*9a7741deSElliott Hughes	if (HTML)
674*9a7741deSElliott Hughes	{
675*9a7741deSElliott Hughes		gsub(/<\/?[^>]*>/,"",s)		# remove SGML tags
676*9a7741deSElliott Hughes		gsub(/&[A-Za-z0-9]+;/,"",s)	# remove SGML entities
677*9a7741deSElliott Hughes	}
678*9a7741deSElliott Hughes	return (length(s))
679*9a7741deSElliott Hughes}
680*9a7741deSElliott Hughes
681*9a7741deSElliott Hughes
682*9a7741deSElliott Hughesfunction html_toc()
683*9a7741deSElliott Hughes{
684*9a7741deSElliott Hughes	print prefix(2) "<H1>"
685*9a7741deSElliott Hughes	print prefix(3) "Table of contents for issues of " Journal
686*9a7741deSElliott Hughes	print prefix(2) "</H1>"
687*9a7741deSElliott Hughes	print HTML_TOC
688*9a7741deSElliott Hughes}
689*9a7741deSElliott Hughes
690*9a7741deSElliott Hughes
691*9a7741deSElliott Hughesfunction html_toc_entry()
692*9a7741deSElliott Hughes{
693*9a7741deSElliott Hughes	HTML_TOC = HTML_TOC "        <A HREF=\"#" html_label() "\">"
694*9a7741deSElliott Hughes	HTML_TOC = HTML_TOC vol_no_month_year()
695*9a7741deSElliott Hughes	HTML_TOC = HTML_TOC "</A><BR>" "\n"
696*9a7741deSElliott Hughes}
697*9a7741deSElliott Hughes
698*9a7741deSElliott Hughes
699*9a7741deSElliott Hughesfunction html_trailer()
700*9a7741deSElliott Hughes{
701*9a7741deSElliott Hughes	html_end_pre()
702*9a7741deSElliott Hughes	print prefix(1) "</BODY>"
703*9a7741deSElliott Hughes	print "</HTML>"
704*9a7741deSElliott Hughes}
705*9a7741deSElliott Hughes
706*9a7741deSElliott Hughes
707*9a7741deSElliott Hughesfunction initialize()
708*9a7741deSElliott Hughes{
709*9a7741deSElliott Hughes	# NB: Update these when the program changes
710*9a7741deSElliott Hughes	VERSION_DATE = "[09-Oct-1996]"
711*9a7741deSElliott Hughes	VERSION_NUMBER = "1.00"
712*9a7741deSElliott Hughes
713*9a7741deSElliott Hughes	HTML = (HTML == "") ? 0 : (0 + HTML)
714*9a7741deSElliott Hughes
715*9a7741deSElliott Hughes	if (INDENT == "")
716*9a7741deSElliott Hughes		INDENT = 4
717*9a7741deSElliott Hughes
718*9a7741deSElliott Hughes	if (HTML == 0)
719*9a7741deSElliott Hughes		INDENT = 0	# indentation suppressed in ASCII mode
720*9a7741deSElliott Hughes
721*9a7741deSElliott Hughes	LEADERS = " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ."
722*9a7741deSElliott Hughes
723*9a7741deSElliott Hughes	MAX_TITLE_CHARS = 36	# 36 produces a 79-char output line when there is
724*9a7741deSElliott Hughes				# just an initial page number.  If this is
725*9a7741deSElliott Hughes				# increased, the LEADERS string may need to be
726*9a7741deSElliott Hughes				# lengthened.
727*9a7741deSElliott Hughes
728*9a7741deSElliott Hughes	MIN_LEADERS = 4		# Minimum number of characters from LEADERS
729*9a7741deSElliott Hughes				# required when leaders are used.  The total
730*9a7741deSElliott Hughes				# number of characters that can appear in a
731*9a7741deSElliott Hughes				# title line is MAX_TITLE_CHARS + MIN_LEADERS.
732*9a7741deSElliott Hughes				# Leaders are omitted when the title length is
733*9a7741deSElliott Hughes				# between MAX_TITLE_CHARS and this sum.
734*9a7741deSElliott Hughes
735*9a7741deSElliott Hughes	MIN_LEADERS_SPACE = "        "	# must be at least MIN_LEADERS characters long
736*9a7741deSElliott Hughes
737*9a7741deSElliott Hughes	Month_expansion["jan"]	= "January"
738*9a7741deSElliott Hughes	Month_expansion["feb"]	= "February"
739*9a7741deSElliott Hughes	Month_expansion["mar"]	= "March"
740*9a7741deSElliott Hughes	Month_expansion["apr"]	= "April"
741*9a7741deSElliott Hughes	Month_expansion["may"]	= "May"
742*9a7741deSElliott Hughes	Month_expansion["jun"]	= "June"
743*9a7741deSElliott Hughes	Month_expansion["jul"]	= "July"
744*9a7741deSElliott Hughes	Month_expansion["aug"]	= "August"
745*9a7741deSElliott Hughes	Month_expansion["sep"]	= "September"
746*9a7741deSElliott Hughes	Month_expansion["oct"]	= "October"
747*9a7741deSElliott Hughes	Month_expansion["nov"]	= "November"
748*9a7741deSElliott Hughes	Month_expansion["dec"]	= "December"
749*9a7741deSElliott Hughes
750*9a7741deSElliott Hughes	Font_cmd_map["\\emph"]		= "EM"
751*9a7741deSElliott Hughes	Font_cmd_map["\\textbf"]	= "B"
752*9a7741deSElliott Hughes	Font_cmd_map["\\textit"]	= "I"
753*9a7741deSElliott Hughes	Font_cmd_map["\\textmd"]	= ""
754*9a7741deSElliott Hughes	Font_cmd_map["\\textrm"]	= ""
755*9a7741deSElliott Hughes	Font_cmd_map["\\textsc"]	= "toupper"
756*9a7741deSElliott Hughes	Font_cmd_map["\\textsl"]	= "I"
757*9a7741deSElliott Hughes	Font_cmd_map["\\texttt"]	= "t"
758*9a7741deSElliott Hughes	Font_cmd_map["\\textup"]	= ""
759*9a7741deSElliott Hughes
760*9a7741deSElliott Hughes	Font_decl_map["\\bf"]		= "B"
761*9a7741deSElliott Hughes	Font_decl_map["\\em"]		= "EM"
762*9a7741deSElliott Hughes	Font_decl_map["\\it"]		= "I"
763*9a7741deSElliott Hughes	Font_decl_map["\\rm"]		= ""
764*9a7741deSElliott Hughes	Font_decl_map["\\sc"]		= "toupper"
765*9a7741deSElliott Hughes	Font_decl_map["\\sf"]		= ""
766*9a7741deSElliott Hughes	Font_decl_map["\\tt"]		= "TT"
767*9a7741deSElliott Hughes	Font_decl_map["\\itshape"]	= "I"
768*9a7741deSElliott Hughes	Font_decl_map["\\upshape"]	= ""
769*9a7741deSElliott Hughes	Font_decl_map["\\slshape"]	= "I"
770*9a7741deSElliott Hughes	Font_decl_map["\\scshape"]	= "toupper"
771*9a7741deSElliott Hughes	Font_decl_map["\\mdseries"]	= ""
772*9a7741deSElliott Hughes	Font_decl_map["\\bfseries"]	= "B"
773*9a7741deSElliott Hughes	Font_decl_map["\\rmfamily"]	= ""
774*9a7741deSElliott Hughes	Font_decl_map["\\sffamily"]	= ""
775*9a7741deSElliott Hughes	Font_decl_map["\\ttfamily"]	= "TT"
776*9a7741deSElliott Hughes}
777*9a7741deSElliott Hughes
778*9a7741deSElliott Hughesfunction min(a,b)
779*9a7741deSElliott Hughes{
780*9a7741deSElliott Hughes	return (a < b) ? a : b
781*9a7741deSElliott Hughes}
782*9a7741deSElliott Hughes
783*9a7741deSElliott Hughes
784*9a7741deSElliott Hughesfunction prefix(level)
785*9a7741deSElliott Hughes{
786*9a7741deSElliott Hughes	# Return a prefix of up to 60 blanks
787*9a7741deSElliott Hughes
788*9a7741deSElliott Hughes	if (In_PRE)
789*9a7741deSElliott Hughes		return ("")
790*9a7741deSElliott Hughes	else
791*9a7741deSElliott Hughes		return (substr("                                                            ", \
792*9a7741deSElliott Hughes			1, INDENT * level))
793*9a7741deSElliott Hughes}
794*9a7741deSElliott Hughes
795*9a7741deSElliott Hughes
796*9a7741deSElliott Hughesfunction print_line(line)
797*9a7741deSElliott Hughes{
798*9a7741deSElliott Hughes	if (HTML)		# must buffer in memory so that we can accumulate TOC
799*9a7741deSElliott Hughes		Body[++BodyLines] = line
800*9a7741deSElliott Hughes	else
801*9a7741deSElliott Hughes		print line
802*9a7741deSElliott Hughes}
803*9a7741deSElliott Hughes
804*9a7741deSElliott Hughes
805*9a7741deSElliott Hughesfunction print_toc_line(author,title,pages, extra,leaders,n,t)
806*9a7741deSElliott Hughes{
807*9a7741deSElliott Hughes	# When we have a multiline title, the hypertext link goes only
808*9a7741deSElliott Hughes	# on the first line.  A multiline hypertext link looks awful
809*9a7741deSElliott Hughes	# because of long underlines under the leading indentation.
810*9a7741deSElliott Hughes
811*9a7741deSElliott Hughes	if (pages == "")	# then no leaders needed in title lines other than last one
812*9a7741deSElliott Hughes		t = sprintf("%31s   %s%s%s", author, Title_prefix, title, Title_suffix)
813*9a7741deSElliott Hughes	else					# last title line, with page number
814*9a7741deSElliott Hughes	{
815*9a7741deSElliott Hughes		n = html_length(title)		# potentially expensive
816*9a7741deSElliott Hughes		extra = n % 2			# extra space for aligned leader dots
817*9a7741deSElliott Hughes		if (n <= MAX_TITLE_CHARS) 	# then need leaders
818*9a7741deSElliott Hughes			leaders = substr(LEADERS, 1, MAX_TITLE_CHARS + MIN_LEADERS - extra - \
819*9a7741deSElliott Hughes				   min(MAX_TITLE_CHARS,n))
820*9a7741deSElliott Hughes		else				# title (almost) fills line, so no leaders
821*9a7741deSElliott Hughes			leaders = substr(MIN_LEADERS_SPACE,1, \
822*9a7741deSElliott Hughes					 (MAX_TITLE_CHARS + MIN_LEADERS - extra - n))
823*9a7741deSElliott Hughes		t = sprintf("%31s   %s%s%s%s%s %4s", \
824*9a7741deSElliott Hughes			    author, Title_prefix, title, Title_suffix, \
825*9a7741deSElliott Hughes			    (extra ? " " : ""), leaders, pages)
826*9a7741deSElliott Hughes	}
827*9a7741deSElliott Hughes
828*9a7741deSElliott Hughes	Title_prefix = ""	# forget any hypertext
829*9a7741deSElliott Hughes	Title_suffix = ""	# link material
830*9a7741deSElliott Hughes
831*9a7741deSElliott Hughes	# Efficency note: an earlier version accumulated the body in a
832*9a7741deSElliott Hughes	# single scalar like this: "Body = Body t".  Profiling revealed
833*9a7741deSElliott Hughes	# this statement as the major hot spot, and the change to array
834*9a7741deSElliott Hughes	# storage made the program more than twice as fast.  This
835*9a7741deSElliott Hughes	# suggests that awk might benefit from an optimization of
836*9a7741deSElliott Hughes	# "s = s t" that uses realloc() instead of malloc().
837*9a7741deSElliott Hughes	if (HTML)
838*9a7741deSElliott Hughes		Body[++BodyLines] = t
839*9a7741deSElliott Hughes	else
840*9a7741deSElliott Hughes		print t
841*9a7741deSElliott Hughes}
842*9a7741deSElliott Hughes
843*9a7741deSElliott Hughes
844*9a7741deSElliott Hughesfunction protect_SGML_characters(s)
845*9a7741deSElliott Hughes{
846*9a7741deSElliott Hughes    gsub(/&/,"\\&amp;",s)	# NB: this one MUST be first
847*9a7741deSElliott Hughes    gsub(/</,"\\&lt;",s)
848*9a7741deSElliott Hughes    gsub(/>/,"\\&gt;",s)
849*9a7741deSElliott Hughes    gsub(/\"/,"\\&quot;",s)
850*9a7741deSElliott Hughes    return (s)
851*9a7741deSElliott Hughes}
852*9a7741deSElliott Hughes
853*9a7741deSElliott Hughes
854*9a7741deSElliott Hughesfunction strip_braces(s, k)
855*9a7741deSElliott Hughes{	# strip non-backslashed braces from s and return the result
856*9a7741deSElliott Hughes
857*9a7741deSElliott Hughes	return (strip_char(strip_char(s,"{"),"}"))
858*9a7741deSElliott Hughes}
859*9a7741deSElliott Hughes
860*9a7741deSElliott Hughes
861*9a7741deSElliott Hughesfunction strip_char(s,c, k)
862*9a7741deSElliott Hughes{	# strip non-backslashed instances of c from s, and return the result
863*9a7741deSElliott Hughes	k = index(s,c)
864*9a7741deSElliott Hughes	if (k > 0)		# then found the character
865*9a7741deSElliott Hughes	{
866*9a7741deSElliott Hughes		if (substr(s,k-1,1) != "\\") # then not backslashed char
867*9a7741deSElliott Hughes			s = substr(s,1,k-1) strip_char(substr(s,k+1),c) # so remove it (recursively)
868*9a7741deSElliott Hughes		else		# preserve backslashed char
869*9a7741deSElliott Hughes			s = substr(s,1,k) strip_char(s,k+1,c)
870*9a7741deSElliott Hughes	}
871*9a7741deSElliott Hughes	return (s)
872*9a7741deSElliott Hughes}
873*9a7741deSElliott Hughes
874*9a7741deSElliott Hughes
875*9a7741deSElliott Hughesfunction strip_html(s)
876*9a7741deSElliott Hughes{
877*9a7741deSElliott Hughes	gsub(/<\/?[^>]*>/,"",s)
878*9a7741deSElliott Hughes	return (s)
879*9a7741deSElliott Hughes}
880*9a7741deSElliott Hughes
881*9a7741deSElliott Hughes
882*9a7741deSElliott Hughesfunction terminate()
883*9a7741deSElliott Hughes{
884*9a7741deSElliott Hughes	if (HTML)
885*9a7741deSElliott Hughes	{
886*9a7741deSElliott Hughes		html_end_pre()
887*9a7741deSElliott Hughes
888*9a7741deSElliott Hughes		HTML = 0	# NB: stop line buffering
889*9a7741deSElliott Hughes		html_header()
890*9a7741deSElliott Hughes		html_toc()
891*9a7741deSElliott Hughes		html_body()
892*9a7741deSElliott Hughes		html_trailer()
893*9a7741deSElliott Hughes	}
894*9a7741deSElliott Hughes}
895*9a7741deSElliott Hughes
896*9a7741deSElliott Hughes
897*9a7741deSElliott Hughesfunction TeX_to_HTML(s, k,n,parts)
898*9a7741deSElliott Hughes{
899*9a7741deSElliott Hughes	# First convert the four SGML reserved characters to SGML entities
900*9a7741deSElliott Hughes	if (HTML)
901*9a7741deSElliott Hughes	{
902*9a7741deSElliott Hughes	    gsub(/>/,	"\\&gt;",	s)
903*9a7741deSElliott Hughes	    gsub(/</,	"\\&lt;",	s)
904*9a7741deSElliott Hughes	    gsub(/"/,	"\\&quot;",	s)
905*9a7741deSElliott Hughes	}
906*9a7741deSElliott Hughes
907*9a7741deSElliott Hughes	gsub(/[$][$]/,"$$",s)	# change display math to triple dollars for split
908*9a7741deSElliott Hughes	n = split(s,parts,/[$]/)# split into non-math (odd) and math (even) parts
909*9a7741deSElliott Hughes
910*9a7741deSElliott Hughes	s = ""
911*9a7741deSElliott Hughes	for (k = 1; k <= n; ++k) # unbrace non-math part, leaving math mode intact
912*9a7741deSElliott Hughes		s = s ((k > 1) ? "$" : "") \
913*9a7741deSElliott Hughes			((k % 2) ? strip_braces(TeX_to_HTML_nonmath(parts[k])) : \
914*9a7741deSElliott Hughes			TeX_to_HTML_math(parts[k]))
915*9a7741deSElliott Hughes
916*9a7741deSElliott Hughes	gsub(/[$][$][$]/,"$$",s) # restore display math
917*9a7741deSElliott Hughes
918*9a7741deSElliott Hughes	return (s)
919*9a7741deSElliott Hughes}
920*9a7741deSElliott Hughes
921*9a7741deSElliott Hughes
922*9a7741deSElliott Hughesfunction TeX_to_HTML_math(s)
923*9a7741deSElliott Hughes{
924*9a7741deSElliott Hughes	# Mostly a dummy for now, but HTML 3 could support some math translation
925*9a7741deSElliott Hughes
926*9a7741deSElliott Hughes	gsub(/\\&/,"\\&amp;",s)	# reduce TeX ampersands to SGML entities
927*9a7741deSElliott Hughes
928*9a7741deSElliott Hughes	return (s)
929*9a7741deSElliott Hughes}
930*9a7741deSElliott Hughes
931*9a7741deSElliott Hughes
932*9a7741deSElliott Hughesfunction TeX_to_HTML_nonmath(s)
933*9a7741deSElliott Hughes{
934*9a7741deSElliott Hughes	if (index(s,"\\") > 0)			# important optimization
935*9a7741deSElliott Hughes	{
936*9a7741deSElliott Hughes		gsub(/\\slash +/,"/",s)		# replace TeX slashes with conventional ones
937*9a7741deSElliott Hughes		gsub(/ *\\emdash +/," --- ",s)	# replace BibNet emdashes with conventional ones
938*9a7741deSElliott Hughes		gsub(/\\%/,"%",s)		# reduce TeX percents to conventional ones
939*9a7741deSElliott Hughes		gsub(/\\[$]/,"$",s)		# reduce TeX dollars to conventional ones
940*9a7741deSElliott Hughes		gsub(/\\#/,"#",s)		# reduce TeX sharps to conventional ones
941*9a7741deSElliott Hughes
942*9a7741deSElliott Hughes		if (HTML)			# translate TeX markup to HTML
943*9a7741deSElliott Hughes		{
944*9a7741deSElliott Hughes			gsub(/\\&/,"\\&amp;",s)	# reduce TeX ampersands to SGML entities
945*9a7741deSElliott Hughes			s = html_accents(s)
946*9a7741deSElliott Hughes			s = html_fonts(s)
947*9a7741deSElliott Hughes		}
948*9a7741deSElliott Hughes		else				# plain ASCII text output: discard all TeX markup
949*9a7741deSElliott Hughes		{
950*9a7741deSElliott Hughes			gsub(/\\\&/, "\\&", s)	# reduce TeX ampersands to conventional ones
951*9a7741deSElliott Hughes
952*9a7741deSElliott Hughes			gsub(/\\[a-z][a-z] +/,"",s) # remove TeX font changes
953*9a7741deSElliott Hughes			gsub(/\\[^A-Za-z]/,"",s) # remove remaining TeX control symbols
954*9a7741deSElliott Hughes		}
955*9a7741deSElliott Hughes	}
956*9a7741deSElliott Hughes	return (s)
957*9a7741deSElliott Hughes}
958*9a7741deSElliott Hughes
959*9a7741deSElliott Hughes
960*9a7741deSElliott Hughesfunction trim(s)
961*9a7741deSElliott Hughes{
962*9a7741deSElliott Hughes    gsub(/^[ \t]+/,"",s)
963*9a7741deSElliott Hughes    gsub(/[ \t]+$/,"",s)
964*9a7741deSElliott Hughes    return (s)
965*9a7741deSElliott Hughes}
966*9a7741deSElliott Hughes
967*9a7741deSElliott Hughes
968*9a7741deSElliott Hughesfunction vol_no_month_year()
969*9a7741deSElliott Hughes{
970*9a7741deSElliott Hughes	return ("Volume " wrap(Volume)  ",  Number " wrap(Number) ", " wrap(Month) ", " wrap(Year))
971*9a7741deSElliott Hughes}
972*9a7741deSElliott Hughes
973*9a7741deSElliott Hughes
974*9a7741deSElliott Hughesfunction wrap(value)
975*9a7741deSElliott Hughes{
976*9a7741deSElliott Hughes	return (HTML ? ("<STRONG>" value "</STRONG>") : value)
977*9a7741deSElliott Hughes}
978