github.com/benhoyt/goawk@v1.8.1/testdata/gawk/funstack.awk (about)

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