diff options
Diffstat (limited to 'support/ltoh')
-rw-r--r-- | support/ltoh/README | 11 | ||||
-rw-r--r-- | support/ltoh/ltoh.pl | 1229 | ||||
-rw-r--r-- | support/ltoh/ltoh.specs | 101 | ||||
-rw-r--r-- | support/ltoh/readme.dvi | bin | 0 -> 36232 bytes | |||
-rw-r--r-- | support/ltoh/readme.html | 777 | ||||
-rw-r--r-- | support/ltoh/readme.pdf | bin | 0 -> 64342 bytes | |||
-rw-r--r-- | support/ltoh/readme.ps | 1027 | ||||
-rw-r--r-- | support/ltoh/readme.txt | 634 | ||||
-rw-r--r-- | support/ltoh/rq-ltoh.specs | 119 | ||||
-rw-r--r-- | support/ltoh/rq209.sty | 43 |
10 files changed, 3941 insertions, 0 deletions
diff --git a/support/ltoh/README b/support/ltoh/README new file mode 100644 index 0000000000..e96cf67eec --- /dev/null +++ b/support/ltoh/README @@ -0,0 +1,11 @@ +Please see the web page + http://www.best.com/~quong/ltoh.html +for the latest information, and release. + +If you got the official distribution (ltoh.zip or ltoh.tgz), +also see: + readme.html + readme.ps +or + readme.txt + diff --git a/support/ltoh/ltoh.pl b/support/ltoh/ltoh.pl new file mode 100644 index 0000000000..496f5425f1 --- /dev/null +++ b/support/ltoh/ltoh.pl @@ -0,0 +1,1229 @@ +#! /usr/bin/perl + +# Copyright (c) 1996, 1997 Russell Quong. +# +# In the following, the "author" refers to "Russell Quong." +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by Russell Quong. +# 3. All HTML generated by ltoh must retain a visible notice that it +# was generated by ltoh and contain a link to the ltoh web page +# +# Any or all of these provisions can be waived if you have specific, +# prior permission from the author. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL RUSSELL QUONG BE LIABLE FOR ANY SPECIAL, +# INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY +# THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# ltoh.pl = a LaTeX to HTML converter +# Russell Quong 1996, 1997 +# Version 97e. + +# enable readable "English names" for variables, like $MATCH or $PERL_VERSION +# instead of " punctuation names" for variables, like $& or $] +use English; + +$false = 0; +$true = 1; + +$author = "Russell W. Quong"; +$version = "Version 97e."; +$reldate = "Mar 1997"; +$status = "Experimental"; +$dirsep = "/"; # directory separator character + +$qval{"today"} = strip_hms_and_day( scalar(localtime()) ); +$qval{"title"} = ""; +$qval{"author"} = "Unknown document author"; +$qval{"email"} = "Unknown email"; +$qval{"url"} = "Unknown Web URL"; +$qval{"keep_comments"} = 0; + +$warnlevel = 3; + +sub bad_command { + my($err_msg, $descrip) = @_; + return "<font color=maroon><em> $err_msg </em> $descrip </font>"; +} + + +# lookup(varname) ==> get the value of variable VARNAME. +sub lookup { + my($idx) = @_; + if ( ! defined $qval{$idx} ) { + return "$idx undefined"; + } else { + return $qval{$idx}; + } +} + +sub print_html_header { + my($filename) = @_; + print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">', "\n"; + print "<HTML>\n"; + if ($qval{"title"} eq "") { + $qval{"title"} = "$filename : [LaTeX --> HTML]"; + } + print "<HEAD>\n<TITLE>\n", $qval{title} , "\n</TITLE>\n</HEAD>\n"; + print "<BODY>\n"; +} + +sub print_html_trailer { + my($filename) = @_; + # need to declare ctime separately from next line, ugh. (scalar vs. array) + print "<HR>\n"; + print "<font size=+0><EM>[Converted LaTeX --> HTML by"; + print ' <a href="http://www.best.com/~quong/ltoh.html">ltoh</a>]'; + print "</EM></font><br>\n"; + + print "<ADDRESS>\n"; + if ($qval{"url"} =~ /Unknown/) { + if (! ($qval{"author"} =~ /Unknown/)) { + print "$qval{author}\n" ; + } + } else { + print "<A href=\"$qval{url}\">$qval{author}</A>\n"; + } + if (! ($qval{"email"} =~ /Unknown/)) { + print "(<A href=\"mailto:$qval{email}\"><SAMP>$qval{email}"; + print "</SAMP></A>)\n"; + } + + my($ctime); + $ctime = localtime; + $ctime = strip_hms_and_day($ctime); + print "Last modified: <font color=maroon><samp>$ctime</samp></font>\n"; + + my($mtime) = get_file_mtime($filename); + if ($mtime ne $ctime) { + print "(LaTeX doc modified: <font color=maroon><samp>"; + print $mtime; + print "</samp></font>)<br>\n"; + } + print "</ADDRESS>\n"; + print "</BODY>\n</HTML>\n"; +} + +sub strip_hms_and_day { + my($str_time) = @_; + + # The next two lines strip off + # the hours:min:secs and the leading day of the week, giving + # Jul 29 1996 + $str_time =~ s/^[A-Z][a-z][a-z][ \t]*//; + $str_time =~ s/\d+:\d+:\d+[ \t]*([A-Z][A-Z]T[ \t]*)?//; + return $str_time; +} + +# +# return the time (as a string) that the file XXX was last modified. +# called via: +# $string = get_file_mtime (XXX); +# +sub get_file_mtime { + my($filename) = @_; + my($str_time) = '<Unable to determine time>'; # default value + + my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, + $atime,$mtime,$ctime,$blksize,$blocks) + = stat($filename); + if ($dev != null) { + $str_time = localtime($mtime); + # We now have string like: + # Mon Jul 29 19:53:49 PDT 1996 + $str_time = strip_hms_and_day($str_time); + + warning(9, "File $filename last modified on $str_time"); + } + return $str_time; +} + +sub logmessage { + my($prefix, @params) = @_; + my($level) = 0; + if (@params > 1) { + if ($params[0] =~ /\d/) { + $level = shift(@params); + } else { + print ("No level given: @_"); + } + } + if ($level <= $warnlevel) { + print "$prefix :: @params\n"; + } else { +# print "level $level > warnlevel $warnleve\n"; + } +} + +sub errmsg { + logmessage(" * Error: ", @_); +} + +sub warning { + logmessage(" + Warning: ", @_); +} + +sub fyi { + logmessage(" - fyi: ", @_); +} + +# +# Try to figure out where the perl script is actually located. +# (1) We can follow symbolic links to ABSOLUTE PATHS correctly, +# (2) But we can't handle relative symbolic links to another directory, +# as we need to keep track of where the link is relative to. +# Case (1) handles the common case of a link: xyz --> /whereever/bin/ltoh +# Also, we can handle the last link referring to a file in the same dir. + +sub get_scriptdir { + fyi("PROGRAM_NAME = $PROGRAM_NAME"); + my($scriptfile) = $PROGRAM_NAME; # maybe a link. We trace it down. + my($scriptdir, $fulldir) = ("." , ""); + + while (-l $scriptfile) { + fyi(9, "$scriptfile is link to -->"); + if ($scriptfile =~ /(.*) $dirsep ( [^$dirsep]+ )/x ) { + $scriptdir = $1; +# if ($scriptdir =~ /^$dirsep/) { +# $fulldir = $scriptdir; +# } else { +# $fulldir .= $scriptdir; +# } +# fyi(9, "scriptdir = $scriptdir"); +# fyi(9, "fulldir = $fulldir"); + } + $scriptfile = readlink $scriptfile; + fyi(9, " $scriptfile."); + fyi(7, "scriptdir = $scriptdir"); + } + return $scriptdir; +} + + # + # handle all the arguments, in the @ARGV array. + # +sub main { + fyi("PROGRAM_VERSION = $version"); + fyi(" by $author. 1996, 1997."); + + my($nextline, $f); + my($nspecfiles) = 0; + my($scriptdir) = get_scriptdir(); # attempt to trace down a sym link. + + # list of spec files + my(@specfiles) = ( + "$scriptdir$dirsep" . "ltoh.specs" , + "~$dirsep.ltoh.specs" , + ".$dirsep.ltoh.specs" + ); + + foreach $f (@specfiles) { + $nspecfiles += read_specfile($f); + } + if ($nspecfiles == 0) { + $nspecfiles += read_specfile("/usr/local/bin/ltoh.specs"); + } + if ($nspecfiles == 0) { + $nspecfiles += read_specfile("/usr/bin/ltoh.specs"); + } + if ($nspecfiles == 0) { + warning("Tried to read spec files: @specfiles"); + errmsg("No specification files found. Bye-bye."); + exit(1); + } + + if (@ARGV == 0) { + handle_file('-'); + } + foreach $i (@ARGV) { + my($texfile) = $i; + if ($i =~ /^(.+)\.([ltex]+)$/ ) { + warning(7, "filebase = $1, suffix = $2, $input file = $texfile"); + } else { + $texfile = $i . ".tex"; + } + if (! -r $texfile) { + print "Cannot read file: $texfile\n"; + return -1; + } + handle_file($texfile); + } +} + + # + # process a specific file. Called via: handle_file($filename); + # +sub handle_file { + my($texfilename) = @_; + my($INFILE) = $texfilename; + if ($texfilename eq '-') { + $INFILE = STDIN; + } else { + open($INFILE, $texfilename); + } + $qval{"title"} = "Unnamed Web page"; + fyi(5, "+ Reading LaTeX input ... handle_file($texfilename)"); + @orig = <$INFILE>; + print_arr('Orig $lineno:', \@orig) if ($warnlevel >= 8); + do_comment_verbatim(\@orig); + print_arr('Verb $lineno:', \@orig) if ($warnlevel >= 8); + do_tables(\@orig); + print_arr('Tabl $lineno:', \@orig) if ($warnlevel >= 8); + do_begin_end(\@orig); + print_arr('BegE $lineno:', \@orig) if ($warnlevel >= 8); + do_tex_comms(\@orig); + print_arr('Comm $lineno:', \@orig) if ($warnlevel >= 8); + mark_delims(\@orig); + print_arr('Mark $lineno:\n', \@delim_lines) if ($warnlevel >= 8); + do_simple_latex_defs(\@delim_lines); + print_arr('{} $lineno:\n', \@delim_lines) if ($warnlevel >= 8); + do_complicated_latex_defs(\@delim_lines); + print_arr('{N} $lineno:\n', \@delim_lines) if ($warnlevel >= 8); + my($i); + final_cleanup(\@delim_lines); + print_arr('[<$lineno>]', \@delim_lines) if ($warnlevel >= 8); + print_arr("", \@delim_lines) if ($warnlevel >= 8); + print_html_file($texfilename); +} + +# generate the HTML file. Pass in the name of the .tex file +# print_html_file( "filename.tex" ); +# +sub print_html_file { + my($texfile) = @_; + my($base, $suffix) = ($texfile, ""); + my($outfile) = $qval{"htmlfile_spec"}; + fyi(8,"texfile = $texfile, outfile = $outfile"); + + if ($texfile =~ /^(.+)\.([^.]*)$/ ) { + $base = $1; + $suffix = $2; + } + fyi(8, "base = $base, suffix = $suffix, $input file = $texfile"); + + $outfile =~ s/\$BASE/$base/e; + $outfile =~ s/\$SUFFIX/$suffix/e; + fyi(3, "+ texbase = $base ; HTML output file => $outfile ."); + if (-e $outfile) { + # + # comment out the following warning if desired. + # +# print "Warn, file $outfile already exists\n"; + } + open(OUTF , ">"."$outfile"); + + # + # print to OUTF by default, by selecting it. + # + select OUTF; + + print_html_header($texfile); + # + # print the generated HTML. + # @delim_lines is the final HTML after processing + # + print_arr("", \@delim_lines); + print_html_trailer($texfile); + + select STDOUT; +} + +$re_fields = 4; + +# +# DO NOT EDIT THEM MANUALLY. +# associative arrays indexed by the LaTeX command +# containing the corresponding the HTML +# E.g, we might have something like: +# %html_start{'textbf'} = '<strong>'; +# %html_end{'textbf'} = '</strong>'; +# The values are read in from a specification file. +# DO NOT EDIT THEM MANUALLY. + +sub do_spec_pseudo_op { + my($line) = @_; + if ($line =~ /^=\*\*\*=[ \t]+([^ \t\n]*)/ ) { + chomp($line); + my($op) = $1; + fyi(7, "Psuedo-op $op: ($line)"); + if ($line =~ /endfile/) { + return $op; + } + if ($line =~ /=[ \t]*echo./) { + print "$POSTMATCH\n"; + } + if ($line =~ /=[ \t]*exit/) { + fyi(6, "Exit request, line $INPUT_LINE_NUMBER, $spec_fname\n"); + exit(1); + } + if ($line =~ /=[ \t]*warnlevel\s*:=\s*(\d+)/i) { + $warnlevel = $1; + } + return "pseudo-op"; + } elsif ($line =~ /^([a-zA-Z_][\w]*)\s*:=(.*)$/ ) { + my($name, $val, $oldval) = ($1, $2, ""); + $val =~ s/^[\s]*["]?//; + $val =~ s/["]?[\s]*$//; + $oldval = $qval{$name}; + $qval{$name} = $val; + fyi(6, "set var: $name := ($val), oldval = $oldval"); + return "set-var"; + } else { + return ""; + } +} + +# Example +# For the specification +# ':b/e :\begin{rqitemize}(\{[^\}]*\})*:<ul>:</>:' +# We get: +# $html_start{'\begin{rqitemize}'} = '<ul>'; +# $html_end{'\begin{rqitemize}'} = '</ul>'; +# $comm_regex{'\begin{rqitemize}'} = '\begin{rqitemize}(\{[^\}]*\})*'; +# $comm_attr{'\begin{rqitemize}'} = 'b/e'; +# +sub read_specfile { + my($globbed_name) = @_; + my($spec_fname) = glob($globbed_name); + + fyi(7, "globbed_name = $globbed_name, spec_fname = $spec_fname"); + + if (! -r $spec_fname) { + warning(7, "Unable to read ltoh spec file $spec_fname."); + return 0; + } + open(SPECFILE, $spec_fname); + + my($line, $status); + my($lineno) = 0; + while ($line = <SPECFILE>) { + $lineno++; + # skip comments + if ($line =~ /^[ \t]*[#;]/ || $line =~ /^[ \t]*$/) { + fyi(9, "Skipping comment: $line"); + next; + } + $status = handle_specification($line); + if ($status eq "endfile") { + last; + } + } + fyi(3, "+ Read spec file ($spec_fname)."); + if ($lineno == 0) { + warning(3, "+ Empty spec file ($spec_fname)."); + } + return 1; +} + +sub handle_specification { + my($line) = @_; + + my(@arr); + my($junk, $from, $to, $rest, $status); + if ( ($status = do_spec_pseudo_op($line)) ne "") { + return $status; + } + $splitter = substr($line, 0, 1); + if ($splitter eq '[ \t]') { + $splitter = "[ \t]+"; + } else { + $splitter = "[" . quotemeta("$splitter") . "]"; + } + fyi(8, "splitter = $splitter"); + @arr = split($splitter, $line, $re_fields+3); + if (@arr < $re_fields+2) { + warning("Malformed spec, line $lineno, too few fields" . "$line"); + next; + } elsif (@arr > $re_fields+2) { + warning("Malformed spec, line $lineno, too many fields" . "$line"); + next; + } else { + # everything is OK. do nothing. + } + ($raw_spec, $from, $to_start, $to_end) = @arr[1 .. $re_fields ]; + + # (a) if $from is "\begin{xyz}MORE-STUFF", strip off MORE-STUFF + # (b) if $from is "\xyz{MORE-STUFF}", strip off MORE-STUFF + # must check if $from looks like "\begin{...}" as must not apply (b) + # to a \begin{...} construct + if ($from =~ /\\begin\{.+\}/ ) { + if ($from =~ s/(\\begin\{[^\}]+\})(.+)/$1/ ) { + fyi(7, "Stripped begin\{...\} args: $arr[2] --> $from"); + } + } elsif ($from =~ /(\\[A-Za-z_]+)([^A-Za-z_].*)/ ) { + $from =~ s/(\\[A-Za-z_]+)([^A-Za-z_].*)/$1/; + fyi(7, "Stripped args: $arr[2] --> $from"); + } + + # if $to_end is "...</>...", + # generate the corresponding closing tags, automatically. Cool. + # Have to reverse the order, hence the while loop. + # + my($scratch) = ""; + if ($to_end =~ '</>') { + $junk = $to_start; + $scratch = ""; + while ($junk =~ s:<([^ \t>]+)([^>]*)>:\@$1\@:o ) { + $scratch = "</$1>" . $scratch; + } + $to_end =~ s:</>:$scratch:; + fyi(7, "Gen to_end: to_start = $to_start, to_end = $to_end"); + } + + fyi(7, "from = $from, to_start = $to_start, to_end = $to_end"); + fyi(8, "raw_spec = $raw_spec"); + + $comm_regex{$from} = $arr[2]; + $comm_attr{$from} = $raw_spec; + $html_start{$from} = $to_start; + $html_end{$from} = $to_end; + + if ($raw_spec =~ /re/i && $to_end ne "") { + warning(5, "Unused specification: $to_end"); + } +} + + + + # Simple protection of special character sequences on a line + # (1) group backslashes by pairs, + # (2) '@' to @AT@, and + # (3) protect \{ and \}. +sub escape_line { + my($line) = @_; + $line =~ s:\@:\@AT\@:g; + + # handle latex math characters/macros. Strip off math mode $...$ for now + $line =~ s:\$ ([<>]) \$:\1:ogx; + $line =~ s:\$ (&[gl]t;) \$:\1:ogx; + $line =~ s:\$ (\\[a-zA-Z]+) \$:\1:ogx; + + # grab pairs of backslash characters and escape them. + # as we need to distinguish between + # \{ ==> preserve '{' (escape it) + # \\{ ==> preserve '\' (escape it), but process '{' normally. + # \\\{ ==> preserve both '\' and '{' alone, follows from above + $line =~ s:\\\\:\@BS\@\@BS\@:og; + $line =~ s:\\\{:\@<<\@:og; + $line =~ s:\\\}:\@>>\@:og; + + # unescape pairs of backslack characters. + $line =~ s:\@BS\@\@BS\@:\\\\:og; + +# not needed, yet. (We run this function early in the processing, +# and this change unnecessarily mucks things up at this early stage). +# escape newlines +# $line =~ s:\@AT\@NL\@AT\@:\@NL\@:og; + + + return $line; +} + + # + # print_arr(prefix_string, reference_to_an_array); + # In prefix_string the string '$lineno' is converted to the array index. + # If prefix_string ends with a '\n' (newline), append a newline to the line. + # Ex: + # @lines = <>; # read all input into an array + # print_arr('$lineno:', \@lines); # pass in a reference to the array +sub print_arr { + my($prefix, $arr) = @_; + my($i); + my($ndigits) = int( (log($#{$arr}) / exp(1) + .999) ) ; + my($newline) = ""; + if ($prefix =~ s/(\\n|\n)$//o) { + $newline = "\n"; + } + foreach $i (0 .. $#{$arr}) { + $s = $prefix; + if ($prefix =~ /\$lineno/o) { + $s =~ s/\$lineno/sprintf("%$ndigits" . "d", $i)/ge; + } + print "$s$arr->[$i]$newline"; + } +} + +$orig_inh = ""; + + # + # I've hard-wired the following "early actions" + # 1) handle \begin{verbatim} for now. + # 2) You can set HTML/Perl variables via lines that look like: + # %-ltoh- pseudo-op-line + # %-tex2html- pseudo-op-line ## backward compatibility for me [RQ] + # + # 2) I've hard coded a simplistic table hander too. Needs updating. + # It handles \multicolumn{ncols}{.}{contents} quite crudely + # It handles \multirow{nrows}{.}{contents} quite crudely + # NOT any more, see +sub do_comment_verbatim { + my($arr) = @_; + my($arrlen) = scalar(@$arr); + vec($orig_inh, $arrlen-1, 0) = 0; # pre-extend + my($inh) = $false; + for ($i=0; $i < $arrlen; $i++) { + vec($orig_inh, $i, 1) = $inh; + my($line) = $arr->[$i]; + + if ($line =~ /^[%]+-tex2html-\s*(.*)/ ) { + warning(3, "Use of -tex2html- is deprecated. Change to -ltoh-"); + handle_specification($1); + } elsif ($line =~ /^[%]+-ltoh-\s*(.*)/ ) { + fyi(6, "Processing psuedo-op in LaTeX source ($1)"); + handle_specification($1); + } + # preserve special chars in html, always + $line =~ s/\\&/&/xg; + $line =~ s/ < /</xg; + $line =~ s/ > />/xg; + if ($line =~ s:\\begin{verbatim}:<pre>: ) { + vec($orig_inh, $i, 1) = $true; # inhibit further processing + $inh = $true; + } elsif ($line =~ s:\\end{verbatim}:</pre>: ) { + vec($orig_inh, $i, 1) = $true; # inhibit further processing + $inh = $false; # allow processing on next line + } elsif ($inh == $false && $line =~ s:^([ \t]*%.*):<!-- $1 -->: ) { + if (! lookup("keep_comments") ) { + $line = ""; + } + vec($orig_inh, $i, 1) = $true; # inhibit further processing + } elsif ($inh == $false && $line =~ /^\\end{document}/ ) { + $#$arr = $i; + fyi(8, "Truncating down to $i lines"); + last; + } + $arr->[$i] = $line; + } +} + +# handle nested braces/parens/brackets. +# convert { ==> {:level: level starts at 0 +# +# E.g. a{b{c}d{e{f}}g} ==> a{:0:b{:1:c:1}d{:1:e{:2:f:2:}:1:}g:0:} +# +sub mark_braces_one_line { + my($ldelim, $rdelim, $line) = @_; + my($newline, $level) = ("", 0); + my($lookfor) = ($ldelim eq $rdelim) ? "[$ldelim]" : "[$ldelim$rdelim]"; + while ( $line =~ /(.*[^\\])($lookfor)(.*)/) { + my($prev, $del, $after) = ($1, $2, $3); + my($repl); + if ($del eq $ldelim) { + $repl = "$del:$level:"; + $level++; + } elsif ($del eq $rdelim) { + $repl = ":$level:$del"; + $level--; + } + $newline .= "$prev$repl"; + $line = $after; + } + return $newline; +} + +# handle nested braces/parens/brackets. +# convert "{" ==> " {:level " where level starts at 0 +# +# E.g. a{b{c}d{e{f}}g}h ==> a {:0 b {:1 c 1:} d {:1 e {:2 f 2:} 1:} g 0:} h +# +sub mark_braces_one_line { + my($ldelim, $rdelim, $origline) = @_; + my($newline, $level, $line) = ("", 0, $origline); + my($lookfor) = ($ldelim eq $rdelim) ? "[$ldelim]" : "[$ldelim$rdelim]"; + my($prev, $del, $after); # need after to survive the loop. + + $line =~ s/\@/ \@AT\@_/g; + $line =~ s/\\\\/ \@2BS\@_/g; + my($qldel) = quotemeta($ldelim); + $line =~ s/\\$qldel/ \@L\@_/g; + my($qrdel) = quotemeta($rdelim); + $line =~ s/\\$qrdel/ \@R\@_/g; + + # need ".../s" in the following while() to preserve newlines. Ugh. + while ( $line =~ /(.*?)($lookfor)(.*)/s) { + ($prev, $del, $after) = ($1, $2, $3); + fyi(9,"mark_braces_one_line:prev=($prev),del=($del),after=($after)\n"); + my($repl); + if ($del eq $ldelim) { + $repl = " $del:$level "; + $level++; + } elsif ($del eq $rdelim) { + $level--; + $repl = " $level:$del "; + } + $newline .= "$prev$repl"; + $line = $after; + } + $newline .= $after; + + $newline =~ s/ \@R\@_/\\$qrdel/g; + $newline =~ s/ \@L\@_/\\$qldel/g; + $newline =~ s/ \@2BS\@_/\\\\/g; + $newline =~ s/ \@AT\@_/\@/g; + return $newline; +} + +$talign{"l"} = "left"; +$talign{"r"} = "right"; +$talign{"c"} = "center"; +$talign{"p"} = "left"; +$talign{"X"} = "left"; + +sub do_tables { + my($arr) = @_; + my($arrlen) = scalar(@$arr); + my($tlev, $endrow, $colnum) = (0, undef, 0); + my(@cols) = (); + for ($i=0; $i < $arrlen; $i++) { + my($origline) = $arr->[$i]; + my($line) = $origline; # + fyi(9, "Tables orig-line $i: $origline"); + if ($origline =~ /\\begin\{[A-Za-z]*tabular[A-Za-z]*\}/) { + $line =~ s/(\\\\)? \s* \\[ch]line.*//x; + $line = mark_braces_one_line("{", "}", $line); + fyi(9, "Tables delim-line $i: $line"); + $line =~ s/ \{:1 .*? 1:\} //g; # remove nested brace stuff + $line =~ s/ \{:0 /\{/g; + $line =~ s/ 0:\} /\}/g; + fyi(9, "Tables squashed-line $i: $line"); + my(@fragments) = split(/[{}]+\s*/,$line); + my($aligns) = $fragments[$#fragments]; + my($tabletag); + if ( $aligns =~ /[|]/) { + $tabletag = "<table border>"; + } else { + $tabletag = "<table>"; + } + while ( $aligns =~ /([lcrpX])(.*)/s ) { + my($lcr) = $1; + my($rest) = $2; + fyi(9, "col-align lcr = $lcr, rest = $rest"); + $aligns = $rest; + push (@cols, $talign{$lcr}); + } + $tlev ++; + $endrow = 1; + $colnum = 0; + $line =~ s/\\begin\{tabular[A-Za-z]*\}\{.*\}/$tabletag/; + fyi(9, "line =-> $line"); + fyi(7, "Table with $#cols+1 columns. Aligns = @cols"); + } elsif ($line =~ s:\\end{tabular[A-Za-z]*}:</table>: ) { + $tlev --; + @cols = (); + } elsif ($tlev > 0) { + if ($endrow) { + $line = "<TR> <TD> $line"; + $endrow = 0; + } + $line =~ s:\& (?![ampltg]+;):</TD> <TD>:gx; + + # "&" ==> "</TD><TD>", but skip ">" "<" and "&". + $line =~ s:\& (?![ampltg]+;):</TD> <TD>:gx; + + # convert \multicolumn --> \mc + if ( $line =~ s:\\multicolumn{:\\mc\{:xg ) { + fyi(9, "mc line: $line"); + } + + # add individual column alignments. + while ( + $line =~ m/(.*?) (<TD>) (\s* \\mc\{\d+\}\{.+?\}\{)? (.*)/sx ) { + my($before, $after) = ($1, $4); + fyi(9, "cols[colnum=$colnum] = $cols[$colnum]"); + my($mcspec) = $3; + fyi(9, "mc: before=($before),mcspec=$mcspec,after=($after)"); + + if ($mcspec eq "") { + if ($colnum > $#cols) { + warning("Too many columns in table, line $i:\n + ($origline)"); + $line = "$before<TD align=left" . ">" . $after; + } else { + $line = "$before<TD align=$cols[$colnum]>" . $after; + } + $colnum++; + } else { + if ($mcspec =~ m:\\mc \{(\d+)\} \{([^}]+)\}:x ) { + my($colspan) = $1; + $colnum += $colspan; + $2 =~ / ([lcrpX]) /x; + $line = "$before<TD align=$talign{$1} colspan=$colspan>{" . $after; + } + } + } + # strip off trailing \\ and/or \hline. Each might be on sep line. + if ( $line =~ s:\\\\:</TD></TR>:xg ) { + $endrow = 1; + $colnum = 0; + } + $line =~ s/\s* \\hline//g; + $line =~ s/\\cline\{[0-9-]+\}//; + } + $arr->[$i] = $line; + } +} + +$re_tex_arg_0 = "(\[[^\]*\]|{[^}]*})*"; # no nesting +$re_tex_arg_1 = "({(([^{}]*{[^{}]*}[^{}]*)*)})*"; # nesting up to level 1. + +sub do_begin_end { + my($arr) = @_; + my($arrlen) = scalar(@$arr); + my($i, $level, $inh); + my($comm, $commregex, $fromx, $tox, $latexcomm); + for ($i=0; $i < $arrlen; $i++) { + if ( vec($orig_inh, $i, 1) > 0) { # skip if processing inhibited + next; + } + $line = $arr->[$i]; + $line = escape_line($line); + if ( $line =~ m/\\((begin|end)\{[a-zA-Z_]+\})/ ) { + # Example: + # $latexcomm = \begin{rqitemize}[12pt]{article} + # $comm = \begin{rqitemize} + # $fromx = \begin{rqitemize} + # $tox = <ul> + # + $latexcomm = $comm = $MATCH; + $comm =~ s/end/begin/; # convert \end{comm} to \begin{comm} + if ( defined $html_start{$comm} ) { + if ($latexcomm =~ /^\\end/) { + $fromx = $latexcomm; + $tox = $html_end{$comm}; + $commregex = $latexcomm; + } else { + $fromx = $comm_regex{$comm}; + $tox = $html_start{$comm}; + $commregex = $comm_regex{$comm}; + +# Flag an attempt to allow any \begin{xxx} to take further args, as +# error, as \begin{center} should not take any further args +# + if ($commregex eq $comm) { + $commregex .= $re_tex_arg_0; + fyi(7, " B/E Spruce: $comm --> $commregex"); + } + } + $commregex =~ s/^\\/\\\\/g; + fyi(7, " B/E Apply: $commregex ==> $tox, on: ($line)"); + $line =~ s/$commregex/$tox/; + } else { + warning(6, "UNDEFINED COMMAND: $comm, ignoring."); + $html_start{$comm} = ""; + $html_end{$comm} = ""; + } + } + $arr->[$i] = $line; + } +} + +# +# handle straight-forward substitutions: +# \xxx ---> yyy +# +sub do_tex_comms { + my($arr) = @_; + my($arrlen) = scalar(@$arr); + my($i, $comm, $comm_re, $fromx, $tox); + for ($i=0; $i < $arrlen; $i++) { + if ( vec($orig_inh, $i, 1) > 0) { # skip if processing inhibited + next; + } + $line = $arr->[$i]; + + # Find the latex command \xxx + # We mark each command, incase there are multiple commands on a line. + # First convert all \xxx --> @BS@xxx, + # Next, one-by-one convert @BS@xxx --> \xxx and process it. + # Thus, we are left with the original \xxx (not breaking old code). + # 9/16/96. + # + $line =~ s/\\([A-Za-z]+)/\@BS\@$1/g; + while ( $line =~ s/\@BS\@([A-Za-z]+)/\\$1/ ) { + $comm = '\\' . $1; + if (defined $html_start{$comm} && ($comm_attr{$comm} =~ /comm/)) { + $tox = $html_start{$comm}; + # might have: + # $comm = '\documentclass' + # $comm_re = '\documentclass[^ \t]+' + # apply $comm_re --> $tox + # + $comm_re = $comm_regex{$comm}; + $comm_re =~ s/^\\/\\\\/g; # escape the darn backslashes + warning(7, " TeXComm Apply: $comm_re ==> $tox on: ($line)"); + $line =~ s/$comm_re/$tox/g; + my($a, $b, $c, $d, $e) = ($1, $2, $3, $4, $5); + $line =~ s/\$1/$a/g; + $line =~ s/\$2/$b/g; + $line =~ s/\$3/$c/g; + $line =~ s/\$4/$d/g; + $line =~ s/\$5/$e/g; + } + if ( ! defined $html_start{$comm} ) { + warning(3, " Unknown \\comm: $comm, on: ($line)"); + } + } + + # + # Hardwired. \today --> current date. + # + my($today) = $qval{"today"}; + $line =~ s/\\today/$today/g; + + if ($line ne $arr->[$i]) { + warning(8, "regex: $arr->[$i] ==> $line"); + } + $arr->[$i] = $line; + } +} + +# dstack = delimiter stack +# dsp = delimiter stack pointer +$dstack[40] = ( "" ); +$dsp = 0; +$dcount = 1; # we reserve dcount=0 as an error. +$argspan[100] = undef; # argspan[i] = range of lines between brace i +$lstack[40] = ( "" ); # last id at this depth (upto depth 40). +$llinestack[40] = ( "" ); # last line containing id at this depth + + # + # the following apply only to complex commands (those processing their arg). + # +$commstack[40] = ( "" ); # the command to +$argsofar[40] = ( "" ); # number of args seen at level i so-far +$argwant[40] = ( "" ); # number of args wanted at level i +$arglist[40][20] = ( "" ); # the actual args for the level i command + +$argrem_stack[40] = ( "" ); # num of args remaining at this depth. +$nextarg[100] = undef; # nextarg[i] = id of next arg at same level + + # + # label all { and } with id's. + # Split strings via braces namely up after '{' and before '}' + # + # Also link up arguments for "complicated" latex commands, which take + # arguments. We must defer processing of these commands + # until we have seen the closing brace for the last argument, + # in case the arguments (i) undergo processing and (ii) are nested. Ugh. + # +sub mark_delims { + my($arr) = @_; + my($arrlen) = scalar(@$arr); + my($i, $j, $id, $level, $line, $frag, $inh); + $#delim_lines = $arrlen; # pre extend array delim_lines + $ndelim_lines = 0; + for ($i=0; $i < $arrlen; $i++) { + $inh = vec($orig_inh, $i, 1); + $line = $arr->[$i]; + # + # Also, handle $line == "", as subsequent code would mishandle it. + # (The split yields zero fragments, and the line is not passed on). + if ($inh > 0 || $line eq "") { + warning(8, "AFTER $ndelim_lines: $line\n"); + vec($delim_inh, $ndelim_lines, 1) = $inh; + $delim_lines[$ndelim_lines] = $line; + $ndelim_lines ++; + next; + } + warning(8, "mark_delims($line)"); + + my($splitstr) = ' @x@ '; + $line =~ s/\\[a-zA-Z_]+\{/$splitstr$MATCH/g; + $line =~ s/{/\{$splitstr/g; + $line =~ s/\}/$splitstr\}/g; + my(@fragments) = split(/$splitstr/,$line); + for ($j=0; $j < scalar(@fragments); $j++) { + $frag = $fragments[$j]; + warning(9, "Frag $j: $frag"); + if ( $frag =~ /^\}/ ) { + $dsp --; + if ($dsp < 0 || ! defined($dstack[$dsp]) ) { + my($lineno) = "Line: $INPUT_LINE_NUMBER"; + warning( + "$lineno, IMBALANCED BRACES: Too many closing braces"); + $id = -1; + } + $id = $dstack[$dsp]; + $dstack[$dsp] = undef; + $lstack[$dsp] = $id; + $lstack[$dsp+1] = undef; + $llinestack[$dsp] = $ndelim_lines; + + my($tmp) = $ndelim_lines - 1; + $argspan{$id} .= "$tmp"; + warning(7, " mark: argspan{$id} = $argspan{$id}"); + + $x = ":$id:\]"; + $frag =~ s/^\}/$x/; + } + if ( $frag =~ /\{$/ ) { + $id = $dstack[$dsp] = $dcount; + my($lastid) = $lstack[$dsp]; + # + # link args only if we find things like: xxx}{yyy + # Whoops, no, as a line break may split the }{ pair + # In either case the prev arg must be on the prev line. + $nextarg[$lastid] = undef; + if ($lastid != undef && $llinestack[$dsp] >= $ndelim_lines-1) { + if ($lastid <= 0 || $lastid > $dcount) { + warning("ERROR linking id's. Contact author."); + } + $nextarg[$lastid] = $id; + warning(7, " mark: nextarg[$lastid] = $nextarg[$lastid]"); + warning(8, " mark: id2comm{$lastid} = $id2comm{$lastid}"); + } + $lstack[$dsp] = $id; + + $dsp ++; + $dcount ++; + + if ( $frag =~ /(\\[\w]+)\{$/) { + warning(8, "mark: id2comm{$id} = $1"); + $id2comm{$id} = $1; + } else { + $id2comm{$id} = "_:NULL_COMMAND:_"; + } + my($tmp) = $ndelim_lines + 1; + $argspan{$id} = "$tmp:"; + + $x = "\[:$id:"; + $frag =~ s/\{$/$x/; + } + $frag =~ s/\n/\@NL\@/g; + warning(8, "END-MARK $ndelim_lines: $frag"); + + $delim_lines[$ndelim_lines] = $frag; + vec($delim_inh, $ndelim_lines, 1) = $inh; + $ndelim_lines ++; + } + } +} + + # + # handle "simple" latex commands not dependent on the data, namely: + # \command{ XXX } ===> <html_start_sequence> XXX <html_end_sequence> + # In particular, the conversion does not depend on XXX. + # Of course, we allow arbitrary nesting of braces in XXX, + # which was the hard part of all this. + # At this point, all braces have been munged and tagged with an unique ID. + # +sub do_simple_latex_defs { + my($arr) = @_; + my($arrlen) = scalar(@$arr); + my($comm, $fromx, $tox, $id, $inh, $i, $j, $k, $l, $nargs, $argidx); + for ($i=0; $i < $arrlen; $i++) { + $inh = vec($delim_inh, $i, 1); + $line = $arr->[$i]; + if ($inh > 0) { + next; + } + warning(8, "do_simple_brace_comms($line)"); + + if ($line =~ /\[:([0-9]+):/) { + $id = $1; + $comm = $id2comm{$id}; + warning(8, " id2comm{$id} is $id2comm{$id}"); + if ($comm ne "_:NULL_COMMAND:_") { + if ($comm_attr{$comm} =~ /\{\d+\}/) { + next; # next line. We don't handle args. + } + $fromx = $comm . $MATCH; + $fromx = quotemeta($fromx); + if ( defined $html_start{$comm} ) { + $tox = $html_start{$comm}; + } else { + $tox = bad_command("Unknown LaTeX command", "$comm\{"); + if ($nextarg[$id] != undef) { + # it's tnot clear what error we should report + } + } + warning(8, " {} Apply: $fromx ==> $tox on: $line"); + if (! ($line =~ s/$fromx/$tox/)) { + warning(3, " {} FAILED: $fromx ==> $tox on: $line"); + } + } + } + if ($line =~ /:([0-9]+):\]/) { + $id = $1; + $comm = $id2comm{$id}; + if ($comm ne "_:NULL_COMMAND:_") { + if ($comm_attr{$comm} =~ /\{\d+\}/) { + next; # next line. We don't handle args. + } + $fromx = $MATCH; + $fromx =~ s/:\]/:\\]/; + if ( defined $html_end{$comm} ) { + $tox = $html_end{$comm}; + } else { + $tox = bad_command("", "\}"); + } + warning(8, " {} Apply: $fromx ==> $tox on: $line"); + $line =~ s/$fromx/$tox/; + } + } + $arr->[$i] = $line; + } +} + +sub getspan { + my($arr, $span) = @_; + my($start,$end, $z) = split(/:/, $span, 3); + my($k, $result) = (0, ""); + for ($k = $start; $k <= $end; $k++) { + $result .= $arr->[$k]; + } + return $result; +} + + # + # Mark the "end arg" via ID of the arguments for multi-arg commands. + # We process the complicated command when we reach the last brace. + # +sub do_complicated_latex_defs { + my($arr) = @_; + my($arrlen) = scalar(@$arr); + my($comm, $fromx, $tox, $id, $inh, $i, $j, $k, $l, $nwant, $argidx); + for ($i=0; $i < $arrlen; $i++) { + $inh = vec($delim_inh, $i, 1); + if ($inh > 0) { + next; + } + $line = $arr->[$i]; + warning(8, "do_complicated_brace_comms($line)"); + if ($line =~ /\[:([0-9]+):/) { + $id = $1; + $from = $comm = $id2comm{$id}; + my($multarg) = scalar($comm_attr{$comm} =~ /\{(\d+)\}/); + warning(9, " multarg = $multarg"); + if (! $multarg) { + next; + } + $nwant = $1; + $argidx = $id; + # + # start from 2, as the first arg will always exist. + # + $argarr[$id][1] = $id; + for ($j=2; $j <= $nwant; $j++) { + $argidx = $nextarg[$argidx]; + if ($argidx == undef) { + warning("Not enough arguments for $comm\n"); + last; + } + $argarr[$id][$j] = $argidx; + } + $comm_trigger{$argidx} = $id; + warning(9, " comm_trigger{$argidx} is $comm_trigger{$argidx}"); + } + if ($line =~ /:([0-9]+):\]/) { + my($trigger_id) = $1; + if ( defined $comm_trigger{$trigger_id} ) { + $id = $comm_trigger{$trigger_id}; + $comm = $id2comm{$id}; + if ($comm_attr{$comm} =~ /\{(\d+)\}/) { + my(@arglist); + $nwant = $1; + $tox = $html_start{$comm}; + for ($j=1; $j <= $nwant; $j++) { + $k = $argarr[$id][$j]; + my($currarg) = getspan($arr, $argspan{$k}); + warning(9, " comp_def: arg[$id][$j] = $currarg"); + $tox =~ s/#$j/$currarg/g; + $arglist[$j] = $currarg; + } + warning(7, "CPX $comm --> tox = $tox"); + my($a, $b) = split(/:/, $argspan{$id}, 2); + $arr->[$a-1] = $tox; + my($c, $d, $e) = split(/:/, $argspan{$argarr[$id][$nwant]}, 3); + warning(9, "CPX erasing lines $a to $d"); + for ($j=$a; $j <= $d; $j++) { + my($o) = $arr->[$j]; + if ($o ne "") { + warning(8, " Wiping out line[$j] --> nothing"); + } + $arr->[$j] = ""; + } + } + $line =~ s/:$trigger_id:\]/$html_end{$comm}/; + } + } + $arr->[$i] = $line; + } +} + +sub final_cleanup { + my($arr) = @_; + my($arrlen) = scalar(@$arr); + my($inh); + my($lastline); + for ($i=0; $i < $arrlen; $i++) { + $inh = vec($delim_inh, $i, 1); + if ($inh > 0) { + next; + } + $line = $arr->[$i]; + + # restore newlines + $line =~ s/(\@NL\@)+/\n/g; + + # restore backslashes + $line =~ s/\@BS\@/\\/g; + + # restore newlines + $line =~ s/(\@NL\@)+/\n/g; + + # convert \\ (force line breaks) to HTML line breaks + $line =~ s/\\\\/<br>/; + + # restore '@' + $line =~ s:\@AT\@:\@:g; + + # convert any remaining unprocessed braces back to their orig form + $line =~ s/\[:\d+:/\{/; + $line =~ s/:\d+:\]/\}/; + + # restore real '{' and '}', after removing extraneous '{' '}' + $line =~ s:\{::g; + $line =~ s:\}::g; + $line =~ s:\@<<\@:{:g; + $line =~ s:\@>>\@:}:g; + $line =~ s:\@<<\@:\\\{:g; + $line =~ s:\@>>\@:\\\}:g; + + # hard-wired. Conversions. Ugh. No, double ugh. + # convert protected latex chars into single chars + $line =~ s/\\([\{\}\_\&\$\#\%])/$1/og; + # drop tildes (forced spaces in LaTeX). + $line =~ s/\.[~]+/\. /og; + # convert multiple dashes to a single dash. + $line =~ s/[-][-]+/-/og; + +# if (($i > 0) && ($lastline =~ /^\s*\n$/) && ($line =~ /[^\s]+/)) { + if (($i>=2) && ($lastline =~ /^\s*\n$/) && ($arr->[$i-2] =~ /\n$/)) { + $line = "<p>$line"; + } + + $lastline = $line; + $arr->[$i] = $line; + } +} + +# +# start executing at main() +# + +main(); + diff --git a/support/ltoh/ltoh.specs b/support/ltoh/ltoh.specs new file mode 100644 index 0000000000..8eec325b55 --- /dev/null +++ b/support/ltoh/ltoh.specs @@ -0,0 +1,101 @@ +# Standard specifications for ltoh. +# R. Quong 1996, 1997 +# quong@best.com + +# Comments begin with optional whitespace followed by a '#', ';', or a '!' +# We recommend you begin all comments with a '#'. +# Each line contains: +# + +author := Russell W. Quong +login := quong +email := quong@best.com +url := http://www.best.com/~quong +htmlfile_spec := $BASE.html + +# Don't monkey with (don't change) the following variable. +# It sets how much debugging information is printed out. +=***= warnlevel := 6 + +# The general structure of a specification is +# :type :latex-macro:html-begin-spec-start:html-end-spec:reserved/not-used +# +# type is one of the following: +# {} = brace delimited command, \textbf{...} +# {N} = command, with brace delimited N arguments, \swap{xxx}{yyy} +# comm = command without any parameters +# b/e = begin/end delimited command \begin{xxx} ... \end{xxx} +# + +:{} :\textbf:<STRONG>:</>: +:{} :\textsl:<EM>:</>: +:{} :\textem:<EM>:</>: +:{} :\textit:<EM>:</>: +:{} :\texttt:<SAMP>:</>: +:{} :\textsf:<EM>:</>: +:{} :\underline:<EM>:</>: +:{} :\chapter:<hr><H1><FONT color=green>:</>: +:{} :\section:<hr><H2><FONT color=blue>:</>: +:{} :\subsection:<H3><FONT color=teal>:</>: +:{} :\subsubsection:<H4><FONT color=teal>:</>: +:{} :\centerline:<P align=center>:</>: +:{} :\footnote:<font size=-1>[:]</>: +:{} :\ensuremath:<IT>:</>: +:{2} :\renewcommand#1#2::: +:{1} :\makebox[^{]*#1:#1:: +:b/e :\begin{center}:<DIV ALIGN=center>:</>: +:b/e :\begin{itemize}:<UL>:</>: +:b/e :\begin{enumerate}:<OL>:</>: +:b/e :\begin{description}:<DL>:</>: +:b/e :\begin{multques}(\{[^\}]*\})*:<OL>:</>: +:b/e :\begin{document}::: +:b/e :\begin{tabular}:\begin{tabular}:\end{tabular}: +:b/e :\begin{quote}:<BLOCKQUOTE>:</>: +:b/e :\begin{verse}:<BLOCKQUOTE>:</>: +:comm :\ldots:...:: +:comm :\par:<p>:: +:comm :\LaTeX[^ \t\n]*:LaTeX:: +:comm :\qquad::: +@comm @\longrightarrow@ ===> @@ +:comm :\TeX[^ \t\n]*:TeX:: +:comm :\backslash:@BS@:: +:comm :\hfill::: +:comm :\hrule:<hr>:: +:comm :\vneg::: +:comm :\item([^]]+\])?:<li><strong>$1</strong>:: +:comm :\def[^\n]+::: +:comm :\small::: +:comm :\normalsize::: +:comm :\footnotesize::: +:comm :\large::: +:comm :\Large::: +:comm :\parindent[^\n]+::: +:comm :\noindent[^\n]+::: +:comm :\setcounter[^ \t\n]*::: +:comm :\addtocounter[^ \t\n]*::: +:comm :\raggedright::: +:comm :\raggedleft::: +:comm :\vspace[*]?\{[^\}]+\}::: +:comm :\hspace[*]?\{[^\}]+\}::: +:comm :\usepackage\{[^\}]+\}::: +:comm :\documentclass[^ \t\n]+::: +:comm :\thispagestyle{.*}::: +:comm :\pagestyle{.*}::: +:comm :\newpage::: +:comm :\vfill::: + +# +# End specifications for standard Latex command +# + +# +# Also, see the file rq-ltoh.specs for more examples. +# + +# everything after =***= endfile =***= is ignored. +# =***= starts a + +=***= endfile =***= + +this stuff is all ignored. + diff --git a/support/ltoh/readme.dvi b/support/ltoh/readme.dvi Binary files differnew file mode 100644 index 0000000000..0fe193317f --- /dev/null +++ b/support/ltoh/readme.dvi diff --git a/support/ltoh/readme.html b/support/ltoh/readme.html new file mode 100644 index 0000000000..4ab8f49444 --- /dev/null +++ b/support/ltoh/readme.html @@ -0,0 +1,777 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> +<HTML> +<HEAD> +<TITLE> +Ltoh, a customizable LaTeX to HTML converter +</TITLE> +</HEAD> +<BODY> + + +<p> + +<p> + + +<p> + +<p> + +<p> + +<p> + +<p><center><H1><FONT color=green><font color=green><tt>Ltoh</tt></font>: a customizable LaTeX to HTML converter</FONT></H1></center> +<center><H3><FONT color=teal>Version 97e, 31 Mar 1997</FONT></H3></center> +<center><H3><FONT color=teal>Russell W. Quong</FONT></H3></center> + +<p> +<DIV ALIGN=center> +<EM>(http://www.best.com/~quong/ltoh)</EM> +</DIV> + +<p><hr><H2><FONT color=blue>Introduction</FONT></H2></hr> + +<p><font color=green><tt>Ltoh</tt></font> is a customizable LaTeX to HTML converter. It handles text, +tables, and hypertext links. <font color=green><tt>ltoh</tt></font> is a large Perl script, and hence is +(almost completely) platform independent. <font color=green><tt>ltoh</tt></font> is customizable in that +you can specify how to translate a given LaTeX2<it>e</it> macro into HTML, +including your own personal macros. In fact, you must manually specify +how to handle your own macros, otherwise <font color=green><tt>ltoh</tt></font> will give a friendly +warning. + +<p>See <a href="http://www.best.com/~quong/ltoh"> the <font color=green><tt>ltoh</tt></font> web page </a> for documentation, the +latest release, and how to contact the author (see the bottom of the web +page). Naturally, the HTML version of document was generated using +<font color=green><tt>ltoh</tt></font>, and in my opinion looks better than the LaTeX2<it>e</it> dvi/PS output, +mostly due to the extra colors. The first public release was version +97e on 3/31/97. + +<p><font color=green><tt>Ltoh</tt></font> has two main restrictions. First, <font color=green><tt>ltoh</tt></font> does <EM>not</EM> handle +math equations, which in general are difficult to display in HTML. +<font size=-1>[Some have resorted to converting the latex equations into +Postscript (PS), converting the PS to a bitmapped figure, and the +displaying the figure in HTML. This is all too difficult for me.]</font> +Second, <font color=green><tt>ltoh</tt></font> requires La/Tex macro parameters to be delimited by +braces; in practice, <font color=green><tt>ltoh</tt></font> might be unsuitable for most existing TeX +code. + +<p>Surprisingly, I often preview my LaTeX2<it>e</it> documents via <font color=green><tt>ltoh</tt></font> instead of +running <SAMP>latex</SAMP>, <SAMP>dvips</SAMP>, and <SAMP>ghostview</SAMP>. + +<p><hr><H2><FONT color=blue>The distribution</FONT></H2></hr> + +<p><font color=green><tt>Ltoh</tt></font> is distributed as either <a href="ltoh.zip"> a zip file </a> or a +<a href="ltoh.tgz"> gzipped tar file </a> (about 75K). + +<p>Both distributions contain the following files. + +<p><DIV ALIGN=center> +<table border> +<TR> <TD align=left> ltoh.pl </TD> <TD align=left> The perl script that does everything </TD></TR> +<TR> <TD align=left> ltoh.specs </TD> <TD align=left> The default specifications. </TD></TR> +<TR> <TD align=left> readme.html </TD> <TD align=left> Generated by <font color=green><tt>ltoh</tt></font> </TD></TR> +<TR> <TD align=left> readme.dvi </TD> <TD align=left> LaTeX2<it>e</it> output </TD></TR> +<TR> <TD align=left> readme.ps </TD> <TD align=left> Uses Times Roman </TD></TR> +<TR> <TD align=left> readme.txt </TD> <TD align=left> Text version (generated from netscape) </TD></TR> +<TR> <TD align=left> README </TD> <TD align=left> </TD></TR> +<TR> <TD align=left> rq-ltoh.specs </TD> <TD align=left> An example of my specifications </TD></TR> +<TR> <TD align=left> rq209.sty </TD> <TD align=left> Allow use of new LaTeX2<it>e</it> font commands in old LaTeX2<it>e</it>. </TD></TR> +<TR> <TD align=left> +</table> +</DIV> + +<p><hr><H2><FONT color=blue>System Software Requirements</FONT></H2></hr> + +<p><font color=green><tt>Ltoh</tt></font> version 97e requires the following system software. + +<p><OL> + <li><strong></strong> A unix operating system. I have tested <font color=green><tt>ltoh</tt></font> only under Linux, +although there is nothing Linux specific in the code. A handful of +lines are Unix dependent mostly in due to filename conventions. Because +<font color=green><tt>ltoh</tt></font> is written in Perl, almost all the code is platform-independent. + +<p> <li><strong></strong> Perl version 5.00x, preferably 5.002 or higher. Run + +<p><P align=center><SAMP>perl -v</SAMP></P> + +<p>to see the version of Perl you have. + +<p> <li><strong></strong> LaTeX2<it>e</it> macro parameters (or arguments) must be brace delimited +(surrounded by braces), because <font color=green><tt>ltoh</tt></font> relies on the braces. + +<p> <li><strong></strong> The <EM>new latex</EM> (LaTeX2<it>e</it>) is strongly recommended over the +<EM>old latex</EM> (LaTeX 2.09), + +<p>Additionally, the default <font color=green><tt>ltoh</tt></font> specifications is +based on standard new latex macros. Finally, to make full use of HTML +tables, future versions of <font color=green><tt>ltoh</tt></font> are likely to support multiple rows in +the table packages only found in the new latex. +</OL> + +<p><H3><FONT color=teal>If you must use LaTeX 2.09 instead of LaTeX2<it>e</it></FONT></H3> + +<p><font color=green><tt>ltoh</tt></font> relies on unique matching braces to delimit arguments to the latex +macros. In particular, the font family and size commands in old latex +do not use braces to delimit arguments. Thus, <font color=green><tt>ltoh</tt></font>\ does not (and +probably never will) handle old latex 2.09 font specifications. +Instead, you must use the LaTeX2<it>e</it> convention, which delimits the text to +be affected by a font change via braces as shown in the following +comparison. + +<pre> +(Old latex) Normal but switch \bf to {bold \it then italics, back to} +bold \normalfont then normal. + +(New latex) Normal but switch \textbf{to bold \textit{then italics, back +to} bold} then normal. +</pre> +<p> +Produces: + +<p><BLOCKQUOTE> +Normal but switch <STRONG>to bold <EM>then italics, back to</EM> +bold</STRONG> then normal. +</BLOCKQUOTE> + +<p>Using the old latex syntax, <font color=green><tt>ltoh</tt></font> cannot determine when the bold and +italic fonts stop being active. + +<p>If you have the new latex on your system, use it. If you must use an +old latex file, convert it to look like new latex as much as possible. +<OL> + <li><strong></strong> Convert all font change macros to use the new latex syntax. +Namely, convert <CODE><FONT color=navy> {\<EM>XYZ</EM> ... } </FONT></CODE> and <CODE><FONT color=navy> +\<EM>XYZ</EM> ... \normalfont </FONT></CODE> to <CODE><FONT color=navy>\ +text<EM>XYZ</EM>...</FONT></CODE>. + +<p> <li><strong></strong> Use the style file <TT><FONT color=maroon>rq209.sty</FONT></TT> (which should be) included +with the <font color=green><tt>ltoh</tt></font> distribution, which defines the \text<EM>XYZ</EM> +macros for use in the old latex. + +<p>To use this file, put +<DIV ALIGN=center> + <SAMP>\input{rq209.sty}</SAMP> +</DIV> + +<p>in your latex files. The file <TT><FONT color=maroon>rq209.sty</FONT></TT> additionally defines +the font size macros + <CODE><FONT color=navy>\fsize<EM>Tiny</EM></FONT></CODE>/.../<CODE><FONT color=navy>\fsize +<EM>Huge</EM></FONT></CODE> which take a single brace-delimited argument. For +exapmle, use <CODE><FONT color=navy>\fsizesmall{some text}</FONT></CODE> instead of <CODE><FONT color=navy> +{ \small some text }</FONT></CODE>. (This author wrote <TT><FONT color=maroon>rq209.sty</FONT></TT> back in +1994 because the office computer ran the old latex but the home Linux +machine ran the new latex.) + +<p>Alternatively, write and use your own definitions of the \ +text<EM>XYZ</EM> font change macros. +</OL> + +<p>(One final note.) The old latex convention is simply a poor technical +chioce. The current philosophy for document specifications (and even +programming languages) is that parameters/arguments/blocks are clearly +delimited syntactically. The use of matching braces by latex2e conforms +to the the SGML syntax, as does HTML which ubiquitously uses matching +begin and end tags. + +<p><hr><H2><FONT color=blue>Running <font color=green><tt>ltoh</tt></font></FONT></H2></hr> + +<p>To generate the HTML file <TT><FONT color=maroon>xyz.html</FONT></TT> from the latex file +<TT><FONT color=maroon>xyz.tex</FONT></TT>, assuming ltoh is in your path, run: + +<p><PRE> + prompt> <font color=green><tt>ltoh</tt></font> xyz.tex +or + prompt> perl fullpath-of-ltoh.pl xyz.tex +</PRE> + +<p>(I have not tested <font color=green><tt>ltoh</tt></font> on a Win32 machine, yet...) On a Win32 machine, +which cannot automatically start Perl to execute the <font color=green><tt>ltoh</tt></font>, you would +probably run + +<p><PRE> + prompt> perl <font color=green><tt>ltoh</tt></font>.pl xyz.tex +</PRE> + +<p><hr><H2><FONT color=blue>Specifications</FONT></H2></hr> + +<p>There are five types of <font color=green><tt>ltoh</tt></font> specifications. Please note the names. + +<p><OL> + <li><strong>[Begin/end pair (<CODE><FONT color=navy>b/e</FONT></CODE>)]</strong> Specifies how to translate a latex +<CODE><FONT color=navy>\begin{XYZ}</FONT></CODE> and matching <CODE><FONT color=navy>\end{XYZ}</FONT></CODE> +command. + +<p> <li><strong>[Command (<CODE><FONT color=navy>comm</FONT></CODE>)]</strong> Specifies how to translate a latex +command that does not take any parameters, such as <CODE><FONT color=navy>\par</FONT></CODE>, +<CODE><FONT color=navy>\item</FONT></CODE> or <CODE><FONT color=navy>\hrule</FONT></CODE>. + +<p> <li><strong>[Simple-macro (<CODE><FONT color=navy>{}</FONT></CODE>)]</strong> Specifies a translation for a +latex macro that takes a single brace-delimited argument <EM>arg-1</EM>, +where the corresponding HTML consists simply of surrounding the argument +with a preamble and postamble. The translation is simple as the +argument stays put; <font color=green><tt>ltoh</tt></font> merely puts stuff before and after it. That +is, we expect + +<p><P align=center> + <CODE><FONT color=navy> + \simplemacro{<EM>...</EM>} <IT> ===> </IT> + HTML-preable <EM>...</EM> HTML-postable + </FONT></CODE> +</P> + +<p>For example, use a simple-macro specification to translate the latex +macro <CODE><FONT color=navy>\textbf{ ... }</FONT></CODE> (switch to bold face) into the HTML +<CODE><FONT color=navy><strong> ... </strong></FONT></CODE>. + +<p> <li><strong>[Arg-macro (<CODE><FONT color=navy>{<EM>N</EM>}</FONT></CODE>)]</strong> Specifies a translation +for a latex macro that takes $N$ brace-delimited arguments; the +corresponding HTML can make arbitrary use of the arguments. For +example, my latex macro <CODE><FONT color=navy>\swallow{arg-1}</FONT></CODE> discards its +single (possibly long) argument. In the corresponding HTML, we also +``use'' the argument, by discarding it. + +<p> <li><strong>[Assignment (<CODE><FONT color=navy>:=</FONT></CODE>)]</strong> An assignment sets a <font color=green><tt>ltoh</tt></font> variable +which is then used later. As of version 97e, only a small number +of built-in variables are supported. I hope to support setting and +getting user-defined variables in the future. + +<p> + +<p></OL> + +<p>The first four specications are known as translations specifications. + +<p><H3><FONT color=teal>Translation specifications</FONT></H3> + +<p>The four types of translation specifications have the same form. Do not +use leading whitespace. Here is the general form and an example of each +type. + +<pre> +:type :latex-macro-name:HTML-start-code:HTML-end-code:reserved/not-used + +:b/e :\begin{itemize}:<UL>:</>: +:comm :\hrule:<hr>:: ++comm +\homepage+http://www.best.com/~quong++ +:{} :\textbf:<STRONG>:</>: +:{2} :\rqhttp#1#2:<a href="#2"> #1 </a>:: +</pre> +<p> +Each specification contains six parts. + +<p><OL> + <li><strong></strong> The first character on the line is the <EM>separator</EM> char, +which delimits the remaining parts of the specification. The separator +char can be any character. I have used a colon (:) and a plus sign (+) +in the above examples. Note that the <CODE><FONT color=navy>\homepage</FONT></CODE> macro +expands to HTML containing a colon, so a colon cannot be the delimiter +and I have used a plus. I do not recommend using a space/tab as the +delimiter, as multiple spaces/tabs are easy to overlook. + +<p> <li><strong></strong> The <EM>type</EM>. If the type is arg-macro, the number of +parameters is specified in the braces. Arbitrary space may follow the +type. + +<p> <li><strong></strong> The <EM>latex macro name</EM> specifies the latex macro to be +translated. A latex macro must start with a backslash (if you have +redefined the LaTeX2<it>e</it> catcodes, sorry). An optional Perl regular +expression can following the macro name, to account for parameters for +the macro. Usually the latex parameters are just discarded in the +resulting HTML. + +<p>As an example of an optional regular expression, the LaTeX2<it>e</it> horizontal +space command <CODE><FONT color=navy>\hspace</FONT></CODE> takes an optional <CODE><FONT color=navy>*</FONT></CODE> +argument, and then a required horizontal length argument. In the +generated HTML, we want to ignore the entire <CODE><FONT color=navy>\hspace</FONT></CODE> +macro, and so I use the following <font color=green><tt>ltoh</tt></font> spec. + +<pre> +:comm :\hspace[*]?\{[^\}]+\}::: +</pre> +<p> + <li><strong></strong> The <EM>HTML start code</EM> is the HTML code to insert +when the macro is first seen. + +<p><OL> + <li><strong>[begin/end pair]</strong> The <CODE><FONT color=navy>\beginXXX</FONT></CODE> expands to +<EM>HTML start code</EM>. + <li><strong>[command]</strong> The LaTeX2<it>e</it> macro expands to <EM>HTML start code</EM>. + <li><strong>[Simple-macro]</strong> The opening brace expands to <EM>HTML start +code</EM>; the closing brace expands to <EM>HTML end code</EM>. + <li><strong>[arg-macro]</strong> The command and all its arguments expands to +<EM>HTML start code</EM>. +</OL> + +<p>In an arg-macro specification, using the LaTeX2<it>e</it> convention, the first +argument is represented by #1, the second argument by #2, and so on in +the HTML start code. (To actually generate a <CODE><FONT color=navy>\#1</FONT></CODE>, use +braces as in #{1}.) Thus, a macro that swaps the order of its +parameters would be written as + +<pre> +:{2} :\swap_two:#2#1:: +</pre> +<p> +As another example, the LaTeX2<it>e</it> <CODE><FONT color=navy>\makebox</FONT></CODE> command takes an +optional alignment parameter (one of <CODE><FONT color=navy>[l]</FONT></CODE>, <CODE><FONT color=navy>[c]</FONT></CODE> or +<CODE><FONT color=navy>[r]</FONT></CODE>) followed by text to be put into the box. I use the +following <font color=green><tt>ltoh</tt></font> spec to ignore the alignment parameter and to print the +text out unadorned. + +<pre> +:{1} :\makebox[^{]*#1:#1:: +</pre> +<p> + <li><strong></strong> The <EM>HTML end code</EM> specifier is the HTML code to insert +at $(i)$ the end of a begin-end pair or $(ii)$ the closing brace of a +simple-macro. Note that the <EM>HTML end code</EM> specifier does not +make sense for a <EM>command</EM> or <EM>arg-macro</EM> specification +and is ignored. + +<p>As a convenience, using <CODE><FONT color=navy></></FONT></CODE> in the <EM>HTML end code</EM> +expands to the end tag(s) in reverse order of the corresponding HTML +begin code. For example, I want a LaTeX2<it>e</it> <CODE><FONT color=navy>\section</FONT></CODE> to show +up as a green <H2> header in HTML, so I specify + +<pre> +:{} :\section:<hr><H2><FONT color=green>:</>: +</pre> +<p> +which is equivalent to + +<pre> +:{} :\section:<hr><H2><FONT color=green>:</FONT></H2></HR>: +</pre> +<p> +</OL> + +<p>The following table summarizes the effects of the various +specifications, and the parts of the spefications used. + +<p><CODE><FONT color=navy> +<table border> +<TR> <TD align=left> Type </TD> <TD align=left> macro name </TD> <TD align=left> HTML start </TD> <TD align=left> HTML end </TD> <TD align=left> </TD> <TD align=left> input </TD> <TD align=left> output </TD></TR> +<TR> <TD align=left> comm </TD> <TD align=left> \abc </TD> <TD align=left> XYZ </TD> <TD align=left> not-used </TD> <TD align=left> </TD> <TD align=left> \abc </TD> <TD align=left> XZY </TD></TR> +<TR> <TD align=left> b/e </TD> <TD align=left> \begin{abc} </TD> <TD align=left> XYZ </TD> <TD align=left> ijk </TD> <TD align=left> </TD> <TD align=left> \begin{abc}...\end{abc} </TD> <TD align=left> XZY ... ijk </TD></TR> +<TR> <TD align=left> {} </TD> <TD align=left> \abc </TD> <TD align=left> XYZ </TD> <TD align=left> ijk </TD> <TD align=left> </TD> <TD align=left> \abc{...} </TD> <TD align=left> XYZ... ijk </TD></TR> +<TR> <TD align=left> {2} </TD> <TD align=left> \abc </TD> <TD align=left> X#2Y#1Z </TD> <TD align=left> not-used </TD> <TD align=left> </TD> <TD align=left>\abc{===}{+++} </TD> <TD align=left> +X+++Y===Z </TD></TR> +</table> +</FONT></CODE> + +<p>As a final example, here's how generate links in HTML. I define a latex +macro <CODE><FONT color=navy>\rqhttp</FONT></CODE> and a corresponding <font color=green><tt>ltoh</tt></font> specficiation. +Because the tilde is accessible only in math mode, I have had to define +a latex macro (<CODE><FONT color=navy>\rqtilde</FONT></CODE>) for it, too. + +<p><PRE> +(latex macro) +<CODE><FONT color=navy>\def\rqtilde{\ensuremath{\tilde{\;}}\xspace}</FONT></CODE> +<CODE><FONT color=navy>\def\rqhttp#1#2{#1 (\texttt{#2})}</FONT></CODE> +(<font color=green><tt>ltoh</tt></font> spec) +<CODE><FONT color=navy>:comm :\rqtilde:~::</FONT></CODE> +<CODE><FONT color=navy>:2 :\rqhttp#1#2:<a href="#2"> #1 </a>::</FONT></CODE> +</PRE> + +<p>In LaTeX2<it>e</it>, I use the <CODE><FONT color=navy>\rqhttp</FONT></CODE> macro as follows. + +<p><BLOCKQUOTE> + See the \rqhttp{\ltoh + webpage}{http://www.best.com/\rqtilde{}quong/ltoh}. +</BLOCKQUOTE> + +<p>The resulting dvi output from latex and the HTML from <font color=green><tt>ltoh</tt></font> look like + +<p><PRE> + (Latex) See the ltoh web page (http://www.best.com/~quong/ltoh). + +<p> (HTML) See the <A HREF="http://www.best.com/~quong/ltoh"> ltoh web page </A> +</PRE> + +<p><hr> + +<p>Finally, good example of using <font color=green><tt>ltoh</tt></font> specifiers is the default <font color=green><tt>ltoh</tt></font> spec file +<TT><FONT color=maroon>ltoh.specs</FONT></TT> that comes with this release. + +<p>[Aside: Technically, the <CODE><FONT color=navy>simple-macro</FONT></CODE> specifier is not needed, +as its functionality can be duplicated with an <CODE><FONT color=navy>arg-macro</FONT></CODE>. +Namely, +<pre> +:{} :\macro:HTML-begin:HTML-end:: +</pre> + +<p>can be duplicated via + +<pre> +:{1} :\macro:HTML-begin#1HTML-end:::. +</pre> +<p> +Nonetheless, use of a simple-macro { } specifiction is preferred, +because its processing is much simpler. With a simple-macro, <font color=green><tt>ltoh</tt></font> does +not have to extract and pass the parameter, and hence it is less likely +to break than an arg-macro.] + +<p><H3><FONT color=teal>Assignment</FONT></H3> + +<p>An assignment specification has two nearly identical forms. The double +quotes are optional and can be used to imbed leading spaces into the +string-value. The whitespace surrounding string-value is removed. + +<p><PRE> + variable-name := string-value + variable-name := "string-value" + +<p> title := The readme for ltoh +</PRE> + +<p>Here are the currently used built-in variables. + +<p><table border> +<TR> <TD align=left> variable </TD> <TD align=left> Default </TD> <TD align=left> Description </TD></TR> +<TR> <TD align=left> <CODE><FONT color=navy>title</FONT></CODE> </TD> <TD align=left> <CODE><FONT color=navy>none</FONT></CODE> </TD> <TD align=left> Title of the resulting HTML file, via +the <CODE><FONT color=navy><TITLE></FONT></CODE> tag. <STRONG><FONT color=maroon>You must define this variable.</FONT></STRONG> +Set <CODE><FONT color=navy>title</FONT></CODE> in the latex file itself. (It drives me nuts when +web pages don't have titles) </TD></TR> +<TR> <TD align=left> <CODE><FONT color=navy>url</FONT></CODE> </TD> <TD align=left> <CODE><FONT color=navy>none</FONT></CODE> </TD> <TD align=left> URL of the home page of the author. </TD></TR> +<TR> <TD align=left> <CODE><FONT color=navy>author</FONT></CODE> </TD> <TD align=left> <CODE><FONT color=navy>none</FONT></CODE> </TD> <TD align=left> Author of the document. </TD></TR> +<TR> <TD align=left> <CODE><FONT color=navy>email</FONT></CODE> </TD> <TD align=left> <CODE><FONT color=navy>none</FONT></CODE> </TD> <TD align=left> Email address to which comments +should be sent </TD></TR> +<TR> <TD align=left> <CODE><FONT color=navy>htmlfile_spec</FONT></CODE> </TD> <TD align=left> <CODE><FONT color=navy>$BASE.html</FONT></CODE> </TD> <TD align=left> Name of HTML file +generated. The <font color=green><tt>ltoh</tt></font> variable <CODE><FONT color=navy>$BASE</FONT></CODE> is the +latex file name stripped of the directory and suffix components. </TD></TR> +</table> + +<p>The <CODE><FONT color=navy>url</FONT></CODE>, <CODE><FONT color=navy>author</FONT></CODE>, and <CODE><FONT color=navy>email</FONT></CODE> variables are used +to generate an address block at the bottom of the HTML page. (See the +bottom of this document if you are reading it on the web). + +<p><hr><H2><FONT color=blue>Tables</FONT></H2></hr> + +<p><font color=green><tt>ltoh</tt></font> handles the LaTeX2<it>e</it> <CODE><FONT color=navy>tabular</FONT></CODE> and <CODE><FONT color=navy>tabularx</FONT></CODE> +environments. Column alignments are read and passed onto the +corresponding HTML. The known column alignments must be one of `` l c r +p X''. If you define your own column alignment, it will not be +understood. + +<p><font color=green><tt>ltoh</tt></font> handles the LaTeX2<it>e</it> <CODE><FONT color=navy>multicolumn</FONT></CODE> macro reasonably well. +The column alignment is read and passed onto the corresponding HTML. + +<p>I plan to support the <CODE><FONT color=navy>\multirow</FONT></CODE> macro soon. + +<p><font color=green><tt>ltoh</tt></font> ignores extraneous LaTeX2<it>e</it> specs in the column alignment +specifications, such as <CODE><FONT color=navy>\@</FONT></CODE>, but there is a small +chance a complicated multiple column alignment spec will break this +code. + +<p>The generated HTML table has a border if one or more dividing lines in +the LaTeX2<it>e</it> table column alignment (namely if a $|$ specifier appears in +the latex, the HTML table has a border). Nested tables are not +supported, and I currently do not plan to support them, as this feature +seems hard. + +<p><hr><H2><FONT color=blue>Where are specifications found?</FONT></H2></hr> + +<p>As of version 97e, <font color=green><tt>ltoh</tt></font> reads specifications from $(i)$ +various specification-files and $(ii)$ from the LaTeX2<it>e</it> file itself as it +is being processed, as follows. + +<p><OL> + <li><strong></strong> Reads the specification file <TT><FONT color=maroon>ltoh.specs</FONT></TT> from the +<TT><FONT color=maroon>install-dir</FONT></TT>, which is the directory where you have placed both +<TT><FONT color=maroon>ltoh.pl</FONT></TT> and <TT><FONT color=maroon>ltoh.specs</FONT></TT>. The <TT><FONT color=maroon>install-dir</FONT></TT> can +be anywhere. + +<p>(In version 97e, you should do one of the following when running +<font color=green><tt>ltoh</tt></font>. +<OL> + <li><strong></strong> Run <font color=green><tt>ltoh</tt></font> via: + +<p><SAMP>prompt> perl install-dir/ltoh.pl file.tex</SAMP>. + +<p> <li><strong></strong> Set up an alias as follows: + +<p>(csh) <SAMP>alias ltoh perl install-dir/ltoh</SAMP> <br> +or<br> +(bash) <SAMP>alias ltoh=perl install-dir/ltoh</SAMP> + +<p> <li><strong></strong> Put <TT><FONT color=maroon>install-dir</FONT></TT> in your path, and run: + +<p><SAMP>prompt> ltoh.pl file.tex</SAMP> + +<p> <li><strong></strong> Set up a single symbolic link, say called <TT><FONT color=maroon>ltoh</FONT></TT>, in your +path which points directly to <TT><FONT color=maroon>install-dir/ltoh.pl</FONT></TT>. You can +then run + +<p><SAMP>prompt> ltoh file.tex</SAMP> + +<p></OL> + +<p>This mess is relative symbolic links. Yes. Given an arbitrary +invocation of <font color=green><tt>ltoh</tt></font> involving symbolic links, I cannot currently +determine where the <TT><FONT color=maroon>ltoh.pl</FONT></TT> script actually resides (the +<TT><FONT color=maroon>install-dir</FONT></TT>). Once I implement this code, the setup won't be +complicated. + +<p> <li><strong></strong> Reads the specification file <TT><FONT color=maroon>.ltoh.specs</FONT></TT> in your home directory. + <li><strong></strong> Reads the specification file <TT><FONT color=maroon>.ltoh.specs</FONT></TT> in the current +directory, where the command is being run. + +<p> <li><strong></strong> If any of these specification files exist, <font color=green><tt>ltoh</tt></font> proceeds to the +next step reading the LaTeX2<it>e</it> input file + +<p>However, if none of the preceding spec files were, <font color=green><tt>ltoh</tt></font> tries to read + +<p><TT><FONT color=maroon>/usr/local/bin/ltoh.specs</FONT></TT> and that fails, tries +<TT><FONT color=maroon>/usr/bin/ltoh.specs</FONT></TT>. If both of these still fail, <font color=green><tt>ltoh</tt></font> +<STRONG><FONT color=maroon>quits</FONT></STRONG>. + +<p> <li><strong></strong> Reads specifications from the latex file being processed, which +appear as latex comments of the form + +<p><P align=center><CODE><FONT color=navy>%-ltoh- <EM>ltoh-specification</EM></FONT></CODE></P>. + +<p><font color=green><tt>ltoh</tt></font> strips the leading <CODE><FONT color=navy>%-ltoh- </FONT></CODE> and processes the +remainder of the line. + +<p>If nothing else, set the <CODE><FONT color=navy>title</FONT></CODE> variable this way. For example, +here's how this LaTeX2<it>e</it> file starts. + +<pre> +\documentclass[]{article} +... various latex commands like \usepackage +%-ltoh- title := Ltoh, a customizable LaTeX to HTML converter +%-ltoh- :comm:\ltoh:<font color=green><tt>ltoh</tt></font>:: +... +\begin{document} +... the body of the document +</pre> +<p> +</OL> + +<p><hr><H2><FONT color=blue>Limitations, bugs, missing features</FONT></H2></hr> + +<p><H3><FONT color=teal>Limitations</FONT></H3> + +<p><OL> + <li><strong></strong> Specifications are applied only once to a latex macro. Namely +if a macro <EM>macroAA</EM> generates a macro <EM>macroBB</EM> in latex, +and <EM>macroBB</EM> is translated to <EM>htmlBB</EM>, then you must +specify to <font color=green><tt>ltoh</tt></font> that <EM>macroAA</EM> is translated directly to +<EM>htmlBB</EM> in your specification for <EM>macroAA</EM>. +</OL> + +<p><H3><FONT color=teal>Bugs</FONT></H3> + +<p>It is not difficult to break <font color=green><tt>ltoh</tt></font>, though there are often easy fixes by +restructuring your LaTeX2<it>e</it>. + +<p><H3><FONT color=teal>Missing features</FONT></H3> + +<p><OL> + <li><strong></strong> There are no command line flags. The following would be +particularly useful. + +<p><table border> +<TR> <TD align=left> -o <EM>ofile</EM> </TD> <TD align=left> generate HTML into file <EM>ofile</EM> </TD></TR> +<TR> <TD align=left> -I <EM>specfile</EM> </TD> <TD align=left> read specifications from <EM>specfile</EM> </TD></TR> +<TR> <TD align=left> -w N </TD> <TD align=left> set the warning level to N (for debugging) </TD></TR> +</table> + +<p> <li><strong></strong> There no means to manipulate counters, which would be useful for +sectioning commands. + +<p> <li><strong></strong> There should be away to set and get a value as part of a +specification. + +<p> <li><strong></strong> If the input uses LaTeX2<it>e</it> sectioning macros, optionally generate +a table of contents with links to anchors. + +<p> <li><strong></strong> Allow for an abitrary prologue and epilogue in the HTML file. + +<p> <li><strong></strong> In a table, we assume that the column alignment specs are on the +same line as the owning <CODE><FONT color=navy>\begin{tabular}</FONT></CODE> or the owning +<CODE><FONT color=navy>\multicolumn</FONT></CODE>. This assumption is very reasonable and +circumventing this restriction is difficult. +</OL> + +<p><hr><H2><FONT color=blue>Internal details</FONT></H2></hr> + +<p><font color=green><tt>Ltoh</tt></font> first reads the entire LaTeX2<it>e</it> file into memory, makes several +passes over the data, and finally spits out the HTML file<font size=-1>[Thus, +it is conceivable that <font color=green><tt>ltoh</tt></font> might run out of memory if processing a +huge LaTeX2<it>e</it> file on a machine with limited memory.]</font> The passes are +roughly as follows. + +<p><OL> + <li><strong></strong> Read spec files. + <li><strong></strong> Handle comments and the verbatim environment. + <li><strong></strong> Escape/protect characters. + <li><strong></strong> Handle tables. + <li><strong></strong> Handle begin/end pairs. + <li><strong></strong> Handle LaTeX2<it>e</it> commands without parameters. + <li><strong></strong> Mark braces, linking braces to macros. + <li><strong></strong> Handle simple macros. + <li><strong></strong> Handle arg macros. + <li><strong></strong> Generate HTML. +</OL> + +<p><hr><H2><FONT color=blue>History</FONT></H2></hr> + +<p> + +<p><table border> +<TR> <TD align=left> June 1996 </TD> <TD align=left> Version 96a. Preliminary fully hard-coded (not +customizable) version. + Purely regular expression based. Unable to handle nested braces. +Ugly, but it worked. Sort of. + </TD></TR> +<TR> <TD align=left> + July 1-15 1996 </TD> <TD align=left> Version 96b. First working version. Able to handle +commands with multiple arguments and nested arguments. Took me a lot +longer than I had expected to get this working. +</TD></TR> +<TR> <TD align=left> + Jan 27-29 1997 </TD> <TD align=left> Version 97a. Stops processing at +<CODE><FONT color=navy>\end{document}</FONT></CODE>. Convert double back slashes +\\to <CODE><FONT color=navy><br></FONT></CODE>, which should have done a long time ago. +Fixed bug involving macros with only one parameter. +</TD></TR> +<TR> <TD align=left> + Feb 1997 </TD> <TD align=left> Version 97b. Added HTML <CODE><FONT color=navy><p></FONT></CODE> tags whenever +two or more consecutive blank lines are seen. +</TD></TR> +<TR> <TD align=left> + Mar 11-15 1997 </TD> <TD align=left> Version 97c. Much improved handling of special +characters such as {, }, <, > and @. In particular, bare braces +which mean nothing in latex are stripped from the HTML. Improved +paragraph detection handling. (OK, OK, "Improved ..." really means +"fixed bugs in ..."). No longer generates HTML comments for latex +comments, by default. Version 97c was meant to be first public release, +but the tables this <TT><FONT color=maroon>readme.tex</FONT></TT> document broke <font color=green><tt>ltoh</tt></font> badly. +</TD></TR> +<TR> <TD align=left> + Mar 19-20 1997 </TD> <TD align=left> Version 97d. Complete rewrite of the table handling +code. Latex column alignment specifications are understood and passed +onto to the HTML. Multiple columns specified via either +<CODE><FONT color=navy>\multicolumn</FONT></CODE> or <CODE><FONT color=navy>\mc</FONT></CODE> (which is my personal +abbreviation macro) are handled properly. We try to ignore extraneous +LaTeX2<it>e</it> specs in the column alignment specifications, such as +<CODE><FONT color=navy>@</FONT></CODE>. +, but there is there is a small chance multiple +columns + +<p>In particular, <font color=green><tt>ltoh</tt></font> now handles this file (<TT><FONT color=maroon>readme.tex</FONT></TT>) +properly. +</TD></TR> +<TR> <TD align=left> + Mar 25-31 1997 </TD> <TD align=left> Version 97e. Official release. Clean up source a +bit for release. Minor improvements on tables (allow end of a row to be +on a separate line), paragraphs, specification files and handling +special characters (allow for multiple chars on one line). </TD></TR> +</table> + +<p><hr><H2><FONT color=blue>License for use</FONT></H2></hr> + +<p>You may use <font color=green><tt>ltoh</tt></font> freely, under the following conditions, which are +covered under a BSD-style license. + +<p><OL> + <li><strong></strong> You must keep the <font color=green><tt>ltoh</tt></font> notice at the end of all generated HTML. +This notice indicates how the document was generated (namely, with +<font color=green><tt>ltoh</tt></font>) and has a link to the <font color=green><tt>ltoh</tt></font> web page. You may reduce the size of +the notice if you wish, but it must remain in your document and visible. + +<p> <li><strong></strong> <font color=green><tt>Ltoh</tt></font> comes with neither a warranty nor a gaurantee about its +correctness, performance, or suitability for any task. + +<p> <li><strong></strong> If you modify or redistribute <font color=green><tt>ltoh</tt></font>, you must keep the current +disclaimer and license with the <font color=green><tt>ltoh</tt></font> source which must be visible upon +startup, unless you + +<p> <li><strong></strong> I, Russell Quong, retain the copyright for <font color=green><tt>ltoh</tt></font>. +</OL> + +<p><H3><FONT color=teal>Official software license</FONT></H3> + +<p>Here's the official license as of 31 Mar 97. + +<pre> +# Copyright (c) 1996, 1997 Russell W Quong. +# +# In the following, the "author" refers to "Russell Quong." +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by Russell Quong. +# 3. All HTML generated by ltoh must retain a visible notice that it +# was generated by ltoh and contain a link to the ltoh web page +# +# Any or all of these provisions can be waived if you have specific, +# prior permission from the author. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL RUSSELL QUONG BE LIABLE FOR ANY SPECIAL, +# INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY +# THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +</pre> +<p> +<hr><H2><FONT color=blue>Motivation</FONT></H2></hr> + +<p>(The motivation section belongs right after the introduction, but most +people probably just want to get on with using <font color=green><tt>ltoh</tt></font>. So this section +has been relegated here. Ah well...) + +<p>Although other LaTeX2<it>e</it> to HTML converters exist, I wrote my own because I +wanted to generate HTML customized to my own liking. In particular, I +use my own custom LaTeX2<it>e</it> definitions (who doesn't?) and wanted to +generate HTML appropriately. Additionally, when using other converters, +I was unable get them to run properly, or I did not like the way the +generated HTML looked. + +<p>Fundamentally, <font color=green><tt>ltoh</tt></font> is a specialized macro processor that reads macro +<EM>specifications</EM> and generates HTML accordingly. A specification +indicates how to convert a specific LaTeX2<it>e</it> definition into HTML. + +<p>My orginal goals in writing <font color=green><tt>ltoh</tt></font> were + +<p><OL> + <li><strong></strong> To become more proficient in Perl. + +<p> <li><strong></strong> To write a converter that allowed customized HTML to be +generated. + +<p> <li><strong></strong> To handle arbitrary LaTeX2<it>e</it> macros, including macros that take +multiple arguments, and arguments that contained nested macros. + +<p> <li><strong></strong> To generate HTML that resembled the original LaTeX2<it>e</it>, as if +someone had done the translation by hand. In particular, I wanted to +avoid generating very long lines of HTML source, which are difficult to +read when ``viewing the source'' in a browser. +</OL> + +<p><hr><H2><FONT color=blue>Acknowledgements</FONT></H2></hr> + +<p>Thanks to <a href="http://www.varesearch.com"> VA Research </a> for letting the author work on +<font color=green><tt>ltoh</tt></font>. + +<p><HR> +<font size=+0><EM>[Converted LaTeX --> HTML by <a href="http://www.best.com/~quong/ltoh.html">ltoh</a>]</EM></font><br> +<ADDRESS> +<A href="http://www.best.com/~quong">Russell W. Quong</A> +(<A href="mailto:quong@best.com"><SAMP>quong@best.com</SAMP></A>) +Last modified: <font color=maroon><samp>Apr 1 1997</samp></font> +</ADDRESS> +</BODY> +</HTML> diff --git a/support/ltoh/readme.pdf b/support/ltoh/readme.pdf Binary files differnew file mode 100644 index 0000000000..213138c79a --- /dev/null +++ b/support/ltoh/readme.pdf diff --git a/support/ltoh/readme.ps b/support/ltoh/readme.ps new file mode 100644 index 0000000000..2450a0216b --- /dev/null +++ b/support/ltoh/readme.ps @@ -0,0 +1,1027 @@ +%!PS-Adobe-2.0 +%%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software +%%Title: readme.dvi +%%Pages: 9 +%%PageOrder: Ascend +%%BoundingBox: 0 0 596 842 +%%DocumentFonts: Helvetica-Bold Times-Bold Helvetica Times-Roman Courier +%%+ Times-Italic Times-BoldItalic Courier-Oblique +%%DocumentPaperSizes: A4 +%%EndComments +%DVIPSCommandLine: dvips readme +%DVIPSParameters: dpi=300, comments removed +%DVIPSSource: TeX output 1997.04.01:0035 +%%BeginProcSet: tex.pro +/TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N +/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 +mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} +ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale +isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div +hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul +TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} +forall round exch round exch]setmatrix}N /@landscape{/isls true N}B +/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B +/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ +/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N +string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N +end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ +/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] +N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup +length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ +128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub +get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data +dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N +/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup +/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx +0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff +setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff +.1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} +if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup +length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ +cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin +0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul +add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict +/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook +known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X +/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for +65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 +0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V +{}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 +getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} +ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false +RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 +false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform +round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg +rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail +{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} +B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ +4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ +p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p +a}B /bos{/SS save N}B /eos{SS restore}B end +%%EndProcSet +%%BeginFont: Helvetica-Bold +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "22 June 1996", +% filename = "8r.enc", +% email = "kb@@mail.tug.org", +% address = "135 Center Hill Rd. // Plymouth, MA 02360", +% codetable = "ISO/ASCII", +% checksum = "119 662 4424", +% docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def +%%EndFont +%%BeginProcSet: texps.pro +TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 +index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict +end definefont 3 -1 roll makefont /setfont load]cvx def}def +/ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def +/ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def +end +%%EndProcSet +TeXDict begin 39158280 55380996 1000 300 300 (readme.dvi) +@start /Fa 1 35 df<07E01FF83818200020003F803F80400080008000801040207FC0 +1F000D0E7F8D10>34 D E /Fb 139[9 4[18 2[7 3[18 104[{ + TeXBase1Encoding ReEncodeFont }4 33.333334 /Helvetica +rf /Fc 134[25 3[25 25 25 2[25 25 25 1[25 2[25 25 25 25 +25 1[25 1[25 6[25 25 25 3[25 5[25 5[25 25[25 25 45[{ + TeXBase1Encoding ReEncodeFont }23 41.666669 /Courier-Oblique +rf /Fd 6 111 df<FFFFFF80FFFFFF8019027D8A20>0 D<000000300000000018000000 +00180000000018000000000C000000000C00000000060000000003000000000380000000 +00C0FFFFFFFFF8FFFFFFFFF800000000C00000000380000000030000000006000000000C +000000000C00000000180000000018000000001800000000300025167E942A>33 +D<003C00E001C00180038003800380038003800380038003800380038003800380038003 +0007001C00F0001C00070003000380038003800380038003800380038003800380038003 +800380018001C000E0003C0E297D9E15>102 D<F0001C00070003000380038003800380 +038003800380038003800380038003800380018001C000E0003C00E001C0018003800380 +03800380038003800380038003800380038003800380030007001C00F0000E297D9E15> +I<C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0 +C0C0C0C0C0C002297B9E0C>106 D<C000C0006000600060003000300030001800180018 +000C000C000C000600060003000300030001800180018000C000C000C000600060003000 +300030001800180018000C000C000C0006000600060003000110297E9E15>110 +D E /Fe 139[12 16 3[21 23 1[12 21 1[12 23 2[18 1[18 21 +21 52[10 44[{ TeXBase1Encoding ReEncodeFont }13 41.666669 +/Times-BoldItalic rf /Ff 1 35 df<003F0001FFC00381E004004008000010000010 +00001000001060000B98000FF800100000200000400000400000400000800000C0008040 +0080600100300E001FFC0007E00013177F9517>34 D E /Fg 190[24 +65[{ TeXBase1Encoding ReEncodeFont }1 33.333334 /Times-Bold +rf /Fh 134[17 17 24 17 17 9 13 11 17 17 17 17 26 9 2[9 +17 17 11 15 17 15 17 15 8[24 3[20 18 2[18 2[30 20 3[24 +2[20 18[17 3[8 1[8 2[11 11 37[18 2[{ TeXBase1Encoding ReEncodeFont }37 +33.333334 /Times-Roman rf /Fi 190[18 14[12 12 49[{ + TeXBase1Encoding ReEncodeFont }3 25.000001 /Times-Roman +rf /Fj 134[21 21 30 2[12 16 14 1[21 21 21 32 12 2[12 +21 21 1[18 21 18 1[18 6[25 30 30 3[25 6[37 25 3[30 5[28 +30 15[21 3[14 42[23 2[{ .167 SlantFont TeXBase1Encoding ReEncodeFont } +30 41.666669 /Times-Roman rf /Fk 139[12 4[21 21 110[{ + TeXBase1Encoding ReEncodeFont }3 41.666669 /Times-Italic +rf /Fl 103[25 15[25 10[25 1[25 25 25 25 25 25 25 25 25 +25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 +1[25 1[25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 +25 25 25 1[25 25 25 25 25 25 25 25 25 25 25 25 25 25 +25 25 25 1[25 25 2[25 25 25 25 25 25 25 25 25 25 25 25 +2[25 25 25 25 34[{ TeXBase1Encoding ReEncodeFont }85 +41.666669 /Courier rf /Fm 5 106 df<00FC03FE0E07180010002000200010C01720 +1FE0200040004000800080008004400860303FE00F8010147F9213>34 +D<000001800000078000001E00000078000001E00000078000000E00000038000000F000 +0003C000000F0000003C000000F0000000F00000003C0000000F00000003C0000000F000 +0000380000000E0000000780000001E0000000780000001E000000078000000180191A7D +9620>60 D<C0000000F00000003C0000000F00000003C0000000F0000000380000000E00 +00000780000001E0000000780000001E00000007800000078000001E00000078000001E0 +0000078000000E00000038000000F0000003C000000F0000003C000000F0000000C00000 +00191A7D9620>62 D<01FC00FF80001C001C00002E001800002E001000002E0010000027 +00100000470020000043002000004380200000438020000081C040000081C040000081C0 +40000080E040000100E08000010070800001007080000100708000020039000002003900 +00020039000002001D000004001E000004000E000004000E00000C000E00001C00040000 +FF80040000211C7E9B21>78 D<01C003C003C001800000000000000000000000001C0027 +0047004700870087000E000E001C001C001C003800388038807080710032001C000A1C7E +9B0E>105 D E /Fn 190[21 14[15 15 49[{ TeXBase1Encoding ReEncodeFont }3 +29.166667 /Times-Roman rf /Fo 64[18 29[14 12[18 18 24[18 +21 21 30 21 21 12 16 14 21 21 21 21 32 12 21 12 12 21 +21 14 18 21 18 21 18 3[14 1[14 1[30 30 39 30 30 25 23 +28 30 23 30 30 37 25 30 16 14 30 30 23 25 30 28 28 30 +38 18 3[12 12 21 21 21 21 21 21 21 21 21 21 12 10 14 +10 23 1[14 14 14 3[21 31[23 23 2[{ TeXBase1Encoding ReEncodeFont }82 +41.666669 /Times-Roman rf /Fp 3 127 df<00800100020006000C000C0018001800 +3000300030006000600060006000E000E000E000E000E000E000E000E000E000E000E000 +E0006000600060006000300030003000180018000C000C000600020001000080092A7C9E +10>40 D<8000400020003000180018000C000C0006000600060003000300030003000380 +038003800380038003800380038003800380038003800300030003000300060006000600 +0C000C00180018003000200040008000092A7E9E10>I<1C043F0843F080E00E047D9B15> +126 D E /Fq 136[30 1[23 12 21 1[23 23 23 23 35 9 3[23 +23 1[23 1[21 23 21[23 17[12 10[12 12 4[14 14 40[{ + TeXBase1Encoding ReEncodeFont }21 41.666669 /Helvetica +rf /Fr 134[25 1[36 1[28 17 19 22 1[28 25 28 41 14 2[14 +1[25 17 22 28 22 1[25 8[36 50 36 1[33 1[36 39 1[39 1[47 +33 2[19 3[33 2[33 36 7[25 25 25 1[25 1[25 25 25 25 1[12 +1[12 41[28 2[{ TeXBase1Encoding ReEncodeFont }42 50.000001 +/Times-Bold rf /Fs 137[21 23 14 16 18 23 1[21 23 35 12 +2[12 23 2[18 23 1[23 21 7[30 23[30 18[10 43[23 2[{ + TeXBase1Encoding ReEncodeFont }20 41.666669 /Times-Bold +rf /Ft 133[27 30 1[43 30 33 20 23 27 33 33 30 33 50 17 +33 1[17 33 30 20 27 33 27 33 30 8[43 60 2[40 33 43 4[56 +40 2[23 47 2[40 3[43 1[30 4[20 30 30 30 30 30 30 30 30 +30 30 3[15 41[33 2[{ TeXBase1Encoding ReEncodeFont }49 +59.999974 /Times-Bold rf /Fu 139[20 4[37 2[17 3[37 27[37 +76[{ TeXBase1Encoding ReEncodeFont }5 59.999974 /Helvetica-Bold +rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 300dpi +TeXDict begin +%%PaperSize: A4 + +%%EndSetup +%%Page: 1 1 +1 0 bop 310 254 a Fu(Ltoh)p Ft(:)17 b(a)e(customizable)e(L)888 +243 y Fs(A)909 254 y Ft(T)939 268 y(E)972 254 y(Xto)i(HTML)f(con)n(v)o +(erter)646 312 y Fr(V)-5 b(ersion)12 b(97e,)h(31)f(Mar)h(1997)726 +370 y(Russell)f(W)-5 b(.)13 b(Quong)607 423 y Fq(\(http://www)n(.best)o +(.c)o(om/)-5 b Fp(~)d Fq(quong/ltoh\))-75 563 y Ft(1)60 +b(Intr)o(oduction)-75 656 y Fq(Ltoh)11 b Fo(is)f(a)i(customizable)e(L) +324 648 y Fn(A)339 656 y Fo(T)357 665 y(E)378 656 y(X)h(to)f(HTML)i +(con)n(v)o(erter)n(.)j(It)10 b(handles)h(te)o(xt,)g(tables,)g(and)g +(hyperte)o(xt)e(links.)14 b Fq(ltoh)d Fo(is)f(a)i(lar)o(ge)f(Perl)f +(script,)-75 706 y(and)j(hence)g(is)g(\(almost)f(completely\))g +(platform)g(independent.)20 b Fq(ltoh)12 b Fo(is)h(customizable)g(in)f +(that)g(you)g(can)h(specify)g(ho)o(w)f(to)g(translate)-75 +755 y(a)h(gi)o(v)o(en)g(L)70 747 y Fn(A)85 755 y Fo(T)103 +765 y(E)124 755 y(X2)p Fm(")f Fo(macro)i(into)e(HTML,)h(including)e +(your)h(o)o(wn)g(personal)h(macros.)21 b(In)13 b(fact,)h(you)e(must)g +(manually)h(specify)f(ho)o(w)h(to)-75 805 y(handle)d(your)g(o)o(wn)f +(macros,)j(otherwise)e Fq(ltoh)g Fo(will)f(gi)o(v)o(e)h(a)h(friendly)e +(warning.)-13 855 y(See)h(the)f Fq(ltoh)f Fo(web)h(page)g(\()p +Fl(http://www.best.com/)-5 b Fp(~)f Fl(quong/ltoh)p Fo(\))8 +b(for)g(documentation,)g(the)h(latest)f(release,)j(and)e(ho)o(w)-75 +905 y(to)h(contact)h(the)g(author)f(\(see)h(the)g(bottom)e(of)i(the)g +(web)g(page\).)k(Naturally)m(,)10 b(the)h(HTML)g(v)o(ersion)g(of)f +(document)h(was)g(generated)g(using)-75 955 y Fq(ltoh)p +Fo(,)k(and)e(in)g(my)g(opinion)f(looks)g(better)h(than)g(the)g(L)713 +946 y Fn(A)728 955 y Fo(T)746 964 y(E)767 955 y(X2)p +Fm(")g Fo(dvi/PS)g(output,)f(mostly)h(due)g(to)g(the)g(e)o(xtra)h +(colors.)22 b(The)14 b(\002rst)f(public)-75 1005 y(release)f(was)e(v)o +(ersion)g(97e)g(on)g(3/31/97.)-13 1054 y Fq(Ltoh)f Fo(has)g(two)f(main) +h(restrictions.)i(First,)e Fq(ltoh)g Fo(does)g Fk(not)g +Fo(handle)f(math)h(equations,)g(which)f(in)h(general)g(are)g(dif)o +(\002cult)f(to)g(display)g(in)-75 1104 y(HTML.)62 1089 +y Fn(1)88 1104 y Fo(Second,)i Fq(ltoh)f Fo(requires)g(La/T)m(e)o(x)h +(macro)g(parameters)g(to)f(be)g(delimited)f(by)g(braces;)i(in)f +(practice,)h Fq(ltoh)f Fo(might)f(be)h(unsuitable)-75 +1154 y(for)h(most)g(e)o(xisting)f(T)234 1163 y(E)255 +1154 y(Xcode.)-13 1204 y(Surprisingly)m(,)f(I)h(often)g(pre)o(vie)o(w)g +(my)h(L)542 1195 y Fn(A)557 1204 y Fo(T)575 1213 y(E)596 +1204 y(X2)p Fm(")f Fo(documents)h(via)f Fq(ltoh)h Fo(instead)f(of)g +(running)f Fl(latex)p Fo(,)h Fl(dvips)p Fo(,)h(and)f +Fl(ghostview)p Fo(.)-75 1344 y Ft(2)60 b(The)14 b(distrib)o(ution)-75 +1436 y Fq(Ltoh)c Fo(is)g(distrib)o(uted)e(as)j(either)f(a)h(zip)f +(\002le)h(\()p Fl(ltoh.zip)p Fo(\))e(or)h(a)h(gzipped)e(tar)i(\002le)f +(\()p Fl(ltoh.tgz)p Fo(\))f(\(about)h(75K\).)-13 1486 +y(Both)f(distrib)o(utions)f(contain)h(the)h(follo)o(wing)e(\002les.)p +-75 1541 1980 2 v -75 1591 2 50 v -48 1576 a(ltoh.pl)p +190 1591 V 155 w(The)j(perl)f(script)g(that)f(does)i(e)o(v)o(erything)p +1903 1591 V -75 1593 1980 2 v -75 1643 2 50 v -48 1628 +a(ltoh.specs)p 190 1643 V 99 w(The)g(default)e(speci\002cations.)p +1903 1643 V -75 1644 1980 2 v -75 1694 2 50 v -48 1679 +a(readme.html)p 190 1694 V 56 w(Generated)i(by)f Fq(ltoh)p +1903 1694 V -75 1696 1980 2 v -75 1746 2 50 v -48 1731 +a Fo(readme.dvi)p 190 1746 V 79 w(L)226 1722 y Fn(A)241 +1731 y Fo(T)259 1740 y(E)280 1731 y(X2)p Fm(")h Fo(output)p +1903 1746 V -75 1747 1980 2 v -75 1797 2 50 v -48 1782 +a(readme.ps)p 190 1797 V 96 w(Uses)g(T)o(imes)g(Roman)p +1903 1797 V -75 1799 1980 2 v -75 1849 2 50 v -48 1834 +a(readme.txt)p 190 1849 V 88 w(T)m(e)o(xt)g(v)o(ersion)f(\(generated)h +(from)f(netscape\))p 1903 1849 V -75 1850 1980 2 v -75 +1900 2 50 v -48 1885 a(README)p 190 1900 V 1903 1900 +V -75 1902 1980 2 v -75 1952 2 50 v -48 1937 a(rq-ltoh.specs)p +190 1952 V 50 w(An)g(e)o(xample)i(of)e(my)g(speci\002cations)p +1903 1952 V -75 1953 1980 2 v -75 2003 2 50 v -48 1988 +a(rq209.sty)p 190 2003 V 107 w(Allo)o(w)f(use)i(of)f(ne)o(w)h(L)529 +1980 y Fn(A)544 1988 y Fo(T)562 1997 y(E)582 1988 y(X2)p +Fm(")g Fo(font)e(commands)i(in)f(old)f(L)1046 1980 y +Fn(A)1061 1988 y Fo(T)1079 1997 y(E)1100 1988 y(X2)p +Fm(")p Fo(.)p 1903 2003 V -75 2005 1980 2 v -75 2115 +a Ft(3)60 b(System)14 b(Softwar)o(e)g(Requir)o(ements)-75 +2208 y Fq(Ltoh)c Fo(v)o(ersion)g(97d)g(requires)g(the)g(follo)o(wing)e +(system)i(software.)-36 2258 y(1.)21 b(A)10 b(unix)f(operating)f +(system.)14 b(I)9 b(ha)o(v)o(e)i(tested)f Fq(ltoh)f Fo(only)g(under)g +(Linux,)h(although)e(there)i(is)f(nothing)f(Linux)h(speci\002c)i(in)e +(the)g(code.)16 2308 y(A)14 b(handful)f(of)h(lines)g(are)h(Unix)e +(dependent)h(mostly)f(in)g(due)h(to)g(\002lename)h(con)n(v)o(entions.) +24 b(Because)16 b Fq(ltoh)e Fo(is)f(written)g(in)h(Perl,)16 +2357 y(almost)c(all)g(the)g(code)h(is)f(platform-independent.)-36 +2407 y(2.)21 b(Perl)11 b(v)o(ersion)f(5.00x,)g(preferably)g(5.002)f(or) +h(higher)n(.)i(Run)828 2457 y Fl(perl)24 b(-v)16 2507 +y Fo(to)10 b(see)h(the)f(v)o(ersion)g(of)g(Perl)h(you)e(ha)o(v)o(e.)-36 +2557 y(3.)21 b(L)26 2548 y Fn(A)41 2557 y Fo(T)59 2566 +y(E)80 2557 y(X2)p Fm(")11 b Fo(macro)h(parameters)g(\(or)f(ar)o +(guments\))g(must)f(be)i(brace)g(delimited)e(\(surrounded)f(by)i +(braces\),)h(because)h Fq(ltoh)e Fo(relies)f(on)16 2607 +y(the)g(braces.)-36 2656 y(4.)21 b(The)11 b Fj(ne)o(w)g(late)o(x)i +Fo(\(L)287 2648 y Fn(A)302 2656 y Fo(T)320 2666 y(E)341 +2656 y(X2)p Fm(")p Fo(\))d(is)g(strongly)f(recommended)i(o)o(v)o(er)g +(the)f Fj(old)g(late)o(x)j Fo(\(L)1190 2648 y Fn(A)1205 +2656 y Fo(T)1223 2666 y(E)1244 2656 y(X2.09\),)16 2706 +y(Additionally)m(,)f(the)h(default)f Fq(ltoh)h Fo(speci\002cations)g +(is)g(based)h(on)f(standard)g(ne)o(w)g(late)o(x)h(macros.)22 +b(Finally)m(,)14 b(to)e(make)i(full)e(use)h(of)16 2756 +y(HTML)g(tables,)g(future)f(v)o(ersions)g(of)g Fq(ltoh)g +Fo(are)i(likely)c(to)i(support)f(multiple)g(ro)o(ws)h(in)f(the)h(table) +h(packages)g(only)e(found)h(in)f(the)16 2806 y(ne)o(w)g(late)o(x.)p +-75 2832 792 2 v -30 2860 a Fi(1)-15 2872 y Fh(Some)d(ha)o(ve)g +(resorted)g(to)h(con)o(verting)d(the)j(latex)f(equations)f(into)i +(Postscript)g(\(PS\),)h(con)o(verting)c(the)j(PS)h(to)f(a)g(bitmapped)e +(\002gure,)i(and)f(the)h(displaying)e(the)i(\002gure)-75 +2911 y(in)f(HTML.)h(This)f(is)h(all)f(too)g(dif)o(\002cult)h(for)f(me.) +905 3036 y Fo(1)p eop +%%Page: 2 2 +2 1 bop -75 253 a Fr(3.1)50 b(If)12 b(y)o(ou)g(must)h(use)f(L)388 +242 y Fg(A)405 253 y Fr(T)430 264 y(E)457 253 y(X2.09)h(instead)e(of)h +(L)826 242 y Fg(A)843 253 y Fr(T)868 264 y(E)895 253 +y(X2)p Ff(")-75 331 y Fq(ltoh)g Fo(relies)g(on)g(unique)f(matching)h +(braces)i(to)d(delimit)g(ar)o(guments)i(to)e(the)h(late)o(x)h(macros.) +19 b(In)12 b(particular)n(,)h(the)f(font)f(family)g(and)h(size)-75 +380 y(commands)f(in)e(old)g(late)o(x)h(do)g(not)f(use)h(braces)h(to)f +(delimit)e(ar)o(guments.)13 b(Thus,)e Fq(ltoh)f Fo(does)g(not)f(\(and)h +(probably)e(ne)o(v)o(er)j(will\))d(handle)i(old)-75 430 +y(late)o(x)h(2.09)f(font)g(speci\002cations.)k(Instead,)d(you)f(must)g +(use)h(the)g(L)870 422 y Fn(A)885 430 y Fo(T)903 440 +y(E)924 430 y(X2)p Fm(")f Fo(con)n(v)o(ention,)h(which)f(delimits)f +(the)i(te)o(xt)f(to)g(be)h(af)o(fected)g(by)g(a)-75 480 +y(font)e(change)i(via)f(braces)i(as)f(sho)o(wn)e(in)h(the)g(follo)o +(wing)e(comparison.)-75 571 y Fl(\(Old)25 b(latex\))f(Normal)g(but)h +(switch)f(\\bf)h(to)g({bold)f(\\it)h(then)f(italics,)g(back)h(to})-75 +621 y(bold)g(\\normalfont)e(then)i(normal.)-75 721 y(\(New)g(latex\))f +(Normal)g(but)h(switch)f(\\textbf{to)g(bold)h(\\textit{then)e(italics,) +i(back)-75 771 y(to})g(bold})f(then)h(normal.)-13 862 +y Fo(Produces:)29 953 y(Normal)10 b(b)o(ut)g(switch)f +Fs(to)h(bold)g Fe(then)h(italics,)e(back)h(to)f Fs(bold)h +Fo(then)g(normal.)-13 1045 y(Using)g(the)g(old)f(late)o(x)i(syntax,)f +Fq(ltoh)g Fo(cannot)g(determine)h(when)f(the)g(bold)f(and)i(italic)e +(fonts)g(stop)h(being)g(acti)o(v)o(e.)-13 1094 y(If)g(you)f(ha)o(v)o(e) +i(the)f(ne)o(w)g(late)o(x)g(on)f(your)g(system,)i(use)f(it.)j(If)c(you) +g(must)h(use)g(an)h(old)e(late)o(x)h(\002le,)g(con)n(v)o(ert)g(it)f(to) +h(look)e(like)h(ne)o(w)h(late)o(x)g(as)-75 1144 y(much)h(as)g +(possible.)-36 1194 y(1.)21 b(Con)n(v)o(ert)c(all)g(font)f(change)i +(macros)g(to)f(use)g(the)g(ne)o(w)h(late)o(x)f(syntax.)34 +b(Namely)m(,)20 b(con)n(v)o(ert)42 b Fd(fn)p Fc(XYZ)25 +b Fl(...)p Fd(g)41 b Fo(and)i Fd(n)p Fc(XYZ)16 1244 y +Fl(...)p Fd(n)p Fl(normalfont)34 b Fo(to)10 b Fd(n)p +Fl(text)p Fc(XYZ)p Fl(...)p Fo(.)-36 1294 y(2.)21 b(Use)11 +b(the)f(style)g(\002le)h Fl(rq209.sty)e Fo(\(which)h(should)f(be\))h +(included)f(with)h(the)g Fq(ltoh)g Fo(distrib)o(ution,)d(which)j +(de\002nes)h(the)f Fd(n)p Fo(te)o(xt)p Fj(XYZ)16 1344 +y Fo(macros)i(for)d(use)i(in)f(the)g(old)f(late)o(x.)16 +1393 y(T)m(o)i(use)f(this)g(\002le,)g(put)755 1460 y +Fd(n)p Fl(input)p Fd(f)p Fl(rq209.sty)p Fd(g)16 1526 +y Fo(in)k(your)f(late)o(x)h(\002les.)25 b(The)15 b(\002le)f +Fl(rq209.sty)f Fo(additionally)f(de\002nes)j(the)f(font)f(size)h +(macros)h Fd(n)p Fl(fsize)p Fc(Tiny)s Fo(/.)6 b(.)g(.)g(/)p +Fd(n)p Fl(fsize)16 1576 y Fc(Huge)k Fo(which)g(take)f(a)i(single)e +(brace-delimited)h(ar)o(gument.)j(F)o(or)d(e)o(xapmle,)i(use)e +Fd(n)p Fl(fsizesmall)p Fd(f)p Fl(some)23 b(text)p Fd(g)10 +b Fo(instead)f(of)16 1626 y Fd(f)25 b(n)p Fl(small)f(some)h(text)f +Fd(g)p Fo(.)16 b(\(This)11 b(author)f(wrote)h Fl(rq209.sty)f +Fo(back)i(in)e(1994)h(because)h(the)f(of)o(\002ce)h(computer)f(ran)g +(the)16 1676 y(old)f(late)o(x)g(b)o(ut)g(the)g(home)h(Linux)e(machine)i +(ran)f(the)h(ne)o(w)f(late)o(x.\))16 1725 y(Alternati)o(v)o(ely)m(,)g +(write)f(and)i(use)f(your)g(o)o(wn)g(de\002nitions)e(of)i(the)h +Fd(n)p Fo(te)o(xt)p Fj(XYZ)j Fo(font)9 b(change)i(macros.)-13 +1775 y(\(One)h(\002nal)f(note.\))16 b(The)11 b(old)g(late)o(x)g(con)n +(v)o(ention)g(is)g(simply)g(a)g(poor)g(technical)g(chioce.)17 +b(The)12 b(current)f(philosophy)d(for)j(document)-75 +1825 y(speci\002cations)j(\(and)h(e)o(v)o(en)g(programming)e +(languages\))h(is)g(that)g(parameters/ar)o(guments/blocks)g(are)h +(clearly)g(delimited)e(syntacti-)-75 1875 y(cally)m(.)g(The)d(use)g(of) +f(matching)g(braces)h(by)f(late)o(x2e)h(conforms)f(to)g(the)g(the)g +(SGML)h(syntax,)f(as)h(does)g(HTML)g(which)e(ubiquitously)f(uses)-75 +1925 y(matching)j(be)o(gin)g(and)g(end)h(tags.)-75 2065 +y Ft(4)60 b(Running)15 b Fu(ltoh)-75 2158 y Fo(T)m(o)10 +b(generate)h(the)f(HTML)h(\002le)g Fl(xyz.html)e Fo(from)h(the)g(late)o +(x)h(\002le)f Fl(xyz.tex)p Fo(,)g(assuming)h(ltoh)e(is)h(in)f(your)h +(path,)g(run:)p -75 2210 1980 2 v -25 2240 a Fl(prompt>)24 +b Fq(ltoh)h Fl(xyz.tex)-75 2290 y(or)-25 2339 y(prompt>)f(perl)h +(fullpath-of-ltoh.pl)e(xyz.tex)p -75 2347 V -13 2419 +a Fo(\(I)12 b(ha)o(v)o(e)h(not)e(tested)h Fq(ltoh)g Fo(on)g(a)h(W)n +(in32)e(machine,)j(yet...\))19 b(On)12 b(a)g(W)n(in32)g(machine,)h +(which)f(cannot)g(automatically)f(start)h(Perl)g(to)-75 +2469 y(e)o(x)o(ecute)g(the)e Fq(ltoh)p Fo(,)h(you)e(would)g(probably)g +(run)p -75 2521 V -25 2551 a Fl(prompt>)24 b(perl)h Fq(ltoh)p +Fl(.pl)f(xyz.tex)p -75 2559 V 905 3036 a Fo(2)p eop +%%Page: 3 3 +3 2 bop -75 253 a Ft(5)60 b(Speci\002cations)-75 346 +y Fo(There)11 b(are)g(\002)o(v)o(e)g(types)f(of)g Fq(ltoh)g +Fo(speci\002cations.)k(Please)d(note)f(the)g(names.)-362 +395 y(Be)o(gin/end)f(pair)h(\()p Fl(b/e)p Fo(\))20 b(Speci\002es)12 +b(ho)o(w)d(to)h(translate)g(a)h(late)o(x)f Fd(n)p Fl(begin)p +Fd(f)p Fl(XYZ)p Fd(g)f Fo(and)i(matching)e Fd(n)p Fl(end)p +Fd(f)p Fl(XYZ)p Fd(g)h Fo(command.)-315 445 y(Command)g(\()p +Fl(comm)p Fo(\))20 b(Speci\002es)12 b(ho)o(w)d(to)h(translate)g(a)h +(late)o(x)f(command)h(that)f(does)h(not)e(take)h(an)o(y)h(parameters,)h +(such)e(as)h Fd(n)p Fl(par)p Fo(,)f Fd(n)p Fl(item)g +Fo(or)g Fd(n)p Fl(hrule)p Fo(.)-319 495 y(Simple-macro)g(\()p +Fd(fg)p Fo(\))20 b(Speci\002es)12 b(a)e(translation)f(for)h(a)g(late)o +(x)h(macro)g(that)f(takes)g(a)h(single)e(brace-delimited)h(ar)o(gument) +g Fj(ar)o(g-1)p Fo(,)h(where)g(the)f(correspond-)16 545 +y(ing)g(HTML)g(consists)g(simply)f(of)h(surrounding)e(the)i(ar)o +(gument)g(with)f(a)i(preamble)f(and)g(postamble.)j(The)e(translation)d +(is)i(simple)16 595 y(as)h(the)f(ar)o(gument)h(stays)f(put;)f +Fq(ltoh)h Fo(merely)h(puts)f(stuf)o(f)f(before)i(and)f(after)g(it.)j +(That)d(is,)g(we)h(e)o(xpect)195 644 y Fd(n)p Fl(simplemacro)p +Fd(f)p Fc(...)p Fd(g)105 b(\000)-6 b(!)82 b Fl(HTML-preable)24 +b Fc(...)50 b Fl(HTML-postable)16 694 y Fo(F)o(or)10 +b(e)o(xample,)h(use)e(a)h(simple-macro)g(speci\002cation)f(to)f +(translate)h(the)g(late)o(x)h(macro)g Fd(n)p Fl(textbf)p +Fd(f)23 b Fl(...)p Fd(g)9 b Fo(\(switch)g(to)f(bold)g(face\))16 +744 y(into)h(the)h(HTML)h Fm(<)p Fl(strong)p Fm(>)25 +b Fl(...)p Fm(<)p Fl(/strong)p Fm(>)p Fo(.)-295 794 y(Ar)o(g-macro)11 +b(\()p Fd(f)p Fc(N)5 b Fd(g)p Fo(\))19 b(Speci\002es)c(a)e(translation) +f(for)h(a)g(late)o(x)h(macro)g(that)f(takes)g Fm(N)18 +b Fo(brace-delimited)13 b(ar)o(guments;)i(the)e(corresponding)e(HTML)j +(can)16 844 y(make)e(arbitrary)e(use)h(of)f(the)h(ar)o(guments.)k(F)o +(or)c(e)o(xample,)i(my)e(late)o(x)g(macro)g Fd(n)p Fl(swallow)p +Fd(f)p Fl(arg-1)p Fd(g)e Fo(discards)i(its)g(single)f(\(pos-)16 +894 y(sibly)f(long\))g(ar)o(gument.)14 b(In)c(the)g(corresponding)f +(HTML,)i(we)g(also)f(\223use\224)i(the)e(ar)o(gument,)h(by)e +(discarding)h(it.)-291 943 y(Assignment)g(\()p Fl(:=)p +Fo(\))20 b(An)13 b(assignment)g(sets)h(a)f Fq(ltoh)g +Fo(v)o(ariable)g(which)g(is)g(then)f(used)i(later)n(.)21 +b(As)13 b(of)g(v)o(ersion)g(97d,)g(only)f(a)i(small)f(number)g(of)g(b)o +(uilt-in)16 993 y(v)o(ariables)e(are)g(supported.)h(I)e(hope)g(to)f +(support)g(setting)g(and)i(getting)e(user)o(-de\002ned)h(v)o(ariables)g +(in)g(the)g(future.)-13 1043 y(The)h(\002rst)f(four)g(specications)g +(are)h(kno)o(wn)e(as)i(translations)e(speci\002cations.)-75 +1161 y Fr(5.1)50 b(T)l(ranslation)12 b(speci\002cations)-75 +1239 y Fo(The)e(four)e(types)h(of)g(translation)e(speci\002cations)i +(ha)o(v)o(e)h(the)f(same)i(form.)h(Do)d(not)f(use)i(leading)e +(whitespace.)13 b(Here)d(is)f(the)g(general)g(form)-75 +1289 y(and)h(an)h(e)o(xample)g(of)f(each)i(type.)-75 +1379 y Fl(:type)74 b(:latex-macro-name:HTML-start-code:HTML-en)o +(d-code:res)o(erved/not-u)o(sed)-75 1478 y(:b/e)99 b +(:\\begin{itemize}:<UL>:</>:)-75 1528 y(:comm)74 b(:\\hrule:<hr>::)-75 +1578 y(+comm)g(+\\homepage+http://www.best.com/\230quong++)-75 +1628 y(:{})124 b(:\\textbf:<STRONG>:</>:)-75 1677 y(:{2})25 +b(:\\rqhttp#1#2:<a)e(href="#2">)h(#1)h(</a>::)-13 1767 +y Fo(Each)12 b(speci\002cation)e(contains)g(six)f(parts.)-36 +1817 y(1.)21 b(The)13 b(\002rst)g(character)g(on)f(the)h(line)f(is)g +(the)g Fj(separator)k Fo(char)n(,)e(which)e(delimits)g(the)g(remaining) +g(parts)g(of)g(the)h(speci\002cation.)19 b(The)16 1866 +y(separator)12 b(char)g(can)h(be)f(an)o(y)g(character)n(.)18 +b(I)12 b(ha)o(v)o(e)h(used)e(a)i(colon)e(\(:\))k(and)c(a)i(plus)e(sign) +f(\(+\))i(in)f(the)h(abo)o(v)o(e)h(e)o(xamples.)18 b(Note)12 +b(that)16 1916 y(the)f Fd(n)p Fl(homepage)f Fo(macro)i(e)o(xpands)f(to) +f(HTML)i(containing)d(a)i(colon,)g(so)g(a)g(colon)f(cannot)h(be)g(the)g +(delimiter)e(and)i(I)g(ha)o(v)o(e)h(used)16 1966 y(a)f(plus.)i(I)d(do)g +(not)f(recommend)i(using)f(a)h(space/tab)f(as)h(the)f(delimiter)n(,)g +(as)h(multiple)e(spaces/tabs)i(are)g(easy)h(to)d(o)o(v)o(erlook.)-36 +2016 y(2.)21 b(The)11 b Fj(type)p Fo(.)h(If)d(the)h(type)f(is)g(ar)o +(g-macro,)i(the)f(number)f(of)h(parameters)g(is)g(speci\002ed)g(in)f +(the)g(braces.)14 b(Arbitrary)9 b(space)h(may)h(follo)o(w)16 +2066 y(the)f(type.)-36 2115 y(3.)21 b(The)11 b Fj(late)o(x)f(macro)h +(name)j Fo(speci\002es)d(the)f(late)o(x)g(macro)h(to)f(be)g +(translated.)j(A)d(late)o(x)g(macro)h(must)f(start)f(with)g(a)i +(backslash)f(\(if)g(you)16 2165 y(ha)o(v)o(e)j(rede\002ned)g(the)f(L) +345 2157 y Fn(A)360 2165 y Fo(T)378 2175 y(E)399 2165 +y(X2)p Fm(")g Fo(catcodes,)i(sorry\).)k(An)12 b(optional)e(Perl)i(re)o +(gular)g(e)o(xpression)g(can)h(follo)o(wing)d(the)i(macro)h(name,)16 +2215 y(to)d(account)g(for)g(parameters)i(for)e(the)g(macro.)k(Usually)9 +b(the)h(late)o(x)h(parameters)g(are)g(just)f(discarded)g(in)g(the)g +(resulting)e(HTML.)16 2265 y(As)17 b(an)f(e)o(xample)i(of)d(an)i +(optional)d(re)o(gular)j(e)o(xpression,)h(the)e(L)965 +2257 y Fn(A)980 2265 y Fo(T)998 2274 y(E)1019 2265 y(X2)p +Fm(")g Fo(horizontal)f(space)i(command)g Fd(n)p Fl(hspace)f +Fo(takes)g(an)16 2315 y(optional)10 b Fl(*)h Fo(ar)o(gument,)g(and)g +(then)g(a)g(required)g(horizontal)e(length)h(ar)o(gument.)16 +b(In)10 b(the)h(generated)h(HTML,)g(we)f(want)g(to)f(ignore)16 +2365 y(the)g(entire)g Fd(n)p Fl(hspace)g Fo(macro,)h(and)g(so)f(I)g +(use)h(the)f(follo)o(wing)e Fq(ltoh)i Fo(spec.)16 2431 +y Fl(:comm)25 b(:\\hspace[*]?\\{[\210\\}]+\\}:::)-36 +2497 y Fo(4.)c(The)11 b Fj(HTML)g(start)f(code)k Fo(is)c(the)g(HTML)h +(code)g(to)f(insert)f(when)h(the)h(macro)g(is)f(\002rst)g(seen.)-172 +2546 y(be)o(gin/end)g(pair)20 b(The)11 b Fd(n)p Fl(beginXXX)e +Fo(e)o(xpands)i(to)f Fj(HTML)h(start)f(code)p Fo(.)-98 +2596 y(command)22 b(The)11 b(L)172 2588 y Fn(A)187 2596 +y Fo(T)205 2606 y(E)226 2596 y(X2)p Fm(")f Fo(macro)h(e)o(xpands)g(to)f +Fj(HTML)h(start)e(code)p Fo(.)-169 2646 y(Simple-macro)21 +b(The)11 b(opening)e(brace)i(e)o(xpands)g(to)f Fj(HTML)h(start)e(code)s +Fo(;)i(the)f(closing)f(brace)j(e)o(xpands)e(to)g Fj(HTML)h(end)f(code)p +Fo(.)-104 2696 y(ar)o(g-macro)22 b(The)11 b(command)g(and)f(all)g(its)g +(ar)o(guments)g(e)o(xpands)h(to)f Fj(HTML)h(start)f(code)p +Fo(.)16 2746 y(In)j(an)g(ar)o(g-macro)h(speci\002cation,)f(using)f(the) +h(L)709 2737 y Fn(A)724 2746 y Fo(T)742 2755 y(E)763 +2746 y(X2)p Fm(")f Fo(con)n(v)o(ention,)i(the)e(\002rst)h(ar)o(gument)g +(is)f(represented)h(by)g(#1,)g(the)g(second)16 2795 y(ar)o(gument)f(by) +f(#2,)h(and)f(so)h(on)f(in)g(the)g(HTML)h(start)f(code.)17 +b(\(T)m(o)11 b(actually)g(generate)h(a)g Fd(n)p Fl(#1)p +Fo(,)g(use)g(braces)h(as)f(in)f(#)p Fd(f)p Fo(1)p Fd(g)p +Fo(.\))k(Thus,)e(a)16 2845 y(macro)e(that)f(swaps)g(the)h(order)f(of)g +(its)f(parameters)j(would)c(be)j(written)e(as)16 2911 +y Fl(:{2})25 b(:\\swap_two:#2#1::)905 3036 y Fo(3)p eop +%%Page: 4 4 +4 3 bop 16 253 a Fo(As)11 b(another)g(e)o(xample,)h(the)f(L)442 +245 y Fn(A)457 253 y Fo(T)475 262 y(E)496 253 y(X2)p +Fm(")g Fd(n)p Fl(makebox)f Fo(command)h(takes)g(an)g(optional)e +(alignment)h(parameter)i(\(one)f(of)f Fl([l])p Fo(,)h +Fl([c])16 303 y Fo(or)h Fl([r])p Fo(\))g(follo)o(wed)e(by)i(te)o(xt)g +(to)f(be)i(put)e(into)g(the)h(box.)17 b(I)12 b(use)h(the)f(follo)o +(wing)d Fq(ltoh)j Fo(spec)h(to)f(ignore)f(the)h(alignment)f(parameter) +16 352 y(and)g(to)e(print)g(the)h(te)o(xt)g(out)g(unadorned.)16 +419 y Fl(:{1})25 b(:\\makebox[\210{]*#1:#1::)-36 485 +y Fo(5.)c(The)14 b Fj(HTML)g(end)f(code)k Fo(speci\002er)c(is)g(the)g +(HTML)h(code)f(to)g(insert)f(at)h Fp(\()p Fm(i)p Fp(\))h +Fo(the)f(end)g(of)g(a)g(be)o(gin-end)g(pair)f(or)h Fp(\()p +Fm(ii)p Fp(\))h Fo(the)f(closing)16 535 y(brace)d(of)e(a)h +(simple-macro.)k(Note)8 b(that)g(the)g Fj(HTML)h(end)f(code)k +Fo(speci\002er)e(does)e(not)g(make)h(sense)g(for)f(a)h +Fj(command)14 b Fo(or)8 b Fj(ar)o(g-macro)16 585 y Fo(speci\002cation)j +(and)f(is)g(ignored.)16 635 y(As)g(a)g(con)n(v)o(enience,)h(using)e +Fm(<)p Fl(/)p Fm(>)h Fo(in)f(the)g Fj(HTML)i(end)e(code)k +Fo(e)o(xpands)d(to)f(the)h(end)f(tag\(s\))g(in)g(re)o(v)o(erse)i(order) +e(of)g(the)h(correspond-)16 685 y(ing)h(HTML)g(be)o(gin)g(code.)17 +b(F)o(or)11 b(e)o(xample,)i(I)e(want)f(a)i(L)803 676 +y Fn(A)818 685 y Fo(T)836 694 y(E)857 685 y(X2)p Fm(")f +Fd(n)p Fl(section)f Fo(to)h(sho)o(w)g(up)f(as)i(a)g(green)f(\241H2\277) +h(header)f(in)g(HTML,)16 734 y(so)g(I)f(specify)16 801 +y Fl(:{})25 b(:\\section:<hr><H2><FONT)e(color=green>:</>:)16 +867 y Fo(which)10 b(is)g(equi)o(v)o(alent)f(to)16 934 +y Fl(:{})25 b(:\\section:<hr><H2><FONT)e +(color=green>:</FONT></H2></HR>:)-13 1017 y Fo(The)11 +b(follo)o(wing)d(table)i(summarizes)i(the)e(ef)o(fects)h(of)f(the)g(v)o +(arious)f(speci\002cations,)i(and)f(the)h(parts)f(of)g(the)g +(spe\002cations)g(used.)p 12 1080 2 50 v 39 1065 a Fl(Type)p +163 1080 V 51 w(macro)24 b(name)p 476 1080 V 64 w(HTML)g(start)p +777 1080 V 51 w(HTML)h(end)p 1028 1080 V 1079 1080 V +1089 1080 V 113 w(input)p 1688 1080 V 474 w(output)p +1989 1080 V 12 1081 1979 2 v 12 1131 2 50 v 39 1116 a(comm)p +163 1131 V 51 w Fd(n)p Fl(abc)p 476 1131 V 217 w(XYZ)p +777 1131 V 225 w(not-used)p 1028 1131 V 1079 1131 V 1089 +1131 V 113 w Fd(n)p Fl(abc)p 1688 1131 V 503 w(XZY)p +1989 1131 V 12 1133 1979 2 v 12 1183 2 50 v 39 1168 a(b/e)p +163 1183 V 76 w Fd(n)p Fl(begin)p Fd(f)p Fl(abc)p Fd(g)p +476 1183 V 50 w Fl(XYZ)p 777 1183 V 225 w(ijk)p 1028 +1183 V 1079 1183 V 1089 1183 V 238 w Fd(n)p Fl(begin)p +Fd(f)p Fl(abc)p Fd(g)p Fl(...)p Fd(n)p Fl(end)p Fd(f)p +Fl(abc)p Fd(g)p 1688 1183 V 48 w Fl(XZY)g(...ijk)p 1989 +1183 V 12 1184 1979 2 v 12 1234 2 50 v 39 1219 a Fd(fg)p +163 1234 V 109 w(n)p Fl(abc)p 476 1234 V 217 w(XYZ)p +777 1234 V 225 w(ijk)p 1028 1234 V 1079 1234 V 1089 1234 +V 238 w Fd(n)p Fl(abc)p Fd(f)p Fl(...)p Fd(g)p 1688 1234 +V 386 w Fl(XYZ...ijk)p 1989 1234 V 12 1236 1979 2 v 12 +1285 2 50 v 39 1271 a Fd(f)p Fl(2)p Fd(g)p 163 1285 V +84 w(n)p Fl(abc)p 476 1285 V 217 w(X#2Y#1Z)p 777 1285 +V 125 w(not-used)p 1028 1285 V 1079 1285 V 1089 1285 +V 113 w Fd(n)p Fl(abc)p Fd(f)p Fl(===)p Fd(gf)p Fl(+++)p +Fd(g)p 1688 1285 V 269 w Fl(X+++Y===Z)p 1989 1285 V 12 +1287 1979 2 v -13 1341 a Fo(As)11 b(a)h(\002nal)e(e)o(xample,)j(here')n +(s)e(ho)o(w)f(generate)i(links)d(in)h(HTML.)i(I)f(de\002ne)g(a)h(late)o +(x)f(macro)g Fd(n)p Fl(rqhttp)g Fo(and)f(a)i(corresponding)d +Fq(ltoh)-75 1391 y Fo(spec\002ciation.)14 b(Because)e(the)f(tilde)e(is) +i(accessible)h(only)d(in)h(math)h(mode,)g(I)g(ha)o(v)o(e)h(had)e(to)g +(de\002ne)h(a)h(late)o(x)e(macro)i(\()p Fd(n)p Fl(rqtilde)p +Fo(\))d(for)i(it,)-75 1441 y(too.)p -75 1484 1980 2 v +-75 1511 a Fl(\(latex)24 b(macro\))-75 1560 y Fd(n)p +Fl(def)p Fd(n)p Fl(rqtilde)p Fd(fn)p Fl(ensuremath)p +Fd(fn)p Fl(ti)o(lde)p Fd(fn)p Fl(;)p Fd(g)o(gn)p Fl(xspac)o(e)p +Fd(g)-75 1610 y(n)p Fl(def)p Fd(n)p Fl(rqhttp#1#2)p Fd(f)p +Fl(#1)f(\()p Fd(n)p Fl(texttt)p Fd(f)p Fl(#2)p Fd(g)p +Fl(\))p Fd(g)-75 1660 y Fl(\()p Fq(ltoh)50 b Fl(spec\))-75 +1710 y(:comm)24 b(:)p Fd(n)p Fl(rqtilde:\230::)-75 1760 +y(:2)h(:)p Fd(n)p Fl(rqhttp#1#2:<a)e(href="#2">)h(#1)h(</a>::)p +-75 1772 V -13 1844 a Fo(In)10 b(L)42 1836 y Fn(A)57 +1844 y Fo(T)75 1854 y(E)96 1844 y(X2)p Fm(")p Fo(,)h(I)f(use)h(the)f +Fd(n)p Fl(rqhttp)f Fo(macro)j(as)f(follo)o(ws.)29 1936 +y(See)g(the)f Fd(n)p Fo(rqhttp)p Fd(fn)p Fo(lto)o(h)e(webpage)p +Fd(gf)p Fo(http://www)m(.best.com/)p Fd(n)p Fo(rqti)o(ld)o(e)p +Fd(fg)p Fo(quon)o(g/l)o(toh)o Fd(g)p Fo(.)-13 2027 y(The)j(resulting)e +(dvi)g(output)g(from)h(late)o(x)g(and)h(the)f(HTML)h(from)f +Fq(ltoh)g Fo(look)f(like)p -75 2079 V -25 2106 a Fl(\(Latex\))24 +b(See)h(the)f(ltoh)h(web)f(page)h +(\(http://www.best.com/\230quong/ltoh\).)-25 2205 y(\(HTML\))f(See)h +(the)f(<A)h(HREF="http://www.best.com/\230quong/ltoh">)c(ltoh)k(web)g +(page)f(</A>)p -75 2213 V -75 2256 V -13 2286 a Fo(Finally)m(,)9 +b(good)e(e)o(xample)j(of)e(using)g Fq(ltoh)h Fo(speci\002ers)g(is)g +(the)f(default)g Fq(ltoh)g Fo(spec)i(\002le)f Fl(ltoh.specs)e +Fo(that)h(comes)i(with)e(this)f(release.)-13 2336 y([Aside:)21 +b(T)m(echnically)m(,)16 b(the)e Fl(simple-macro)g Fo(speci\002er)h(is)f +(not)g(needed,)i(as)g(its)d(functionality)f(can)j(be)g(duplicated)e +(with)h(an)-75 2386 y Fl(arg-macro)p Fo(.)e(Namely)m(,)-75 +2469 y Fl(:{})99 b(:\\macro:HTML-begin:HTML-end::)-13 +2552 y Fo(can)11 b(be)g(duplicated)e(via)-75 2643 y Fl(:{1})99 +b(:\\macro:HTML-begin#1HTML-end:::.)-13 2735 y Fo(Nonetheless,)15 +b(use)f(of)f(a)i(simple-macro)f Fd(f)f(g)h Fo(speci\002ction)f(is)g +(preferred,)i(because)g(its)e(processing)h(is)f(much)h(simpler)n(.)22 +b(W)n(ith)14 b(a)-75 2784 y(simple-macro,)i Fq(ltoh)e +Fo(does)g(not)g(ha)o(v)o(e)h(to)f(e)o(xtract)g(and)g(pass)h(the)f +(parameter)n(,)j(and)d(hence)h(it)f(is)g(less)g(likely)f(to)g(break)i +(than)e(an)i(ar)o(g-)-75 2834 y(macro.])905 3036 y(4)p +eop +%%Page: 5 5 +5 4 bop -75 253 a Fr(5.2)50 b(Assignment)-75 331 y Fo(An)12 +b(assignment)f(speci\002cation)h(has)g(two)f(nearly)h(identical)f +(forms.)17 b(The)c(double)e(quotes)g(are)i(optional)d(and)h(can)i(be)f +(used)g(to)f(imbed)-75 380 y(leading)f(spaces)h(into)e(the)h(string-v)o +(alue.)i(The)f(whitespace)g(surrounding)d(string-v)o(alue)g(is)i(remo)o +(v)o(ed.)p -75 433 1980 2 v -25 460 a Fl(variable-name)24 +b(:=)g(string-value)-25 510 y(variable-name)g(:=)g("string-value")-25 +610 y(title)g(:=)h(The)g(readme)f(for)h(ltoh)p -75 612 +V -13 682 a Fo(Here)11 b(are)g(the)f(currently)g(used)g(b)o(uilt-in)e +(v)o(ariables.)p -13 696 V -13 746 2 50 v 14 731 a(v)o(ariable)p +353 746 V 232 w(Default)p 653 746 V 176 w(Description)p +1966 746 V -13 748 1980 2 v -13 897 2 150 v 14 783 a +Fl(title)p 353 897 V 240 w(none)p 653 897 V 201 w Fo(T)o(itle)44 +b(of)i(the)f(resulting)f(HTML)j(\002le,)55 b(via)45 b(the)h +Fm(<)p Fl(TITLE)p Fm(>)g Fo(tag.)680 833 y Fs(Y)-5 b(ou)10 +b(must)g(de\002ne)i(this)e(variable.)p 680 840 525 2 +v 22 w Fo(Set)23 b Fl(title)f Fo(in)g(the)h(late)o(x)g(\002le)g +(itself.)50 b(\(It)680 882 y(dri)o(v)o(es)10 b(me)h(nuts)f(when)g(web)g +(pages)h(don')o(t)f(ha)o(v)o(e)h(titles\))p 1966 897 +2 150 v -13 899 1980 2 v -13 949 2 50 v 14 934 a Fl(url)p +353 949 V 290 w(none)p 653 949 V 201 w Fo(URL)f(of)g(the)g(home)h(page) +f(of)g(the)h(author)n(.)p 1966 949 V -13 950 1980 2 v +-13 1000 2 50 v 14 985 a Fl(author)p 353 1000 V 215 w(none)p +653 1000 V 201 w Fo(Author)e(of)h(the)g(document.)p 1966 +1000 V -13 1002 1980 2 v -13 1052 2 50 v 14 1037 a Fl(email)p +353 1052 V 240 w(none)p 653 1052 V 201 w Fo(Email)g(address)h(to)f +(which)g(comments)h(should)e(be)h(sent)p 1966 1052 V +-13 1053 1980 2 v -13 1153 2 100 v 14 1088 a Fl(htmlfile)p +216 1088 13 2 v 14 w(spec)p 353 1153 2 100 v 51 w($BASE.html)p +653 1153 V 51 w Fo(Name)15 b(of)f(HTML)h(\002le)g(generated.)26 +b(The)15 b Fq(ltoh)f Fo(v)o(ariable)h Fl($BASE)f Fo(is)g(the)g(late)o +(x)h(\002le)680 1138 y(name)c(stripped)e(of)h(the)g(directory)f(and)i +(suf)o(\002x)f(components.)p 1966 1153 V -13 1155 1980 +2 v -13 1187 a(The)j Fl(url)p Fo(,)f Fl(author)p Fo(,)h(and)f +Fl(email)f Fo(v)o(ariables)h(are)h(used)f(to)f(generate)i(an)f(address) +h(block)e(at)h(the)g(bottom)e(of)i(the)g(HTML)g(page.)-75 +1237 y(\(See)f(the)f(bottom)f(of)h(this)g(document)g(if)f(you)h(are)h +(reading)f(it)f(on)h(the)g(web\).)-75 1377 y Ft(6)60 +b(T)-5 b(ables)-75 1470 y Fq(ltoh)13 b Fo(handles)f(the)h(L)218 +1462 y Fn(A)233 1470 y Fo(T)251 1479 y(E)272 1470 y(X2)p +Fm(")g Fl(tabular)f Fo(and)h Fl(tabularx)f Fo(en)n(vironments.)20 +b(Column)11 b(alignments)h(are)i(read)f(and)g(passed)h(onto)d(the)-75 +1520 y(corresponding)i(HTML.)j(The)g(kno)o(wn)e(column)g(alignments)g +(must)h(be)g(one)g(of)f(\223)h(l)g(c)g(r)g(p)f(X\224.)i(If)f(you)f +(de\002ne)h(your)f(o)o(wn)g(column)-75 1569 y(alignment,)c(it)f(will)g +(not)h(be)g(understood.)-13 1619 y Fq(ltoh)j Fo(handles)g(the)f(L)280 +1611 y Fn(A)295 1619 y Fo(T)313 1629 y(E)334 1619 y(X2)p +Fm(")h Fl(multicolumn)f Fo(macro)i(reasonably)f(well.)20 +b(The)13 b(column)g(alignment)f(is)g(read)i(and)f(passed)g(onto)-75 +1669 y(the)d(corresponding)f(HTML.)-13 1719 y(I)h(plan)g(to)g(support)f +(the)h Fd(n)p Fl(multirow)f Fo(macro)j(soon.)-13 1769 +y Fq(ltoh)c Fo(ignores)f(e)o(xtraneous)h(L)389 1760 y +Fn(A)404 1769 y Fo(T)422 1778 y(E)443 1769 y(X2)p Fm(")g +Fo(specs)h(in)e(the)h(column)f(alignment)g(speci\002cations,)i(such)f +(as)608 b(,)-75 1819 y(b)o(ut)10 b(there)g(is)g(a)h(small)f(chance)i(a) +f(complicated)f(multiple)f(column)h(alignment)f(spec)i(will)e(break)i +(this)e(code.)-13 1868 y(The)h(generated)f(HTML)g(table)f(has)i(a)f +(border)f(if)g(one)h(or)f(more)h(di)o(viding)d(lines)i(in)g(the)h(L) +1239 1860 y Fn(A)1254 1868 y Fo(T)1272 1878 y(E)1293 +1868 y(X2)p Fm(")f Fo(table)h(column)f(alignment)g(\(namely)-75 +1918 y(if)j(a)i Fd(j)f Fo(speci\002er)g(appears)h(in)f(the)g(late)o(x,) +h(the)e(HTML)i(table)f(has)g(a)h(border\).)18 b(Nested)12 +b(tables)g(are)h(not)e(supported,)h(and)g(I)g(currently)e(do)-75 +1968 y(not)f(plan)h(to)g(support)f(them,)i(as)g(this)e(feature)i(seems) +g(hard.)-75 2108 y Ft(7)60 b(Wher)o(e)13 b(ar)o(e)h(speci\002cations)g +(f)o(ound?)-75 2201 y Fo(As)d(of)f(v)o(ersion)g(97d,)h +Fq(ltoh)f Fo(reads)i(speci\002cations)e(from)h Fp(\()p +Fm(i)p Fp(\))g Fo(v)o(arious)f(speci\002cation-\002les)h(and)f +Fp(\()p Fm(ii)p Fp(\))i Fo(from)e(the)h(L)1545 2193 y +Fn(A)1560 2201 y Fo(T)1578 2210 y(E)1598 2201 y(X2)p +Fm(")g Fo(\002le)g(itself)f(as)h(it)-75 2251 y(is)f(being)g(processed,) +h(as)g(follo)o(ws.)-36 2300 y(1.)21 b(Reads)9 b(the)g(speci\002cation)f +(\002le)h Fl(ltoh.specs)f Fo(from)g(the)g Fl(install-dir)p +Fo(,)h(which)f(is)g(the)h(directory)e(where)i(you)f(ha)o(v)o(e)i +(placed)16 2350 y(both)g Fl(ltoh.pl)f Fo(and)i Fl(ltoh.specs)p +Fo(.)h(The)f Fl(install-dir)e Fo(can)i(be)g(an)o(ywhere.)16 +2400 y(\(In)f(v)o(ersion)g(97d,)g(you)g(should)f(do)h(one)g(of)g(the)g +(follo)o(wing)e(when)i(running)f Fq(ltoh)p Fo(.)20 2450 +y(\(a\))21 b(Run)9 b Fq(ltoh)i Fo(via:)87 2500 y Fl(prompt)p +Fm(>)25 b Fl(perl)f(install-dir/ltoh.pl)f(file.tex)p +Fo(.)18 2550 y(\(b\))d(Set)10 b(up)g(an)h(alias)f(as)h(follo)o(ws:)87 +2599 y(\(csh\))f Fl(alias)25 b(ltoh)f(perl)h(install-dir/ltoh)87 +2649 y Fo(or)87 2699 y(\(bash\))10 b Fl(alias)24 b(ltoh=perl)h +(install-dir/ltoh)20 2749 y Fo(\(c\))c(Put)10 b Fl(install-dir)f +Fo(in)h(your)f(path,)h(and)h(run:)87 2799 y Fl(prompt)p +Fm(>)25 b Fl(ltoh.pl)f(file.tex)905 3036 y Fo(5)p eop +%%Page: 6 6 +6 5 bop 18 253 a Fo(\(d\))20 b(Set)8 b(up)f(a)i(single)e(symbolic)g +(link,)g(say)h(called)g Fl(ltoh)p Fo(,)h(in)e(your)g(path)g(which)h +(points)e(directly)h(to)g Fl(install-dir/ltoh.pl)p Fo(.)87 +303 y(Y)-5 b(ou)10 b(can)h(then)f(run)87 352 y Fl(prompt)p +Fm(>)25 b Fl(ltoh)f(file.tex)16 402 y Fo(This)11 b(mess)g(is)g(relati)o +(v)o(e)f(symbolic)g(links.)j(Y)l(es.)h(Gi)o(v)o(en)c(an)h(arbitrary)f +(in)n(v)o(ocation)f(of)h Fq(ltoh)h Fo(in)n(v)o(olving)d(symbolic)i +(links,)g(I)g(cannot)16 452 y(currently)k(determine)h(where)g(the)g +Fl(ltoh.pl)f Fo(script)g(actually)h(resides)g(\(the)g +Fl(install-dir)p Fo(\).)25 b(Once)16 b(I)f(implement)f(this)16 +502 y(code,)d(the)g(setup)f(won')o(t)f(be)h(complicated.)-36 +552 y(2.)21 b(Reads)11 b(the)f(speci\002cation)g(\002le)h +Fl(.ltoh.specs)e Fo(in)h(your)f(home)i(directory)m(.)-36 +602 y(3.)21 b(Reads)11 b(the)f(speci\002cation)g(\002le)h +Fl(.ltoh.specs)e Fo(in)h(the)g(current)g(directory)m(,)g(where)h(the)f +(command)h(is)f(being)g(run.)-36 651 y(4.)21 b(If)10 +b(an)o(y)h(of)f(these)h(speci\002cation)f(\002les)g(e)o(xist,)h +Fq(ltoh)f Fo(proceeds)h(to)f(the)g(ne)o(xt)g(step)g(reading)g(the)g(L) +1366 643 y Fn(A)1381 651 y Fo(T)1399 661 y(E)1420 651 +y(X2)p Fm(")h Fo(input)d(\002le)16 701 y(Ho)o(we)o(v)o(er)n(,)k(if)e +(none)g(of)g(the)g(preceding)g(spec)h(\002les)g(were,)g +Fq(ltoh)f Fo(tries)g(to)g(read)16 751 y Fl(/usr/local/bin/ltoh.specs)i +Fo(and)h(that)g(fails,)h(tries)f Fl(/usr/bin/ltoh.specs)p +Fo(.)20 b(If)14 b(both)e(of)h(these)h(still)e(fail,)16 +801 y Fq(ltoh)f Fs(quits)p 94 816 88 2 v -1 w Fo(.)-36 +851 y(5.)21 b(Reads)11 b(speci\002cations)g(from)f(the)g(late)o(x)g +(\002le)h(being)e(processed,)j(which)d(appear)i(as)g(late)o(x)g +(comments)g(of)f(the)g(form)591 900 y Fl(\045-ltoh-)24 +b Fc(ltoh-specification)16 950 y Fo(.)16 1000 y Fq(ltoh)11 +b Fo(strips)e(the)h(leading)g Fl(\045-ltoh-)34 b Fo(and)11 +b(processes)g(the)f(remainder)h(of)f(the)g(line.)16 1050 +y(If)g(nothing)f(else,)i(set)f(the)g Fl(title)g Fo(v)o(ariable)g(this)g +(way)m(.)j(F)o(or)e(e)o(xample,)g(here')n(s)g(ho)o(w)f(this)f(L)1331 +1042 y Fn(A)1346 1050 y Fo(T)1364 1059 y(E)1385 1050 +y(X2)p Fm(")h Fo(\002le)h(starts.)16 1116 y Fl +(\\documentclass[]{article})16 1166 y(...)25 b(various)f(latex)h +(commands)f(like)g(\\usepackage)16 1216 y(\045-ltoh-)74 +b(title)25 b(:=)g(Ltoh,)f(a)h(customizable)f(LaTeX)g(to)h(HTML)f +(converter)16 1266 y(\045-ltoh-)74 b(:comm:\\ltoh:<font)24 +b(color=green><tt>ltoh</tt></font>::)16 1316 y(...)16 +1365 y(\\begin{document})16 1415 y(...)h(the)g(body)f(of)h(the)f +(document)-75 1555 y Ft(8)60 b(Limitations,)13 b(b)o(ugs,)i(missing)g +(featur)o(es)-75 1656 y Fr(8.1)50 b(Limitations)-36 1734 +y Fo(1.)21 b(Speci\002cations)12 b(are)g(applied)f(only)f(once)i(to)f +(a)h(late)o(x)f(macro.)18 b(Namely)12 b(if)e(a)i(macro)h +Fj(macroAA)j Fo(generates)d(a)f(macro)g Fj(macroBB)16 +1784 y Fo(in)f(late)o(x,)g(and)g Fj(macroBB)16 b Fo(is)11 +b(translated)f(to)h Fj(htmlBB)p Fo(,)e(then)i(you)f(must)h(specify)g +(to)f Fq(ltoh)h Fo(that)g Fj(macroAA)16 b Fo(is)11 b(translated)f +(directly)16 1834 y(to)g Fj(htmlBB)j Fo(in)d(your)g(speci\002cation)g +(for)g Fj(macroAA)p Fo(.)-75 1953 y Fr(8.2)50 b(Bugs)-75 +2030 y Fo(It)10 b(is)g(not)f(dif)o(\002cult)g(to)h(break)g +Fq(ltoh)p Fo(,)h(though)e(there)h(are)h(often)f(easy)h(\002x)o(es)g(by) +f(restructuring)e(your)i(L)1355 2022 y Fn(A)1370 2030 +y Fo(T)1388 2040 y(E)1409 2030 y(X2)p Fm(")p Fo(.)-75 +2149 y Fr(8.3)50 b(Missing)13 b(featur)o(es)-36 2227 +y Fo(1.)21 b(There)12 b(are)f(no)e(command)j(line)d(\003ags.)14 +b(The)d(follo)o(wing)d(would)g(be)j(particularly)e(useful.)p +16 2242 970 2 v 16 2292 2 50 v 43 2277 a(-o)h Fj(o\002le)p +236 2292 V 100 w Fo(generate)h(HTML)g(into)e(\002le)i +Fj(o\002le)p 984 2292 V 16 2293 970 2 v 16 2343 2 50 +v 43 2328 a Fo(-I)f Fj(spec\002le)p 236 2343 V 55 w Fo(read)h +(speci\002cations)g(from)f Fj(spec\002le)p 984 2343 V +16 2345 970 2 v 16 2395 2 50 v 43 2380 a Fo(-w)g(N)p +236 2395 V 135 w(set)h(the)f(warning)f(le)o(v)o(el)h(to)g(N)g(\(for)g +(deb)o(ugging\))p 984 2395 V 16 2396 970 2 v -36 2429 +a(2.)21 b(There)12 b(no)d(means)j(to)e(manipulate)f(counters,)i(which)f +(would)e(be)j(useful)f(for)f(sectioning)h(commands.)-36 +2479 y(3.)21 b(There)12 b(should)d(be)h(a)o(way)h(to)f(set)g(and)h(get) +f(a)g(v)o(alue)h(as)g(part)f(of)g(a)g(speci\002cation.)-36 +2528 y(4.)21 b(If)10 b(the)g(input)f(uses)i(L)303 2520 +y Fn(A)318 2528 y Fo(T)336 2538 y(E)357 2528 y(X2)p Fm(")f +Fo(sectioning)f(macros,)j(optionally)c(generate)j(a)f(table)h(of)f +(contents)f(with)g(links)h(to)f(anchors.)-36 2578 y(5.)21 +b(Allo)o(w)9 b(for)h(an)h(abitrary)e(prologue)g(and)i(epilogue)e(in)h +(the)g(HTML)h(\002le.)-36 2628 y(6.)21 b(In)10 b(a)g(table,)g(we)g +(assume)h(that)e(the)g(column)h(alignment)f(specs)h(are)h(on)e(the)g +(same)i(line)e(as)i(the)e(o)o(wning)g Fd(n)p Fl(begin)p +Fd(f)p Fl(tabular)p Fd(g)e Fo(or)16 2678 y(the)j(o)o(wning)f +Fd(n)p Fl(multicolumn)p Fo(.)j(This)e(assumption)g(is)g(v)o(ery)h +(reasonable)f(and)h(circumv)o(enting)e(this)h(restriction)e(is)i(dif)o +(\002cult.)905 3036 y(6)p eop +%%Page: 7 7 +7 6 bop -75 253 a Ft(9)60 b(Inter)o(nal)14 b(details)-75 +346 y Fq(Ltoh)c Fo(\002rst)g(reads)h(the)g(entire)f(L)366 +337 y Fn(A)381 346 y Fo(T)399 355 y(E)420 346 y(X2)p +Fm(")g Fo(\002le)h(into)e(memory)m(,)i(makes)h(se)o(v)o(eral)f(passes)h +(o)o(v)o(er)f(the)f(data,)h(and)f(\002nally)g(spits)g(out)f(the)h(HTML) +-75 395 y(\002le)-22 380 y Fn(2)5 395 y Fo(The)h(passes)g(are)g +(roughly)e(as)i(follo)o(ws.)-36 445 y(1.)21 b(Read)11 +b(spec)g(\002les.)-36 495 y(2.)21 b(Handle)11 b(comments)g(and)f(the)g +(v)o(erbatim)g(en)n(vironment.)-36 545 y(3.)21 b(Escape/protect)11 +b(characters.)-36 595 y(4.)21 b(Handle)11 b(tables.)-36 +644 y(5.)21 b(Handle)11 b(be)o(gin/end)e(pairs.)-36 694 +y(6.)21 b(Handle)11 b(L)157 686 y Fn(A)172 694 y Fo(T)190 +704 y(E)210 694 y(X2)p Fm(")g Fo(commands)g(without)d(parameters.)-36 +744 y(7.)21 b(Mark)11 b(braces,)g(linking)d(braces)k(to)d(macros.)-36 +794 y(8.)21 b(Handle)11 b(simple)f(macros.)-36 844 y(9.)21 +b(Handle)11 b(ar)o(g)f(macros.)-56 894 y(10.)20 b(Generate)12 +b(HTML.)-75 1034 y Ft(10)60 b(History)p -75 1095 1980 +2 v -75 1194 2 100 v -48 1129 a Fo(June)10 b(1996)p 246 +1194 V 151 w(V)-5 b(ersion)10 b(96a.)15 b(Preliminary)9 +b(fully)g(hard-coded)i(\(not)e(customizable\))i(v)o(ersion.)j(Purely)c +(re)o(gular)h(e)o(xpression)273 1179 y(based.)j(Unable)c(to)g(handle)g +(nested)g(braces.)k(Ugly)m(,)c(b)o(ut)g(it)f(worked.)j(Sort)e(of.)p +1903 1194 V -75 1196 1980 2 v -75 1296 2 100 v -48 1231 +a(July)f(1-15)h(1996)p 246 1296 V 71 w(V)-5 b(ersion)15 +b(96b)n(.)29 b(First)15 b(working)e(v)o(ersion.)29 b(Able)15 +b(to)g(handle)h(commands)g(with)f(multiple)f(ar)o(guments)h(and)273 +1281 y(nested)10 b(ar)o(guments.)k(T)m(ook)9 b(me)i(a)g(lot)f(longer)f +(than)h(I)g(had)g(e)o(xpected)i(to)d(get)h(this)g(working.)p +1903 1296 V -75 1297 1980 2 v -75 1397 2 100 v -48 1332 +a(Jan)g(27-29)g(1997)p 246 1397 V 64 w(V)-5 b(ersion)10 +b(97a.)k(Stops)c(processing)g(at)h Fd(n)p Fl(end)p Fd(f)p +Fl(document)p Fd(g)p Fo(.)h(Con)n(v)o(ert)e(double)g(back)h(slashes)g +Fd(nn)p Fo(to)f Fm(<)p Fl(br)p Fm(>)p Fo(,)273 1382 y(which)g(should)f +(ha)o(v)o(e)i(done)f(a)h(long)e(time)h(ago.)j(Fix)o(ed)e(b)o(ug)f(in)n +(v)o(olving)e(macros)j(with)e(only)g(one)i(parameter)n(.)p +1903 1397 V -75 1398 1980 2 v -75 1448 2 50 v -48 1433 +a(Feb)f(1997)p 246 1448 V 165 w(V)-5 b(ersion)10 b(97b)n(.)j(Added)d +(HTML)h Fm(<)p Fl(p)p Fm(>)g Fo(tags)f(whene)o(v)o(er)h(two)e(or)h +(more)h(consecuti)o(v)o(e)g(blank)e(lines)h(are)h(seen.)p +1903 1448 V -75 1450 1980 2 v -75 1699 2 250 v -48 1485 +a(Mar)f(11-15)f(1997)p 246 1699 V 51 w(V)-5 b(ersion)10 +b(97c.)15 b(Much)c(impro)o(v)o(ed)f(handling)f(of)i(special)g +(characters)h(such)f(as)g Fd(f)p Fo(,)g Fd(g)p Fo(,)g +Fm(<)p Fo(,)h Fm(>)f Fo(and)g(@.)k(In)10 b(partic-)273 +1535 y(ular)n(,)h(bare)h(braces)g(which)e(mean)i(nothing)d(in)h(late)o +(x)h(are)h(stripped)e(from)h(the)f(HTML.)i(Impro)o(v)o(ed)f(paragraph) +273 1584 y(detection)f(handling.)k(\(OK,)d(OK,)g(\224Impro)o(v)o(ed)h +(.)6 b(.)g(.)g(\224)13 b(really)e(means)h(\224\002x)o(ed)g(b)o(ugs)e +(in)g(.)c(.)g(.)g(\224\).)18 b(No)11 b(longer)f(gen-)273 +1634 y(erates)h(HTML)f(comments)h(for)e(late)o(x)h(comments,)h(by)f +(default.)i(V)-5 b(ersion)9 b(97c)h(was)g(meant)h(to)e(be)h(\002rst)g +(public)273 1684 y(release,)i(b)o(ut)d(the)i(tables)f(this)f +Fl(readme.tex)h Fo(document)g(broke)f Fq(ltoh)h Fo(badly)m(.)p +1903 1699 V -75 1701 1980 2 v -75 2000 2 299 v -48 1736 +a(Mar)g(19-20)f(1997)p 246 2000 V 51 w(V)-5 b(ersion)18 +b(97d.)36 b(Complete)18 b(re)o(write)g(of)g(the)g(table)g(handling)e +(code.)38 b(Late)o(x)19 b(column)f(alignment)f(spec-)273 +1785 y(i\002cations)g(are)i(understood)e(and)h(passed)h(onto)e(to)h +(the)g(HTML.)h(Multiple)d(columns)i(speci\002ed)h(via)f(ei-)273 +1835 y(ther)12 b Fd(n)p Fl(multicolumn)f Fo(or)h Fd(n)p +Fl(mc)g Fo(\(which)g(is)g(my)h(personal)f(abbre)o(viation)f(macro\))i +(are)g(handled)f(properly)m(.)273 1885 y(W)m(e)k(try)e(to)h(ignore)g(e) +o(xtraneous)g(L)778 1877 y Fn(A)793 1885 y Fo(T)811 1894 +y(E)832 1885 y(X2)p Fm(")h Fo(specs)g(in)f(the)g(column)g(alignment)g +(speci\002cations,)i(such)e(as)i Fl(@)273 1935 y Fo(.)c(,)e(b)o(ut)e +(there)i(is)f(there)g(is)g(a)h(small)f(chance)i(multiple)d(columns)273 +1985 y(In)h(particular)n(,)g Fq(ltoh)g Fo(no)o(w)g(handles)g(this)g +(\002le)g(\()p Fl(readme.tex)p Fo(\))f(properly)m(.)p +1903 2000 V -75 2001 1980 2 v -75 2151 2 150 v -48 2036 +a(Mar)h(25-31)f(1997)p 246 2151 V 51 w(V)-5 b(ersion)12 +b(97e.)20 b(Of)o(\002cial)12 b(release.)21 b(Clean)12 +b(up)g(source)h(a)g(bit)f(for)g(release.)20 b(Minor)12 +b(impro)o(v)o(ements)h(on)f(tables)273 2086 y(\(allo)o(w)e(end)h(of)g +(a)g(ro)o(w)g(to)f(be)i(on)e(a)i(separate)g(line\),)f(paragraphs,)g +(speci\002cation)g(\002les)h(and)f(handling)e(special)273 +2136 y(characters)i(\(allo)o(w)f(for)g(multiple)e(chars)j(on)f(one)h +(line\).)p 1903 2151 V -75 2152 1980 2 v -75 2263 a Ft(11)60 +b(License)13 b(f)o(or)h(use)-75 2356 y Fo(Y)-5 b(ou)10 +b(may)h(use)g Fq(ltoh)f Fo(freely)m(,)h(under)f(the)g(follo)o(wing)e +(conditions,)h(which)g(are)i(co)o(v)o(ered)h(under)e(a)h(BSD-style)e +(license.)-36 2406 y(1.)21 b(Y)-5 b(ou)14 b(must)g(keep)g(the)g +Fq(ltoh)g Fo(notice)f(at)h(the)g(end)g(of)f(all)h(generated)g(HTML.)h +(This)f(notice)f(indicates)h(ho)o(w)f(the)h(document)g(was)16 +2455 y(generated)f(\(namely)m(,)h(with)d Fq(ltoh)p Fo(\))i(and)f(has)h +(a)g(link)e(to)h(the)h Fq(ltoh)f Fo(web)h(page.)20 b(Y)-5 +b(ou)13 b(may)g(reduce)g(the)f(size)h(of)f(the)h(notice)f(if)g(you)16 +2505 y(wish,)e(b)o(ut)g(it)g(must)g(remain)g(in)g(your)f(document)i +(and)f(visible.)-36 2555 y(2.)21 b Fq(Ltoh)10 b Fo(comes)i(with)d +(neither)h(a)h(warranty)e(nor)h(a)h(gaurantee)f(about)g(its)f +(correctness,)j(performance,)f(or)f(suitability)e(for)h(an)o(y)i(task.) +-36 2605 y(3.)21 b(If)13 b(you)g(modify)f(or)h(redistrib)o(ute)e +Fq(ltoh)p Fo(,)k(you)d(must)h(keep)h(the)f(current)g(disclaimer)g(and)g +(license)h(with)e(the)h Fq(ltoh)g Fo(source)h(which)16 +2655 y(must)c(be)h(visible)e(upon)g(startup,)h(unless)g(you)-36 +2704 y(4.)21 b(I,)11 b(Russell)f(Quong,)f(retain)h(the)g(copyright)e +(for)i Fq(ltoh)p Fo(.)p -75 2740 792 2 v -30 2768 a Fi(2)-15 +2780 y Fh(Thus,)e(it)h(is)f(concei)o(v)o(able)e(that)i +Fb(ltoh)i Fh(might)e(run)g(out)f(of)h(memory)f(if)i(processing)d(a)i +(huge)f(L)1037 2774 y Fi(A)1050 2780 y Fh(T)1064 2787 +y(E)1081 2780 y(X2)p Fa(")i Fh(\002le)f(on)g(a)g(machine)f(with)h +(limited)g(memory)n(.)905 3036 y Fo(7)p eop +%%Page: 8 8 +8 7 bop -75 253 a Fr(11.1)50 b(Of\002cial)11 b(softwar)o(e)h(license) +-75 331 y Fo(Here')n(s)f(the)f(of)o(\002cial)g(license)g(as)h(of)f(31)g +(Mar)h(97.)-75 422 y Fl(#)25 b(Copyright)f(\(c\))h(1996,)f(1997)g +(Russell)h(W)g(Quong.)-75 472 y(#)-75 522 y(#)g(In)g(the)f(following,)g +(the)h("author")f(refers)g(to)h("Russell)f(Quong.")-75 +571 y(#)-75 621 y(#)h(Permission)f(to)h(use,)f(copy,)g(modify,)h +(distribute,)f(and)g(sell)h(this)f(software)g(and)-75 +671 y(#)h(its)f(documentation)g(for)h(any)f(purpose)h(is)f(hereby)h +(granted)f(without)g(fee,)h(provided)-75 721 y(#)g(that)f(the)h +(following)f(conditions)g(are)h(met:)-75 771 y(#)g(1.)g +(Redistributions)e(of)i(source)f(code)h(must)f(retain)h(the)f(above)h +(copyright)-75 820 y(#)100 b(notice,)24 b(this)g(list)h(of)g +(conditions)f(and)g(the)h(following)f(disclaimer.)-75 +870 y(#)h(2.)g(All)f(advertising)g(materials)g(mentioning)g(features)g +(or)h(use)g(of)f(this)h(software)-75 920 y(#)100 b(must)24 +b(display)g(the)h(following)f(acknowledgement:)-75 970 +y(#)149 b(This)25 b(product)f(includes)g(software)g(developed)h(by)f +(Russell)g(Quong.)-75 1020 y(#)h(3.)g(All)f(HTML)h(generated)f(by)g +(ltoh)h(must)g(retain)f(a)h(visible)f(notice)g(that)h(it)-75 +1070 y(#)100 b(was)24 b(generated)g(by)h(ltoh)f(and)h(contain)f(a)h +(link)g(to)f(the)h(ltoh)g(web)f(page)-75 1119 y(#)-75 +1169 y(#)h(Any)f(or)h(all)g(of)g(these)f(provisions)g(can)h(be)f +(waived)h(if)f(you)h(have)f(specific,)-75 1219 y(#)h(prior)f +(permission)g(from)h(the)f(author.)-75 1269 y(#)-75 1319 +y(#)h(THE)f(SOFTWARE)h(IS)f(PROVIDED)g("AS-IS")h(AND)f(WITHOUT)h +(WARRANTY)f(OF)g(ANY)h(KIND,)-75 1368 y(#)g(EXPRESS,)f(IMPLIED)g(OR)h +(OTHERWISE,)f(INCLUDING)g(WITHOUT)g(LIMITATION,)g(ANY)-75 +1418 y(#)h(WARRANTY)f(OF)h(MERCHANTABILITY)e(OR)i(FITNESS)f(FOR)h(A)g +(PARTICULAR)f(PURPOSE.)-75 1468 y(#)-75 1518 y(#)h(IN)g(NO)f(EVENT)h +(SHALL)f(RUSSELL)g(QUONG)h(BE)g(LIABLE)f(FOR)h(ANY)f(SPECIAL,)-75 +1568 y(#)h(INCIDENTAL,)f(INDIRECT)g(OR)h(CONSEQUENTIAL)e(DAMAGES)i(OF)f +(ANY)h(KIND,)f(OR)h(ANY)-75 1618 y(#)g(DAMAGES)f(WHATSOEVER)g +(RESULTING)g(FROM)h(LOSS)f(OF)h(USE,)f(DATA)h(OR)g(PROFITS,)-75 +1667 y(#)g(WHETHER)f(OR)h(NOT)f(ADVISED)h(OF)f(THE)h(POSSIBILITY)f(OF)h +(DAMAGE,)f(AND)g(ON)h(ANY)-75 1717 y(#)g(THEORY)f(OF)h(LIABILITY,)f +(ARISING)g(OUT)h(OF)f(OR)h(IN)g(CONNECTION)f(WITH)g(THE)h(USE)g(OR)-75 +1767 y(#)g(PERFORMANCE)f(OF)g(THIS)h(SOFTWARE.)-75 1907 +y Ft(12)60 b(Moti)o(v)o(ation)-75 2000 y Fo(\(The)14 +b(moti)o(v)o(ation)d(section)h(belongs)h(right)e(after)j(the)f +(introduction,)e(b)o(ut)h(most)h(people)g(probably)f(just)g(want)h(to)f +(get)h(on)g(with)f(using)-75 2050 y Fq(ltoh)p Fo(.)h(So)d(this)g +(section)g(has)g(been)h(rele)o(gated)g(here.)j(Ah)c(well...\))-13 +2099 y(Although)d(other)i(L)258 2091 y Fn(A)273 2099 +y Fo(T)291 2109 y(E)312 2099 y(X2)p Fm(")g Fo(to)f(HTML)i(con)n(v)o +(erters)g(e)o(xist,)g(I)f(wrote)g(my)g(o)o(wn)f(because)j(I)e(wanted)g +(to)f(generate)i(HTML)g(customized)-75 2149 y(to)f(my)g(o)o(wn)g +(liking.)i(In)d(particular)n(,)i(I)f(use)h(my)f(o)o(wn)g(custom)g(L)819 +2141 y Fn(A)834 2149 y Fo(T)852 2159 y(E)873 2149 y(X2)p +Fm(")g Fo(de\002nitions)f(\(who)h(doesn')o(t?\))j(and)d(wanted)g(to)f +(generate)i(HTML)-75 2199 y(appropriately)m(.)i(Additionally)l(,)c +(when)h(using)g(other)f(con)n(v)o(erters,)j(I)e(was)h(unable)f(get)g +(them)h(to)f(run)f(properly)m(,)h(or)g(I)h(did)e(not)h(like)f(the)h +(way)-75 2249 y(the)h(generated)h(HTML)g(looked.)-13 +2299 y(Fundamentally)m(,)h Fq(ltoh)f Fo(is)g(a)h(specialized)g(macro)g +(processor)f(that)g(reads)h(macro)g Fj(speci\002cations)i +Fo(and)d(generates)i(HTML)f(accord-)-75 2349 y(ingly)m(.)g(A)e +(speci\002cation)g(indicates)g(ho)o(w)g(to)g(con)n(v)o(ert)g(a)h +(speci\002c)g(L)881 2340 y Fn(A)896 2349 y Fo(T)914 2358 +y(E)935 2349 y(X2)p Fm(")g Fo(de\002nition)d(into)h(HTML.)-13 +2398 y(My)h(or)o(ginal)g(goals)g(in)f(writing)g Fq(ltoh)h +Fo(were)-36 2448 y(1.)21 b(T)m(o)11 b(become)g(more)g(pro\002cient)e +(in)h(Perl.)-36 2498 y(2.)21 b(T)m(o)11 b(write)e(a)i(con)n(v)o(erter)g +(that)e(allo)o(wed)h(customized)h(HTML)g(to)e(be)i(generated.)-36 +2548 y(3.)21 b(T)m(o)10 b(handle)g(arbitrary)f(L)353 +2539 y Fn(A)368 2548 y Fo(T)386 2557 y(E)407 2548 y(X2)p +Fm(")i Fo(macros,)g(including)d(macros)j(that)f(take)g(multiple)f(ar)o +(guments,)h(and)h(ar)o(guments)f(that)g(contained)16 +2598 y(nested)h(macros.)-36 2647 y(4.)21 b(T)m(o)16 b(generate)h(HTML)g +(that)e(resembled)i(the)f(original)e(L)853 2639 y Fn(A)868 +2647 y Fo(T)886 2657 y(E)907 2647 y(X2)p Fm(")p Fo(,)k(as)e(if)g +(someone)h(had)f(done)f(the)h(translation)f(by)g(hand.)30 +b(In)16 2697 y(particular)n(,)10 b(I)f(wanted)f(to)h(a)o(v)o(oid)f +(generating)h(v)o(ery)g(long)f(lines)h(of)g(HTML)g(source,)i(which)d +(are)i(dif)o(\002cult)e(to)g(read)i(when)f(\223vie)o(wing)16 +2747 y(the)h(source\224)i(in)d(a)i(bro)o(wser)n(.)905 +3036 y(8)p eop +%%Page: 9 9 +9 8 bop -75 253 a Ft(13)60 b(Ackno)o(wledgements)-75 +346 y Fo(Thanks)11 b(to)e(V)-6 b(A)11 b(Research)g(\()p +Fl(http://www.varesearch.com)p Fo(\))d(for)i(letting)e(the)j(author)e +(work)g(on)h Fq(ltoh)p Fo(.)905 3036 y(9)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/support/ltoh/readme.txt b/support/ltoh/readme.txt new file mode 100644 index 0000000000..1ddf740d32 --- /dev/null +++ b/support/ltoh/readme.txt @@ -0,0 +1,634 @@ + Ltoh: a customizable LaTeX to HTML converter + + Version 97e, 31 Mar 1997 + + Russell W. Quong + + (http://www.best.com/~quong/ltoh) + +---------------------------------------------------------------------------- + +Introduction + +Ltoh is a customizable LaTeX to HTML converter. It handles text, tables, and +hypertext links. ltoh is a large Perl script, and hence is (almost +completely) platform independent. ltoh is customizable in that you can +specify how to translate a given LaTeX2e macro into HTML, including your own +personal macros. In fact, you must manually specify how to handle your own +macros, otherwise ltoh will give a friendly warning. + +See the ltoh web page for documentation, the latest release, and how to +contact the author (see the bottom of the web page). Naturally, the HTML +version of document was generated using ltoh, and in my opinion looks better +than the LaTeX2e dvi/PS output, mostly due to the extra colors. The first +public release was version 97e on 3/31/97. + +Ltoh has two main restrictions. First, ltoh does not handle math equations, +which in general are difficult to display in HTML. [Some have resorted to +converting the latex equations into Postscript (PS), converting the PS to a +bitmapped figure, and the displaying the figure in HTML. This is all too +difficult for me.] Second, ltoh requires La/Tex macro parameters to be +delimited by braces; in practice, ltoh might be unsuitable for most existing +TeX code. + +Surprisingly, I often preview my LaTeX2e documents via ltoh instead of +running latex, dvips, and ghostview. + +---------------------------------------------------------------------------- + +The distribution + +Ltoh is distributed as either a zip file or a gzipped tar file (about 75K). + +Both distributions contain the following files. + + ltoh.pl The perl script that does everything + ltoh.specs The default specifications. + readme.html Generated by ltoh + readme.dvi LaTeX2e output + readme.ps Uses Times Roman + readme.txt Text version (generated from netscape) + README + rq-ltoh.specs An example of my specifications + rq209.sty Allow use of new LaTeX2e font commands in old LaTeX2e. + +---------------------------------------------------------------------------- + +System Software Requirements + +Ltoh version 97e requires the following system software. + + 1. A unix operating system. I have tested ltoh only under Linux, although + there is nothing Linux specific in the code. A handful of lines are + Unix dependent mostly in due to filename conventions. Because ltoh is + written in Perl, almost all the code is platform-independent. + + 2. Perl version 5.00x, preferably 5.002 or higher. Run + + perl -v + + to see the version of Perl you have. + + 3. LaTeX2e macro parameters (or arguments) must be brace delimited + (surrounded by braces), because ltoh relies on the braces. + + 4. The new latex (LaTeX2e) is strongly recommended over the old latex + (LaTeX 2.09), + + Additionally, the default ltoh specifications is based on standard new + latex macros. Finally, to make full use of HTML tables, future versions + of ltoh are likely to support multiple rows in the table packages only + found in the new latex. + +If you must use LaTeX 2.09 instead of LaTeX2e + +ltoh relies on unique matching braces to delimit arguments to the latex +macros. In particular, the font family and size commands in old latex do not +use braces to delimit arguments. Thus, ltoh\ does not (and probably never +will) handle old latex 2.09 font specifications. Instead, you must use the +LaTeX2e convention, which delimits the text to be affected by a font change +via braces as shown in the following comparison. + +(Old latex) Normal but switch \bf to {bold \it then italics, back to} +bold \normalfont then normal. + +(New latex) Normal but switch \textbf{to bold \textit{then italics, back +to} bold} then normal. + +Produces: + + Normal but switch to bold then italics, back to bold then normal. + +Using the old latex syntax, ltoh cannot determine when the bold and italic +fonts stop being active. + +If you have the new latex on your system, use it. If you must use an old +latex file, convert it to look like new latex as much as possible. + + 1. Convert all font change macros to use the new latex syntax. Namely, + convert {\XYZ ... } and \XYZ ... \normalfont to \ textXYZ.... + + 2. Use the style file rq209.sty (which should be) included with the ltoh + distribution, which defines the \textXYZ macros for use in the old + latex. + + To use this file, put + \input{rq209.sty} + + in your latex files. The file rq209.sty additionally defines the font + size macros \fsizeTiny/.../\fsize Huge which take a single + brace-delimited argument. For exapmle, use \fsizesmall{some text} + instead of { \small some text }. (This author wrote rq209.sty back in + 1994 because the office computer ran the old latex but the home Linux + machine ran the new latex.) + + Alternatively, write and use your own definitions of the \ textXYZ font + change macros. + +(One final note.) The old latex convention is simply a poor technical +chioce. The current philosophy for document specifications (and even +programming languages) is that parameters/arguments/blocks are clearly +delimited syntactically. The use of matching braces by latex2e conforms to +the the SGML syntax, as does HTML which ubiquitously uses matching begin and +end tags. + +---------------------------------------------------------------------------- + +Running ltoh + +To generate the HTML file xyz.html from the latex file xyz.tex, assuming +ltoh is in your path, run: + + prompt> ltoh xyz.tex +or + prompt> perl fullpath-of-ltoh.pl xyz.tex + +(I have not tested ltoh on a Win32 machine, yet...) On a Win32 machine, +which cannot automatically start Perl to execute the ltoh, you would +probably run + + prompt> perl ltoh.pl xyz.tex + +---------------------------------------------------------------------------- + +Specifications + +There are five types of ltoh specifications. Please note the names. + + 1. [Begin/end pair (b/e)] Specifies how to translate a latex \begin{XYZ} + and matching \end{XYZ} command. + + 2. [Command (comm)] Specifies how to translate a latex command that does + not take any parameters, such as \par, \item or \hrule. + + 3. [Simple-macro ({})] Specifies a translation for a latex macro that + takes a single brace-delimited argument arg-1, where the corresponding + HTML consists simply of surrounding the argument with a preamble and + postamble. The translation is simple as the argument stays put; ltoh + merely puts stuff before and after it. That is, we expect + + \simplemacro{...} ===> HTML-preable ... HTML-postable + + For example, use a simple-macro specification to translate the latex + macro \textbf{ ... } (switch to bold face) into the HTML <strong> ... + </strong>. + + 4. [Arg-macro ({N})] Specifies a translation for a latex macro that takes + $N$ brace-delimited arguments; the corresponding HTML can make + arbitrary use of the arguments. For example, my latex macro + \swallow{arg-1} discards its single (possibly long) argument. In the + corresponding HTML, we also ``use'' the argument, by discarding it. + + 5. [Assignment (:=)] An assignment sets a ltoh variable which is then used + later. As of version 97e, only a small number of built-in variables are + supported. I hope to support setting and getting user-defined variables + in the future. + +The first four specications are known as translations specifications. + +Translation specifications + +The four types of translation specifications have the same form. Do not use +leading whitespace. Here is the general form and an example of each type. + +:type :latex-macro-name:HTML-start-code:HTML-end-code:reserved/not-used + +:b/e :\begin{itemize}:<UL>:</>: +:comm :\hrule:<hr>:: ++comm +\homepage+http://www.best.com/~quong++ +:{} :\textbf:<STRONG>:</>: +:{2} :\rqhttp#1#2:<a href="#2"> #1 </a>:: + +Each specification contains six parts. + + 1. The first character on the line is the separator char, which delimits + the remaining parts of the specification. The separator char can be any + character. I have used a colon (:) and a plus sign (+) in the above + examples. Note that the \homepage macro expands to HTML containing a + colon, so a colon cannot be the delimiter and I have used a plus. I do + not recommend using a space/tab as the delimiter, as multiple + spaces/tabs are easy to overlook. + + 2. The type. If the type is arg-macro, the number of parameters is + specified in the braces. Arbitrary space may follow the type. + + 3. The latex macro name specifies the latex macro to be translated. A + latex macro must start with a backslash (if you have redefined the + LaTeX2e catcodes, sorry). An optional Perl regular expression can + following the macro name, to account for parameters for the macro. + Usually the latex parameters are just discarded in the resulting HTML. + + As an example of an optional regular expression, the LaTeX2e horizontal + space command \hspace takes an optional * argument, and then a required + horizontal length argument. In the generated HTML, we want to ignore + the entire \hspace macro, and so I use the following ltoh spec. + + :comm :\hspace[*]?\{[^\}]+\}::: + + 4. The HTML start code is the HTML code to insert when the macro is first + seen. + + 1. [begin/end pair] The \beginXXX expands to HTML start code. + 2. [command] The LaTeX2e macro expands to HTML start code. + 3. [Simple-macro] The opening brace expands to HTML start code; the + closing brace expands to HTML end code. + 4. [arg-macro] The command and all its arguments expands to HTML + start code. + + In an arg-macro specification, using the LaTeX2e convention, the first + argument is represented by #1, the second argument by #2, and so on in + the HTML start code. (To actually generate a \#1, use braces as in + #{1}.) Thus, a macro that swaps the order of its parameters would be + written as + + :{2} :\swap_two:#2#1:: + + As another example, the LaTeX2e \makebox command takes an optional + alignment parameter (one of [l], [c] or [r]) followed by text to be put + into the box. I use the following ltoh spec to ignore the alignment + parameter and to print the text out unadorned. + + :{1} :\makebox[^{]*#1:#1:: + + 5. The HTML end code specifier is the HTML code to insert at $(i)$ the end + of a begin-end pair or $(ii)$ the closing brace of a simple-macro. Note + that the HTML end code specifier does not make sense for a command or + arg-macro specification and is ignored. + + As a convenience, using </> in the HTML end code expands to the end + tag(s) in reverse order of the corresponding HTML begin code. For + example, I want a LaTeX2e \section to show up as a green <H2> header in + HTML, so I specify + + :{} :\section:<hr><H2><FONT color=green>:</>: + + which is equivalent to + + :{} :\section:<hr><H2><FONT color=green>:</FONT></H2></HR>: + +The following table summarizes the effects of the various specifications, +and the parts of the spefications used. + + Type macro name HTML HTML end input output + start + comm \abc XYZ not-used \abc XZY + b/e \begin{abc} XYZ ijk \begin{abc}...\end{abc} XZY ... ijk + {} \abc XYZ ijk \abc{...} XYZ... ijk + {2} \abc X#2Y#1Z not-used \abc{===}{+++} X+++Y===Z + +As a final example, here's how generate links in HTML. I define a latex +macro \rqhttp and a corresponding ltoh specficiation. Because the tilde is +accessible only in math mode, I have had to define a latex macro (\rqtilde) +for it, too. + +(latex macro) +\def\rqtilde{\ensuremath{\tilde{\;}}\xspace} +\def\rqhttp#1#2{#1 (\texttt{#2})} +(ltoh spec) +:comm :\rqtilde:~:: +:2 :\rqhttp#1#2:<a href="#2"> #1 </a>:: + +In LaTeX2e, I use the \rqhttp macro as follows. + + See the \rqhttp{\ltoh + webpage}{http://www.best.com/\rqtilde{}quong/ltoh}. + +The resulting dvi output from latex and the HTML from ltoh look like + + (Latex) See the ltoh web page (http://www.best.com/~quong/ltoh). + + (HTML) See the <A HREF="http://www.best.com/~quong/ltoh"> ltoh web page </A> + +---------------------------------------------------------------------------- + +Finally, good example of using ltoh specifiers is the default ltoh spec file +ltoh.specs that comes with this release. + +[Aside: Technically, the simple-macro specifier is not needed, as its +functionality can be duplicated with an arg-macro. Namely, + +:{} :\macro:HTML-begin:HTML-end:: + +can be duplicated via + +:{1} :\macro:HTML-begin#1HTML-end:::. + +Nonetheless, use of a simple-macro { } specifiction is preferred, because +its processing is much simpler. With a simple-macro, ltoh does not have to +extract and pass the parameter, and hence it is less likely to break than an +arg-macro.] + +Assignment + +An assignment specification has two nearly identical forms. The double +quotes are optional and can be used to imbed leading spaces into the +string-value. The whitespace surrounding string-value is removed. + + variable-name := string-value + variable-name := "string-value" + + title := The readme for ltoh + +Here are the currently used built-in variables. + + variable Default Description + Title of the resulting HTML file, via the + title none <TITLE> tag. You must define this variable. Set + title in the latex file itself. (It drives me + nuts when web pages don't have titles) + url none URL of the home page of the author. + author none Author of the document. + email none Email address to which comments should be sent + Name of HTML file generated. The ltoh variable + htmlfile_spec $BASE.html $BASE is the latex file name stripped of the + directory and suffix components. + +The url, author, and email variables are used to generate an address block +at the bottom of the HTML page. (See the bottom of this document if you are +reading it on the web). + +---------------------------------------------------------------------------- + +Tables + +ltoh handles the LaTeX2e tabular and tabularx environments. Column +alignments are read and passed onto the corresponding HTML. The known column +alignments must be one of `` l c r p X''. If you define your own column +alignment, it will not be understood. + +ltoh handles the LaTeX2e multicolumn macro reasonably well. The column +alignment is read and passed onto the corresponding HTML. + +I plan to support the \multirow macro soon. + +ltoh ignores extraneous LaTeX2e specs in the column alignment +specifications, such as \@, but there is a small chance a complicated +multiple column alignment spec will break this code. + +The generated HTML table has a border if one or more dividing lines in the +LaTeX2e table column alignment (namely if a $|$ specifier appears in the +latex, the HTML table has a border). Nested tables are not supported, and I +currently do not plan to support them, as this feature seems hard. + +---------------------------------------------------------------------------- + +Where are specifications found? + +As of version 97e, ltoh reads specifications from $(i)$ various +specification-files and $(ii)$ from the LaTeX2e file itself as it is being +processed, as follows. + + 1. Reads the specification file ltoh.specs from the install-dir, which is + the directory where you have placed both ltoh.pl and ltoh.specs. The + install-dir can be anywhere. + + (In version 97e, you should do one of the following when running ltoh. + 1. Run ltoh via: + + prompt> perl install-dir/ltoh.pl file.tex. + + 2. Set up an alias as follows: + + (csh) alias ltoh perl install-dir/ltoh + or + (bash) alias ltoh=perl install-dir/ltoh + + 3. Put install-dir in your path, and run: + + prompt> ltoh.pl file.tex + + 4. Set up a single symbolic link, say called ltoh, in your path which + points directly to install-dir/ltoh.pl. You can then run + + prompt> ltoh file.tex + + This mess is relative symbolic links. Yes. Given an arbitrary + invocation of ltoh involving symbolic links, I cannot currently + determine where the ltoh.pl script actually resides (the install-dir). + Once I implement this code, the setup won't be complicated. + + 2. Reads the specification file .ltoh.specs in your home directory. + 3. Reads the specification file .ltoh.specs in the current directory, + where the command is being run. + + 4. If any of these specification files exist, ltoh proceeds to the next + step reading the LaTeX2e input file + + However, if none of the preceding spec files were, ltoh tries to read + + /usr/local/bin/ltoh.specs and that fails, tries /usr/bin/ltoh.specs. If + both of these still fail, ltoh quits. + + 5. Reads specifications from the latex file being processed, which appear + as latex comments of the form + + %-ltoh- ltoh-specification + + . + + ltoh strips the leading %-ltoh- and processes the remainder of the + line. + + If nothing else, set the title variable this way. For example, here's + how this LaTeX2e file starts. + + \documentclass[]{article} + ... various latex commands like \usepackage + %-ltoh- title := Ltoh, a customizable LaTeX to HTML converter + %-ltoh- :comm:\ltoh:<font color=green><tt>ltoh</tt></font>:: + ... + \begin{document} + ... the body of the document + +---------------------------------------------------------------------------- + +Limitations, bugs, missing features + +Limitations + + 1. Specifications are applied only once to a latex macro. Namely if a + macro macroAA generates a macro macroBB in latex, and macroBB is + translated to htmlBB, then you must specify to ltoh that macroAA is + translated directly to htmlBB in your specification for macroAA. + +Bugs + +It is not difficult to break ltoh, though there are often easy fixes by +restructuring your LaTeX2e. + +Missing features + + 1. There are no command line flags. The following would be particularly + useful. + + -o ofile generate HTML into file ofile + -I specfile read specifications from specfile + -w N set the warning level to N (for debugging) + + 2. There no means to manipulate counters, which would be useful for + sectioning commands. + + 3. There should be away to set and get a value as part of a specification. + + 4. If the input uses LaTeX2e sectioning macros, optionally generate a + table of contents with links to anchors. + + 5. Allow for an abitrary prologue and epilogue in the HTML file. + + 6. In a table, we assume that the column alignment specs are on the same + line as the owning \begin{tabular} or the owning \multicolumn. This + assumption is very reasonable and circumventing this restriction is + difficult. + +---------------------------------------------------------------------------- + +Internal details + +Ltoh first reads the entire LaTeX2e file into memory, makes several passes +over the data, and finally spits out the HTML file[Thus, it is conceivable +that ltoh might run out of memory if processing a huge LaTeX2e file on a +machine with limited memory.] The passes are roughly as follows. + + 1. Read spec files. + 2. Handle comments and the verbatim environment. + 3. Escape/protect characters. + 4. Handle tables. + 5. Handle begin/end pairs. + 6. Handle LaTeX2e commands without parameters. + 7. Mark braces, linking braces to macros. + 8. Handle simple macros. + 9. Handle arg macros. + 10. Generate HTML. + +---------------------------------------------------------------------------- + +History + + June Version 96a. Preliminary fully hard-coded (not customizable) + 1996 version. Purely regular expression based. Unable to handle nested + braces. Ugly, but it worked. Sort of. + July Version 96b. First working version. Able to handle commands with + 1-15 multiple arguments and nested arguments. Took me a lot longer than + 1996 I had expected to get this working. + Jan Version 97a. Stops processing at \end{document}. Convert double + 27-29 back slashes \\to <br>, which should have done a long time ago. + 1997 Fixed bug involving macros with only one parameter. + Feb Version 97b. Added HTML <p> tags whenever two or more consecutive + 1997 blank lines are seen. + Version 97c. Much improved handling of special characters such as + {, }, <, > and @. In particular, bare braces which mean nothing in + Mar latex are stripped from the HTML. Improved paragraph detection + 11-15 handling. (OK, OK, "Improved ..." really means "fixed bugs in + 1997 ..."). No longer generates HTML comments for latex comments, by + default. Version 97c was meant to be first public release, but the + tables this readme.tex document broke ltoh badly. + Version 97d. Complete rewrite of the table handling code. Latex + column alignment specifications are understood and passed onto to + the HTML. Multiple columns specified via either \multicolumn or + Mar \mc (which is my personal abbreviation macro) are handled + 19-20 properly. We try to ignore extraneous LaTeX2e specs in the column + 1997 alignment specifications, such as @. , but there is there is a + small chance multiple columns + + In particular, ltoh now handles this file (readme.tex) properly. + + Mar Version 97e. Official release. Clean up source a bit for release. + 25-31 Minor improvements on tables (allow end of a row to be on a + 1997 separate line), paragraphs, specification files and handling + special characters (allow for multiple chars on one line). + +---------------------------------------------------------------------------- + +License for use + +You may use ltoh freely, under the following conditions, which are covered +under a BSD-style license. + + 1. You must keep the ltoh notice at the end of all generated HTML. This + notice indicates how the document was generated (namely, with ltoh) and + has a link to the ltoh web page. You may reduce the size of the notice + if you wish, but it must remain in your document and visible. + + 2. Ltoh comes with neither a warranty nor a gaurantee about its + correctness, performance, or suitability for any task. + + 3. If you modify or redistribute ltoh, you must keep the current + disclaimer and license with the ltoh source which must be visible upon + startup, unless you + + 4. I, Russell Quong, retain the copyright for ltoh. + +Official software license + +Here's the official license as of 31 Mar 97. + +# Copyright (c) 1996, 1997 Russell W Quong. +# +# In the following, the "author" refers to "Russell Quong." +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by Russell Quong. +# 3. All HTML generated by ltoh must retain a visible notice that it +# was generated by ltoh and contain a link to the ltoh web page +# +# Any or all of these provisions can be waived if you have specific, +# prior permission from the author. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL RUSSELL QUONG BE LIABLE FOR ANY SPECIAL, +# INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY +# THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +---------------------------------------------------------------------------- + +Motivation + +(The motivation section belongs right after the introduction, but most +people probably just want to get on with using ltoh. So this section has +been relegated here. Ah well...) + +Although other LaTeX2e to HTML converters exist, I wrote my own because I +wanted to generate HTML customized to my own liking. In particular, I use my +own custom LaTeX2e definitions (who doesn't?) and wanted to generate HTML +appropriately. Additionally, when using other converters, I was unable get +them to run properly, or I did not like the way the generated HTML looked. + +Fundamentally, ltoh is a specialized macro processor that reads macro +specifications and generates HTML accordingly. A specification indicates how +to convert a specific LaTeX2e definition into HTML. + +My orginal goals in writing ltoh were + + 1. To become more proficient in Perl. + + 2. To write a converter that allowed customized HTML to be generated. + + 3. To handle arbitrary LaTeX2e macros, including macros that take multiple + arguments, and arguments that contained nested macros. + + 4. To generate HTML that resembled the original LaTeX2e, as if someone had + done the translation by hand. In particular, I wanted to avoid + generating very long lines of HTML source, which are difficult to read + when ``viewing the source'' in a browser. + +---------------------------------------------------------------------------- + +Acknowledgements + +Thanks to VA Research for letting the author work on ltoh. + +---------------------------------------------------------------------------- +[Converted LaTeX --> HTML by ltoh] +Russell W. Quong (quong@best.com) Last modified: Apr 1 1997 diff --git a/support/ltoh/rq-ltoh.specs b/support/ltoh/rq-ltoh.specs new file mode 100644 index 0000000000..febf4ab4cd --- /dev/null +++ b/support/ltoh/rq-ltoh.specs @@ -0,0 +1,119 @@ +# ================================================================ +# +# These are definitions for my own latex commands -- R Quong +# \textXX = fonts for diff categories. XX: ff = files, ss = source. +:{} :\textff:<TT><FONT color=maroon>:</>: +:{} :\textss:<CODE><FONT color=navy>:</>: +:{} :\textwarn:<STRONG><FONT color=maroon>:</>: +:{1} :\swallow#1::: + +# +# shows use of @ instead of : as a separator, as using : inside the expansion +# +@{} @\prob@<p><strong><font color=teal>Prob: @</>@ +:{} :\setProbPrefix::: +:{} :\rqtilde:~:: +:{} :\rqtitle:<center><H1><FONT color=green>:</>: +:{} :\rqsubtitle:<center><H3><FONT color=teal>:</>: +:{} :\rqsect:<H5><FONT color=green>:</>: +:{} :\topic:<H4>:</>: +:{} :\ul:<EM>:</>: +:{} :\rqapplet:<APPLET :></APPLET>: +:{} :\labsec:<a name=":"></a>: +:b/e :\begin{quesans}(\{[^\}]*\})*:<OL>:</>: +:b/e :\begin{rqitemize}(\{[^\}]*\})*:<UL>:</>: +:b/e :\begin{rqenumerate}(\{[^\}]*\})*:<OL>:</>: + +# +# Note, you may choose whatever separator you wish for a specification line. +# I.e the \rqhttp command has a colon in it, so we cannot use the +# colon as the separator. Instead, I use a comma. +# +:b/e :\begin{rqcode}:<PRE>:</>: +:b/e :\begin{rqanswer}::: +:b/e :\begin{setindent}{.*}::: +:{} :\rqimage:<img src=":">: +,{2} ,\rqhttp#1#2,<a href="#2"> #1 </a>,, +,{2} ,\rqhttpx#1#2,<a href="http://#2"> #1 </a>,, ++{2} +\rqftp#1#2+<a href="ftp://#2">#1</a>++ +!{2} !\rqhlink#1#2!<a href="#2">#1</a>!! +!{2} !\rqemail#1#2!<a href="mailto:#2">#1</a>!! +|comm |\rqwebhome|http://www.best.com/~quong|| +|comm |\ituwebhome|http://www.itu.edu/computer|| +|comm |\vawebhome|http://www.varesearch.com|| +@{1} @\to#1@To: <strong>#1<br>@</strong>@ +@{1} @\from#1@From: <strong>#1<br>@</strong>@ +@{1} @\subject#1@Subject: <strong>#1</strong><br>@@ +@{1} @\org#1@Document Type: <strong>#1 Memo</strong><br>@@ +@comm @\memohead@Date: <strong>\today</strong><br><hr>@@ +:comm :\today:\today:: +:comm :\vpos::: +:comm :\bsl[ \t]*:\{}:: +:comm :\setProbPrefix[^ \t\n]+::: +:comm :\rqfullpageB[^ \t\n]*::: +:comm :\rqfullpageC[^ \t\n]*::: +:comm :\rqfullpageD[^ \t\n]*::: +:comm :\what[^\n]+::: +:comm :\fi::: +:comm :\ifques::: +:comm :\ifans::: +:comm :\showAns::: +:comm :\onlyans::: +:comm :\onlyprob::: +:comm :\h::: +:comm :\vdots::: +:comm :\normAnsString::: + +# +# the "basic 16" colors +# +:{} :\coloraqua:<font color=aqua>:</>: +:{} :\colorblack:<font color=black>:</>: +:{} :\colorblue:<font color=blue>:</>: +:{} :\colorfuchsia:<font color=fuchsia>:</>: +:{} :\colorgray:<font color=gray>:</>: +:{} :\colorgreen:<font color=green>:</>: +:{} :\colorlime:<font color=lime>:</>: +:{} :\colormaroon:<font color=maroon>:</>: +:{} :\colornavy:<font color=navy>:</>: +:{} :\colorolive:<font color=olive>:</>: +:{} :\colorpurple:<font color=purple>:</>: +:{} :\colorred:<font color=red>:</>: +:{} :\colorsilver:<font color=silver>:</>: +:{} :\colorteal:<font color=teal>:</>: +:{} :\colorwhite:<font color=white>:</>: +:{} :\coloryellow:<font color=yellow>:</>: + +# +# some others colors I like +# +:{} :\colorgold:<font color=gold>:</>: +:{} :\colordarkgrey:<font color=darkgrey>:</>: +:{} :\colorcornsilk:<font color=cornsilk>:</>: +:{} :\colortomato:<font color=tomato>:</>: +:{} :\colorseagreen:<font color=seagreen>:</>: +:{} :\colorperu:<font color=peru>:</>: +:{} :\colorbrown:<font color=brown>:</>: +:{} :\colororange:<font color=orange>:</>: +:{} :\colorlavender:<font color=lavender>:</>: +:{} :\colormistyrose:<font color=mistyrose>:</>: +:{} :\colorivory:<font color=ivory>:</>: +:{} :\colorroyalblue:<font color=royalblue>:</>: +:{} :\colorlightgray:<font color=lightgray>:</>: +:{} :\colorturquoise:<font color=turquoise>:</>: +:{} :\colorcyan:<font color=cyan>:</>: +:{} :\colorsalmon:<font color=salmon>:</>: +:{} :\colorkhaki:<font color=khaki>:</>: +:{} :\colorgoldenrod:<font color=goldenrod>:</>: +:{} :\colorpink:<font color=pink>:</>: +:{} :\colormagenta:<font color=magenta>:</>: +:{} :\colorcoral:<font color=coral>:</>: + +# +# These macros were used for testing, especially for nested parameters. +# +:{2} :\twoSwap#1#2:(#2,#1):: +:{4} :\fourArg:[#1,#2,#3,#4]:: + +=***= warnlevel := 5 + diff --git a/support/ltoh/rq209.sty b/support/ltoh/rq209.sty new file mode 100644 index 0000000000..15f0a70849 --- /dev/null +++ b/support/ltoh/rq209.sty @@ -0,0 +1,43 @@ +% +% Define LaTeX2e font commands for use in the old Latex 2.09 +% R Quong 1994 (or was it 1993 or 1995?) +% + +\@ifundefined{emph}{ + \typeout{Will fake LaTeX2e commands in LaTeX 2.09} + \def\emph#1{{\em #1}} + \def\texttt#1{{\tt #1}} + \def\textsf#1{{\sf #1}} + \def\textsl#1{{\sl #1}} + \def\textit#1{{\it #1}} + \def\textsc#1{{\sc #1}} + \def\textbf#1{{\bf #1}} + \def\textup#1{{\rm #1}} + \def\textmd#1{{\rm #1}} + \def\textrm#1{{\rm #1}} + \def\textul#1{\underline{#1}} + + \def\ttfamily{\tt} + \def\rmfamily{\rm} + \def\sffamily{\sf} + + \def\bfseries{\bf} + \def\mdfamily{\rm} + + \def\itshape{\it} + \def\upshape{\rm} + \def\slshape{\sl} + \def\scshape{\sc} + + \def\ensuremath#1{\mbox{$#1$}} + \def\text#1{\mbox{#1}} + \def\usepackage#1{\input #1} + \newenvironment{comment}{\swallow{}{}} +}{ + \typeout{Skipping rq209.sty (running LaTeX2e already)}\endinput + \def\Box{\rule{.5ex}{.5ex}} +} + + + + |