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