#!/usr/bin/perl # # This tool generates HTML pages in my own format given a stylized Latex file. # # The output is in HTML 4.01 Transitional form. # # Allen Leung (leunga@cs.nyu.edu) ############################################################################ # # Formatting parameters # ############################################################################ $BACKGROUND_COLOR="#ffffff"; #white $TEXT_COLOR="#000020"; $TITLE_COLOR="#aa0000"; #dark red $ABSTRACT_TITLE_COLOR="#486591"; #black $SECTION_COLOR="#486591"; #dark red $SUBSECTION_COLOR="#486591"; #dark red $SUBSUBSECTION_COLOR="#486591"; #dark red $PARAGRAPH_COLOR="#486591"; #dark red $NEWDEF_COLOR="#ff0000"; #red $NEWTYPE_COLOR="#ff0000"; #red $LINK_COLOR="navy"; $VLINK_COLOR="gray"; $ALINK_COLOR="maroon"; $SML_TYVAR_COLOR="#00aaaa"; #green $SML_KEYWORD_COLOR="#6060a0"; #blue $SML_IDENT_COLOR="#9c4040"; $EMPH_COLOR="#ff0000"; #red $DESC_COLOR="#000070"; #blue $CAPTION_COLOR="#007777"; #green/blue $CODE_COLOR="#000000"; # black $TOC_BACKGROUND_COLOR="#e6e6e6"; $SECTION_TOC_TEXT_COLOR="#486591"; $MAJORSECTION_TEXT_COLOR="ffffff"; $MAJORSECTION_BACKGROUND_COLOR="#486591"; $SECTION_TOC_BACKGROUND_COLOR="#e6e6e6"; $TOC_FACE="hevetica"; $MAX_LOCAL_TOC_ENTRY_LENGTH=40; $MAX_GLOBAL_TOC_ENTRY_LENGTH=40; $GLOBAL_TOC_WIDTH=170; $SCREEN_WIDTH=700; $TEXT_WIDTH=400; $TOC_SIZE=-1; $X_PIXELS = 1024; $Y_PIXELS = 768; $IMAGE_SCALING=0.8; $PAPER_HEIGHT = "11in"; $PAPER_WIDTH = "8.5in"; @AUTHORS=("Lal George", "Allen Leung"); @EMAILS=('george@research.bell-labs.com','leunga@cs.nyu.edu'); $PWD=`pwd`; $DATE=`date`; $HOSTNAME=`hostname`; chop $HOSTNAME; chop $DATE; chop $PWD; $USER=$ENV{"USER"}; $WWWHOST="www.cs.nyu.edu"; $URLPREFIX="leunga/MLRISC/Doc/html/"; $BEGINPRE="<font color=\"$CODE_COLOR\"><small><pre>"; $ENDPRE="</pre></small></font>"; $BEGINALLTT="<font color=\"$CODE_COLOR\"><pre>"; $ENDALLTT="</pre></font>"; ############################################################################ # # Global variables and tables # ############################################################################ $PARAM='[^\{\}]*'; sub globalInit() { @GLOBALTOC=(); # table of contents for entire document @LOCALTOC=(); # table of contents for each section %LINKLABEL={}; # name to link for referenceing %LINKNAME={}; $PATHNAME=""; # current pathname $FILENAME=""; # current file $HTML_FILENAME=""; $LINE_NO=0; # current line $GENERATE_TOC=0; # generate table of contents? $PAGE_TITLE=""; $DOCUMENT_TITLE=""; $DOCUMENT_ABSTRACT=""; $DOCUMENT_AUTHOR=""; %SECTION_TEXT = (); @TEXT=(); @TEXT_STACK=(); } sub IGNORE { return ""; } ############################################################################ # # Error # ############################################################################ sub msg { my($text) = @_; print "$FILENAME:$LINE_NO: ", $text, "\n"; } sub warning { msg("WARNING: " . $_[0]); } sub error { msg($_[0]); die($_[0]); } ############################################################################ # # Filename processing # ############################################################################ sub basename { my($f) = @_; $f =~ s|^.*/||; return $f; } sub dirname { my($f) = @_; $f =~ s|^(.*/).*$|\1|; return $f; } sub suffix { my($f) = @_; $f = basename($f); $f =~ /^.*\.(.*)/; return $1; } sub replaceSuffix { my($f, $old, $new) = @_; if ($f =~ /^(.*\.)$old/) { return $1 . $new; } else { error("file $f does not have suffix $old"); } } ############################################################################ # # Indexing and Cross Referencing. # ############################################################################ sub localtocentry # add local index entry { my($name,$level) = @_; my(@entry) = ($name, $level); push @LOCALTOC, \@entry; my($label) = $LABELCOUNTER++; $LINKLABEL{$name} = '#'. $label; $LINKNAME{$name} = $name; $CURRENT_SECTION_NAME=$name; return "<a name=\"$label\"></a>"; } sub globaltocentry # add global index entry { my($name, $level) = @_; my(@entry) = ($name, $level); push @GLOBALTOC, \@entry; my($key) = "section:$name"; $LINKLABEL{$key} = $HTML_FILENAME; $LINKNAME{$key} = $name; $CURRENT_SECTION_NAME=$name; } sub tableofcontents { $GENERATE_TOC = 1; print "[Generating table of contents]\n"; return ""; } sub label { my($label) = @_; $LINKLABEL{$label} = $HTML_FILENAME . '#' . $label; $LINKNAME{$label} = $CURRENT_SECTION_NAME; return "<a name=\"$label\"></a>"; } sub ref { my($label) = @_; return "{$label}"; } sub lookupRef { my($label) = @_; my($ref) = $LINKLABEL{$label}; my($name) = $LINKNAME{$label}; return " <a href=\"$ref\">$name</a>"; } sub resolveReferences { my($text) = @_; $text =~ s/\{($PARAM)\}/&lookupRef($1)/oge; return $text; } ############################################################################ # # Execute a subprogram # ############################################################################ sub runprog { my($command) = @_; print STDERR "running: ", $command, "\n"; system("$command"); if ($?) { die("$? $command"); } } ############################################################################ # # Environment/command processing # ############################################################################ sub enterMode { my($m) = @_; push @MODE_STACK, $m; $MODE = $m; } sub leaveMode { my($m) = @_; if ($MODE ne $m) { die("Trying to leave $m but actually in " . $MODE . " mode"); } pop @MODE_STACK; $MODE = $MODE_STACK[$#MODE_STACK]; $parbreak=1; } sub pushTextStack { push @TEXT_STACK, \@TEXT; @TEXT=(); } sub popTextStack { my(@text) = @TEXT; my($old) = pop @TEXT_STACK; @TEXT = @{$old}; return "@text"; } %DEFINEDNAMES = {}; %BEGINENV = {}; # how to process \begin{env} %ENDENV = {}; # how to process \end{env} %HTMLENV = {}; # html tag translation %COMMAND = {}; # how to process \command %ARITY = {}; # how many parameters does the environment has @ENV0 = (); @ENV1 = (); @ENV2 = (); @COMMAND0 = (); @COMMAND1 = (); @COMMAND2 = (); @COMMAND3 = (); sub newenvironment { my($name,$arity,$begin,$end) = @_; if (defined $DEFINEDNAMES{$name}) { die("$name has already been defined"); } $DEFINEDNAMES{$name} = "env"; $BEGINENV{$name} = $begin; $ENDENV{$name} = $end; $ARITY{$name} = $arity; push @ENV0, $name if $arity == 0; push @ENV1, $name if $arity == 1; push @ENV2, $name if $arity == 2; } sub newhtmlenvironment { my($name,$tag) = @_; if (defined $DEFINEDNAMES{$name}) { die("$name has already been defined"); } $DEFINEDNAMES{$name} = "htmltag"; $HTMLENV{$name} = $tag; push @ENV0, $name; } # This environment does not cause trailing paragraph breaks sub newhtmlparenvironment { newhtmlenvironment(@_); my($name) = @_; $PARENV{$name} = 1; } sub newcommand { my($name,$arity,$command) = @_; if (defined $DEFINEDNAMES{$name}) { die("$name has already been defined"); } $DEFINEDNAMES{$name} = "command"; $COMMAND{$name} = $command; $ARITY{$name} = $arity; push @COMMAND0, $name if $arity == 0; push @COMMAND1, $name if $arity == 1; push @COMMAND2, $name if $arity == 2; push @COMMAND3, $name if $arity == 3; } sub beginenv { my($env,@args) = @_; my($type) = $DEFINEDNAMES{$env}; if (! defined $type) { warning("environment $env is not defined"); return "\\begin{$env}"; } if ($type eq "env") { my($func) = $BEGINENV{$env}; return $func->(@args); # call function } return "<$HTMLENV{$env}>" if $type eq "htmltag"; die("don't know how to handle \\begin{$env} at line $LINE_NO"); } sub endenv { my($env) = @_; my($type) = $DEFINEDNAMES{$env}; if (! defined $type) { warning("environment $env is not defined"); return "\\end{$env}"; } return "</$HTMLENV{$env}>" if $type eq "htmltag"; if ($type eq "env") { my($func) = $ENDENV{$env}; my($text) = $func->(); # call function $parbreak = 1; return $text; } die("don't know how to handle \\end{$env} at line $LINE_NO"); } sub command { my($command,@args) = @_; my($type) = $DEFINEDNAMES{$command}; if (! defined $type) { warning("command $command is not defined"); return "\\$env"; } #print "[$command]"; if ($type eq "command") { my($func) = $COMMAND{$command}; if (! $func) { die("don't know how to handle \\$command at line $LINE_NO"); } return $func->(@args); } die("don't know how to handle \\$command at line $LINE_NO"); } ############################################################################ # # Color processing # ############################################################################ $COLORS{"red"} = "#ff0000"; $COLORS{"green"} = "#00ff00"; $COLORS{"blue"} = "#0000ff"; $COLORS{"darkred"} = "#aa0000"; $COLORS{"darkgreen"} = "#00aa00"; $COLORS{"darkblue"} = "#0000aa"; $COLORS{"black"} = "#000000"; $COLORS{"grey"} = "#777777"; $COLORS{"white"} = "#ffffff"; sub colorOf { my($c) = @_; return $COLORS{$c} if (defined $COLORS{$c}); return "\"$c\""; } sub begincolor { my($c) = @_; return "<font color=" . colorOf($c) . ">"; } sub endcolor { return "</font>"; } ############################################################################ # # Generic LaTeX fonts and sizes handling. # ############################################################################ sub bf { return ""; } sub tt { return ""; } sub it { return ""; } sub em { return ""; } sub sf { return ""; } sub rm { return ""; } sub huge { return ""; } sub LARGE { return ""; } sub Large { return ""; } sub large { return ""; } sub normalsize { return ""; } sub small { return ""; } sub footnotesize { return ""; } sub scriptsize { return ""; } sub tiny { return ""; } ############################################################################ # # Headers and footers # ############################################################################ sub header { $HEADER= <<"END"; <!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"> <!-- Generated by mltex2html --> <!-- do not edit this file --> END return $HEADER; } sub footer { my($filename) = @_; my($URL)="http://$WWWHOST/$URLPREFIX$outfile"; my($contact) = "<table>\n"; for ($i=0; $i <= $#AUTHORS; $i++) { $author = $AUTHORS[$i]; $email = $EMAILS[$i]; $contact .= "<tr><td><font size=\"-1\">\n"; $contact .= "<a href=\"mailto:$email\">$author</a>\n"; $contact .= "</font></td></tr>\n"; } $contact .= "</table>\n"; $FOOTER= <<"END"; <hr> <table cellpadding=0 cellspacing=0 width="100%"> <tr> <td align=left> $contact </td> <td align=right> <a href="http://cm.bell-labs.com/cm/cs/what/smlnj/index.html"> <img src="graphics/smlnj.jpg" width=80 height=50 alt="SML/NJ" border=0> </a> <a href="http://validator.w3.org/check?url=$URL"> <img src="graphics/vh401.gif" width=88 height=31 alt="Validate this page" border=0> </a> </td> </tr> <tr> <td align=left> <font size="-1"> <i> Generated by <a href="mltex.html"> <font color="#007777">mltex2html</font> </a> </i> </font> </td> </tr> <tr> <td> <font size="-2"> Last modified: $DATE by $USER\@$HOSTNAME </font> </td> </tr> </table> END return $FOOTER; } ############################################################################ # # SML keyword highlighting # ############################################################################ @KEYWORDS=("structure", "datatype", "type", "of", "eqtype", "struct", "end", "case", "if", "then", "else", "signature", "functor", "withtype", "sharing", "include", "where", "val", "fun", "handle", "raise", "exception", "let", "in", "local", "abstype", "rec", "and", "andalso", "orelse", "open", "infix", "infixr", "nonfix" ); @DEFKEYWORDS=("functor", "structure", "signature", "exception", "withtype", "datatype", "type", "eqtype", "fun", "val"); $KEYWORDS = "@KEYWORDS"; $KEYWORDS =~ s/ /|/g; $DEFKEYWORDS = "@DEFKEYWORDS"; $DEFKEYWORDS =~ s/ /|/g; $SMLIDENT = "[a-zA-Z_][a-zA-Z0-9_']*"; $SMLTYPEVAR = "('+$SMLIDENT)"; sub highlightKeyword { return "<font color=\"$SML_KEYWORD_COLOR\"><b>$_[0]</b></font>"; } sub highlightTyvar { return "<font color=\"$SML_TYVAR_COLOR\">$_[0]</font>"; } sub highlightIdent { my($keyword, $typevar, $ident) = @_; if ($typevar ne "") { $typevar .= " "; } return "$keyword $typevar<font color=\"$SML_IDENT_COLOR\"><b>$ident</b></font>"; } sub escape { my($line) = @_; $line =~ s|<|<|g; $line =~ s|>|>|g; $line =~ s|<|<|g; $line =~ s|>|>|g; return $line; } sub smldisplay { my($line) = @_; #$line =~ s/\b(($DEFKEYWORDS)\s+($SMLTYPEVAR|\(\s*$SMLTYPEVAR(\s*,\s*$SMLTYPEVAR)*\))?)\s*($SMLIDENT)(\s*=)/&highlightIdent($2,$3,$8) . $9/oge; $line =~ s/\b($KEYWORDS)\b/&highlightKeyword($1)/oge; $line =~ s/^(sig)\b/&highlightKeyword($1)/oge; $line =~ s/([^\.\w])(sig)\b/$1 . &highlightKeyword($2)/oge; $line =~ s/('\w+)/&highlightTyvar($1)/oge; return $line; } sub sml { return "<tt>" . smldisplay(@_) . "</tt>"; } ############################################################################ # # Sectioning commands # ############################################################################ sub include { my($filename) = @_; $FILENAME= $PATHNAME . $filename . ".tex"; $HTML_FILENAME=replaceSuffix(basename($FILENAME),"tex","html"); print STDERR "[Processing $FILENAME]\n"; my($title,@text) = processSection($FILENAME); my($localtoc) = ""; if ($#LOCALTOC >= 0) { my(@toctitle) = ($title, 0); my(@LOCALTOC) = (\@toctitle, @LOCALTOC); $localtoc = makeTOC("local", "border=0 align=right bgcolor=\"$SECTION_TOC_BACKGROUND_COLOR\"", $MAX_LOCAL_TOC_ENTRY_LENGTH,"",@LOCALTOC); } my(@entry) = ($title, $localtoc, @text); $SECTION_TEXT{$FILENAME} = \@entry; return ""; } sub section { my($name) = @_; #print "section $name\n"; $parbreak=1; $PAGE_TITLE=$name; globaltocentry($name,1); return ""; } sub majorsection { my($name) = @_; my(@entry) = ($name, 0); push @GLOBALTOC, \@entry; $parbreak=1; return ""; } sub title { $DOCUMENT_TITLE = $_[0]; $parbreak=1; return ""; } sub subsection { my($name) = @_; #print "[subsection $name]\n"; $parbreak=1; my($label) = localtocentry($name, 2); return <<"END" $label <h2><font color="$SUBSECTION_COLOR">$name</font></h2> END } sub subsubsection { my($name) = @_; #print "subsubsection $name\n"; $parbreak=1; my($label) = localtocentry($name, 3); return <<"END"; $label <h3><font color="$SUBSUBSECTION_COLOR">$name</font></h3> END } sub paragraph { my($name) = @_; #print "paragraph $name\n"; $parbreak=1; my($label) = localtocentry($name, 4); return <<"END"; $label <h4><font color="$PARAGRAPH_COLOR">$name</font></h4> END } sub beginabstract { print "[begin abstract]\n"; pushTextStack(); return ""; } sub endabstract { print "[end abstract]\n"; $DOCUMENT_ABSTRACT = popTextStack(); return ""; } ############################################################################ # # Hypertext links # ############################################################################ sub href { return "<a href=\"$_[0]\">$_[1]</a>"; } sub mlrischref { return "<a href=\"../../$_[0]\" target=code>$_[1]</a>"; } sub externhref { return "<a href=\"$_[0]\">$_[1]</a>"; } ############################################################################ # # Images and figures # ########################################################################### sub isGraphics { my($filename) = @_; return 1 if $filename =~ /\.png$/; return 1 if $filename =~ /\.jpg$/; return 1 if $filename =~ /\.gif$/; return 1 if $filename =~ /\.tif$/; return 1 if $filename =~ /\.tiff$/; return 0; } sub image { return "<img alt=\"$_[0]\" src=$_[1] $_[2]>"; } # # Given a image file, try to find out if the original source exists # Paths are hardwired for now. sub figOf { my($filename) = @_; my($basename) = ""; $basename = $1 if $filename =~ m|^\.\./pictures/eps/(.*)\.eps|; my($fig) = "../pictures/fig/$basename.fig"; return $fig if (-f $fig); return ""; } # # Try to convert the eps file to png # sub imageOf { my($filename) = @_; $basename = $1 if ($filename =~ m|^\.\./pictures/eps/(.*)\.eps$|); my($png) = "../pictures/png/$basename.png"; return $png if -f $png; my($jpg) = "../pictures/jpeg/$basename.jpg"; return $jpg if -f $jpg; my($fig) = figOf($filename); if ($fig) { runprog("fig2dev -L png $fig $png"); return $png; } return ""; } # # Try to translate LaTeX lengths into pixel sizes # sub lengthOf { my($l) = @_; return $1 * 0.4 if $l =~ /^(\d*(\.\d*)?)em$/; # making a guess return $1 * 0.4 if $l =~ /^(\d*(\.\d*)?)cm$/; return $1 * 1.0 if $l =~ /^(\d*(\.\d*)?)in$/; if (! ($l =~ /^\s*$/)) { die("lengthOf($l)"); } return 0; } sub heightOf { return lengthOf(@_) / lengthOf($PAPER_HEIGHT) * $Y_PIXELS * $IMAGE_SCALING; } sub widthOf { return lengthOf(@_) / lengthOf($PAPER_WIDTH) * $X_PIXELS * $IMAGE_SCALING; } # # Try to translate sizes into pixel sizes # sub makeSize { my($height, $width) = @_; $height = heightOf($height); $width = widthOf($width); my($size) = ""; $size .= "height=$height" if $height; $size .= " width=$width" if $width; return $size; } sub psfig { my($params) = @_; my($filename) = ($params =~ /figure=([^ ,]*)/); my($height) = ($params =~ /height=([^ ,]*)/); my($width) = ($params =~ /width=([^ ,]*)/); my($size) = makeSize($height, $width); if (! defined $filename) { die("figure not found in $params"); } if (! -f $filename) { warning("filename $filename not found"); } my($img) = imageOf($filename); if ($img) { return <<"END"; <a href="$img" target=image> <img src="$img" align=left alt="Click to enlarge" $size border=0> </a> END } else { return "<a href=\"$filename\"> $filename </a>"; } } sub cpsfig { return "<center>" . psfig(@_) . "</center>"; } sub beginfig { my($border,$align) = @_; $CAPTION = ""; $align = "align=left" if $align eq "l"; $align = "align=right" if $align eq "r"; $align = "align=center" if $align eq "c"; return "<table border=$border $align><tr><td align=center>"; } sub endfig { my($caption) = @_; msg("new figure, caption=$caption"); if ($caption ne "") { $caption = <<"END"; <tr> <td align=center> <font color="$CAPTION_COLOR"> <i>$caption</i> </font> </td> </tr> END } return "</td></tr>$caption</table>"; } sub beginFigure { return beginfig(0,""); } sub endFigure { return endfig($CAPTION); } sub caption { my($text) = @_; $CAPTION = $text; return ""; } sub beginwrapfigure { my($align,$size) = @_; return beginfig(0,$align); } sub endwrapfigure { return endfig($CAPTION); } ############################################################################ # # Generic tabular processing # ############################################################################ sub begintab { my($taboptions, $html) = @_; enterMode("tabular"); # guess the border my($border) = 0; $border = 1 if ($taboptions =~ /^\|/); $border = 2 if ($taboptions =~ /^\|\|/); if ($html eq "") { $html = "align=center"; } push @tabular_stack, $taboptions; push @current_taboptions, $taboptions; return "<table border=$border $html><tr>" . newtabitem(); } sub endtab { leaveMode("tabular"); pop @tabular_stack; pop @current_tab; return "</td></tr></table>"; } sub newtabitem { my($t) = $current_taboptions[$#current_taboptions]; my($align) = "left"; $t = $1 if $t =~ /^\|+(.*)/; ($align = "center", $t = $1) if $t =~ /^c(.*)/; ($align = "left", $t = $1) if $t =~ /^l(.*)/; ($align = "right", $t = $1) if $t =~ /^r(.*)/; $current_taboptions[$#current_taboptions] = $t; return "<td align=$align>"; } sub addtab { return "</td>" . newtabitem(); } sub tabnewline { $current_taboptions[$#current_taboptions] = $tabular_stack[$#tabular_stack]; return "</tr><tr>" . newtabitem(); } sub newline { return "<br>"; } ############################################################################ # # Math mode processing # ############################################################################ $MATHPARAM='[^$]*'; $MATHPARAM2='([^$\\]|\\[^)]+)*'; sub math { my($math) = @_; $math =~ s|&||g; $math =~ s|\\le\b|<=|g; $math =~ s|\\ge\b|>=|g; #quote all < and > first $math =~ s/</</g; $math =~ s/>/>/g; # fonts changing $math =~ s|{\\tt\s+($PARAM)}|<tt>\1</tt>|g; # subscript/superscripts $math =~ s|_([^{])|<sub>\1</sub>|g; $math =~ s|\^([^{])|<sup>\1</sup>|g; $math =~ s|_{($PARAM)}|<sub>\1</sub>|g; $math =~ s|^{($PARAM)}|<sup>\1</sup>|g; $math =~ s|\\sb{($PARAM)}|<sub>\1</sub>|g; $math =~ s|\\sp{($PARAM)}|<sup>\1</sup>|g; # other stuff $math =~ s|\\edge\{($PARAM)\}|&rarr<sub>\1</sub>|g; $math =~ s|\\defas\b|=|g; $math =~ s|\\lim\b|lim|g; $math =~ s|\\sin\b|sin|g; $math =~ s|\\cos\b|cos|g; $math =~ s|\\tan\b|tan|g; $math =~ s|\\log\b|log|g; $math =~ s|\\equiv\b|==|g; $math =~ s|\\ldots\b|...|g; $math =~ s|\\in\b|∈|g; $math =~ s|\\alpha\b|α|g; $math =~ s|\\beta\b|β|g; $math =~ s|\\gamma\b|γ|g; $math =~ s|\\lambda\b|λ|g; $math =~ s|\\phi\b|φ|g; $math =~ s|\\sum\b|∑|g; $math =~ s|\\cup\b|∪|g; $math =~ s|\\cap\b|∩|g; $math =~ s|\\rightarrow\b|→|g; $math =~ s|\\leftarrow\b|←|g; $math =~ s/\{/{/g; $math =~ s/\}/}/g; #unquote all < and > $math =~ s|<|<|g; $math =~ s|>|>|g; $math =~ s|\\ne\b|<>|g; $math =~ s|\\\\|<dt><dd>|g; return "<math class=\"inline\"><i>$math</i></math>"; } sub displaymath { my($math) = @_; return "<dl><dt><dd>" . math($math) . "</dl>"; } sub stupidBrowserMath { s#&rarr(;|\b)#->#g; s#&larr(;|\b)#<-#g; s#&isin(;|\b)#in #g; } ############################################################################ # # Frames and boxes # ############################################################################ sub beginboxit { return "<table border=1><tr><td>"; } sub endboxit { return "</td></tr></table>"; } ############################################################################ # # Setup the commands and environments # ############################################################################ newenvironment("color",1, \&begincolor, \&endcolor); newhtmlenvironment("small","small"); newhtmlenvironment("Bold","b"); newhtmlenvironment("Italics","i"); newhtmlenvironment("Emph","em"); newhtmlenvironment("address","address"); newhtmlparenvironment("quotation","blockquote"); newhtmlparenvironment("center","center"); newhtmlparenvironment("enumerate","ol"); newhtmlparenvironment("itemize","ul"); newhtmlparenvironment("description","dl"); newenvironment("boxit", 0, \&beginboxit, \&endboxit); newenvironment("Boxit", 0, \&beginboxit, \&endboxit); newcommand("title", 1, \&title); newcommand("section", 1, \§ion); newcommand("subsection", 1, \&subsection); newcommand("subsubsection", 1, \&subsubsection); newcommand("paragraph", 1, \¶graph); newcommand("include", 1, \&include); newcommand("majorsection", 1, \&majorsection); newenvironment("abstract",0,\&beginabstract,\&endabstract); newcommand("bf",0,\&bf); newcommand("tt",0,\&tt); newcommand("it",0,\&it); newcommand("em",0,\&em); newcommand("sf",0,\&sf); newcommand("rm",0,\&rm); newcommand("huge",0,\&huge); newcommand("LARGE",0,\&LARGE); newcommand("Large",0,\&Large); newcommand("large",0,\&large); newcommand("normalsize",0,\&normalsize); newcommand("footnotesize",0,\&footnotesize); newcommand("scriptsize",0,\&scriptsize); newcommand("tiny",0,\&tiny); newcommand("Term", 1, sub { return "<i>$_[0]</i>"; } ); newcommand("italics", 1, sub { return "<i>$_[0]</i>"; }); newcommand("bold", 1, sub { return "<b>$_[0]</b>"; }); newcommand("emph", 1, sub { return "<em>$_[0]</em>"; }); newcommand("href", 2, \&href); newcommand("mlrischref", 2, \&mlrischref); newcommand("externhref", 2, \&externhref); newcommand("image", 3, \&image); newcommand("psfig", 1, \&psfig); newcommand("cpsfig", 1, \&cpsfig); newcommand("linebreak", 0, \&IGNORE); newcommand("hr", 0, sub { return "<hr>"; }); newcommand("hline", 0, \&IGNORE); newcommand("pagebreak", 0, \&IGNORE); newcommand("br", 1, sub { return "<br $_[0]>"; }); newcommand("label",1, \&label); newcommand("ref",1, \&ref); newcommand("MLRISC", 0, sub { return "MLRISC"; }); newcommand("LaTeX", 0, sub { return "L<sup>A</sup>T<sub>E</sub>X"; }); newcommand("MLTeX", 0, sub { return "MLT<sub>E</sub>X"; }); newcommand("caption", 1, \&caption); newenvironment("Figure", 0, \&beginFigure, \&endFigure); newenvironment("wrapfigure", 2, \&beginwrapfigure, \&endwrapfigure); sub newdef { return "<font color=\"$NEWDEF_COLOR\">$_[0]</font>"; } sub newtype { return "<font color=\"$NEWTYPE_COLOR\"><tt>$_[0]</tt></font>"; } newcommand("newdef",1,\&newdef); newcommand("newtype",1,\&newtype); newcommand("cite", 1, sub { return "<cite>[$_[0]]</cite>"; }); newcommand("tableofcontents", 0, \&tableofcontents); ############################################################################ # # Import style file # ############################################################################ require "mltex.thm"; ############################################################################ # # Setup the patterns for command and environment parsing # ############################################################################ $COMMAND0 = "@COMMAND0"; $COMMAND0 =~ s/ /|/g; $COMMAND1 = "@COMMAND1"; $COMMAND1 =~ s/ /|/g; $COMMAND2 = "@COMMAND2"; $COMMAND2 =~ s/ /|/g; $COMMAND3 = "@COMMAND3"; $COMMAND3 =~ s/ /|/g; $COMMAND0 = 'XXXXXXXXXXXXXXXXX' if ($COMMAND0 eq ""); $COMMAND1 = 'XXXXXXXXXXXXXXXXX' if ($COMMAND1 eq ""); $COMMAND2 = 'XXXXXXXXXXXXXXXXX' if ($COMMAND2 eq ""); $COMMAND3 = 'XXXXXXXXXXXXXXXXX' if ($COMMAND3 eq ""); $ENV0 = "@ENV0"; $ENV0 =~ s/ /|/g; $ENV1 = "@ENV1"; $ENV1 =~ s/ /|/g; $ENV2 = "@ENV2"; $ENV2 =~ s/ /|/g; $ENV0 = 'XXXXXXXXXXXXXXXXX' if ($ENV0 eq ""); $ENV1 = 'XXXXXXXXXXXXXXXXX' if ($ENV1 eq ""); $ENV2 = 'XXXXXXXXXXXXXXXXX' if ($ENV2 eq ""); #print "COMMAND0 = $COMMAND0\n"; #print "COMMAND1 = $COMMAND1\n"; #print "COMMAND2 = $COMMAND2\n"; #print "COMMAND3 = $COMMAND3\n"; #print "ENV0 = $ENV0\n"; #print "ENV1 = $ENV1\n"; #print "ENV2 = $ENV2\n"; ############################################################################ # # Indexing and Table of Contents generation. # ############################################################################ sub truncentry { my($entry,$max_len) = @_; if ($max_len > 0 && length($entry) >= $max_len) { $entry = substr($entry, 0, $max_len-1) . "..."; } return $entry; } ############################################################################ # # Make a table of contents # ############################################################################ sub makeTOC { my($type, # local or global $html, # extra html parameters to the table $max_len, # maximal length of each entry $highlight, # which entry to highlight @TOC # the entries ) = @_; return "" if $#TOC < 0; my($toc) = ""; my($labelprefix) = ""; if ($type eq "global") { $labelprefix = "section:"; } $toc = <<"END"; <!-- table of contents --> <table cellpadding=0 cellspacing=0 $html> <tr><td> END for $entry (@TOC) { my($name) = $entry->[0]; my($level) = $entry->[1]; my($label) = $LINKLABEL{$labelprefix . $name}; my($text) = truncentry($name,$max_len); # Major section heading if ($level == 0) { $toc .= <<"END"; </td></tr><tr><td> <table bgcolor="$MAJORSECTION_BACKGROUND_COLOR" width="100%" border=0 cellpadding=0 cellspacing=0> <tr><td align=center><font color="$MAJORSECTION_TEXT_COLOR"> $text </font> </td></tr></table><tr><td> END } else # Normal extries { my($indent) = "-" x ($level - 2); if ($name eq $highlight) { $text = "<font color=\"$SECTION_TOC_TEXT_COLOR\"><b>$text</b></font>"; } if ($type eq "local") { $text = "<font size=\"$TOC_SIZE\" color=\"$SECTION_TOC_TEXT_COLOR\">$text</font>"; } else { $text = "<font size=\"$TOC_SIZE\">$text</font>"; } $toc .= <<"END"; $indent<a href="$label">$text</a><br> END } } $toc .= <<"END"; </td></tr> </table> <!-- end of table of contents --> END return $toc; } ############################################################################ # # Generate the output # ############################################################################ sub writeSection { my($filename,$TITLE,$localtoc,@TEXT) = @_; my($outfile) = replaceSuffix(basename($filename), "tex", "html"); my($toc) = ""; print STDERR "[Generating $outfile]\n"; # Global table of contents if ($GENERATE_TOC) { $toc = makeTOC("global", "border=0 width=$GLOBAL_TOC_WIDTH bgcolor=\"$TOC_BACKGROUND_COLOR\"", $MAX_GLOBAL_TOC_ENTRY_LENGTH, $TITLE, @GLOBALTOC); $toc = <<"END"; <td valign=top align=left width="$GLOBAL_TOC_WIDTH"> $toc </td> END } open(OUTFILE,">$outfile") || die("$!: $outfile"); $header = header($TITLE); $footer = footer($outfile); $maintext = resolveReferences("@TEXT"); $TOTAL_WIDTH = $TEXT_WIDTH + $GLOBAL_TOC_WIDTH; print OUTFILE <<"END"; $header <html> <head> <title> $TITLE </title> </head> <body bgcolor="$BACKGROUND_COLOR" text="$TEXT_COLOR" link="$LINK_COLOR" vlink="$VLINK_COLOR" alink="$ALINK_COLOR"> <table border=0> <tr> $toc <td width=2> </td> <td valign=top align=left> <center><h1><font color="$SECTION_COLOR"><b>$TITLE</b></font></h1></center> <hr> $localtoc $maintext $footer </td> </tr> </table> </body> </html> END close OUTFILE; } ############################################################################ # # Write out the main page # ############################################################################ sub writeDocument { my($filename) = @_; my($outfile) = replaceSuffix(basename($filename), "tex", "html"); print STDERR "[Generating $outfile]\n"; my($toc) = makeTOC("global","border=0 width=$GLOBAL_TOC_WIDTH", $MAX_GLOBAL_TOC_ENTRY_LENGTH, "", @GLOBALTOC); open(OUTFILE,">$outfile") || die("$!: $outfile"); my($header) = header($DOCUMENT_TITLE); my($footer) = footer($outfile); print OUTFILE <<"END"; $header <html> <head> <title> $DOCUMENT_TITLE </title> </head> <body bgcolor="$BACKGROUND_COLOR" text="$TEXT_COLOR"> <table border=0> <tr> <td valign=top align=left> $toc </td> <td width=2> </td> <td valign=top align=left textwidth="$TEXT_WIDTH"> <center><h1><font color="$TITLE_COLOR">$DOCUMENT_TITLE</font></h1></center> <hr> <center> $DOCUMENT_AUTHOR </center> <center> <font color="$ABSTRACT_TITLE_COLOR"><b>Abstract</b></font> </center> <blockquote> $DOCUMENT_ABSTRACT </blockquote> $footer </td></tr> </table> </td> </tr> </table> </body> </html> END close OUTFILE; } ############################################################################ # # Initialization # ############################################################################ sub init() { $MODE = "latex"; @MODE_STACK=($MODE); @tabular_stack=(); $LINE_NO=0; @TEXT=(); @LOCALTOC=(); $LABELCOUNTER="link0000"; } ############################################################################ # # Main loop for processing a section # ############################################################################ sub processSection { my ($filename) = @_; if (! ($filename =~/\.tex$/)) { die("$filename must end in .tex"); } open(INFILE,$filename) || die("$!: $filename"); init(); local($LINE_NO) = 0; while (<INFILE>) { $LINE_NO++; # Verbatim mode handling if ($MODE eq "verbatim") { if (s|\\end{verbatim}|$ENDPRE|) { leaveMode("verbatim"); } else { s/</</g; s/>/>/g; } push @TEXT, $_; next; } if ($MODE eq "alltt") { if (s|\\end{alltt}|$ENDALLTT|) { leaveMode("alltt"); }; push @TEXT, $_; next; } $_ = escape($_) if $MODE eq "sml"; # \verb # Must match the mimimum number of times s|\\verb(.)(.*?)\1|<tt>\2</tt>|g if ($MODE ne "verbatim"); # paragraph if ($MODE eq "latex") { if (/^\s+$/) { if (! $parbreak) { $_ = "<p>\n"; $parbreak=1; } } else { $parbreak = 0; } } # special formatting environments if (s|\\begin{SML}|$BEGINPRE|) { enterMode("sml"); }; if (s|\\end{SML}|$ENDPRE|) { leaveMode("sml"); }; if (s|\\begin{code}|$BEGINPRE|) { enterMode("code"); }; if (s|\\end{code}|$ENDPRE|) { leaveMode("code"); }; if (s|\\begin{verbatim}|$BEGINPRE|) { enterMode("verbatim"); }; if (s|\\begin{alltt}|$BEGINALLTT|) { enterMode("alltt"); }; # method if (s|\\begin{methods}|<dl><dt><tt>|) { enterMode("methods"); }; if (s|\\end{methods}|</tt></dl>|) { leaveMode("methods"); }; s|\&|</tt><dd>|g if $MODE eq "methods"; s|\\\\|<dt><tt>|g if $MODE eq "methods"; # Itemize s|\\item\[([^\]]*)\]|<dt><font color="$DESC_COLOR">\1</font><dd>|; s|\\item|<li>|; # Tables s|\\begin{tabular}{($PARAM)}|&begintab($1,"")|oge; s|\\end{tabular}|&endtab()|oge; s|\\begin{Table}{($PARAM)}{($PARAM)}|&begintab($1,$2)|oge; s|\\end{Table}|&endtab()|oge; s|\&|&addtab()|oge if $MODE eq "tabular"; s|\\\\|&tabnewline()|oge if $MODE eq "tabular"; s|\\\\|&newline()|oge if $MODE eq "latex"; # SML mode handling s|\\sml{($PARAM)}|&sml($1)|oge; s|\\code{($PARAM)}|<tt>\1</tt>|g; if ($MODE eq "sml") { $_ = smldisplay($_); } # Math mode handling if ($MODE ne "sml") { s|\$($MATHPARAM)\$|&math($1)|eg; } s|\\\(($MATHPARAM2)\\\)|&math($1)|oeg; if (/\\\[\s*\S|\S\s*\\\[/) { error("please put \\[ on a separate line by itself"); } if (/^\s*\S+\s*\\\]\s*$/) { error("please put \\] on a separate line by itself"); } if ($MODE eq "displaymath") { $_ = math($_); } if ($MODE eq "eqnarray*") { $_ = math($_); } if ($MODE eq "eqnarray") { $_ = math($_); } if (s|\\\[\s*$|<dl><dt><dd>|) { enterMode("displaymath"); } if (s|\\\]|</dl>|) { leaveMode("displaymath"); } if (s|\\begin{eqnarray\*}|<dl><dt><dd>|) { enterMode("eqnarray*"); } if (s|\\end{eqnarray\*}|</dl>|) { leaveMode("eqnarray*"); } if (s|\\begin{eqnarray}|<dl><dt><dd>|) { enterMode("eqnarray"); } if (s|\\end{eqnarray}|</dl>|) { leaveMode("eqnarray"); } # How to handle environment s|~?\\begin{($ENV0)}|&beginenv($1)|oge; s|~?\\begin{($ENV1)}{($PARAM)}|&beginenv($1,$2)|oge; s|~?\\begin{($ENV2)}{($PARAM)}{($PARAM)}|&beginenv($1,$2,$3)|oge; s|~?\\end{($PARAM)}|&endenv($1)|oge; # How to handle commands s/~?\\($COMMAND0)(\{\}|\b)/&command($1)/oge; s|~?\\($COMMAND1){($PARAM)}|&command($1,$2)|oge; s|~?\\($COMMAND2){($PARAM)}{($PARAM)}|&command($1,$2,$3)|oge; s|~?\\($COMMAND3){($PARAM)}{($PARAM)}{($PARAM)}|&command($1,$2,$3,$4)|oge; # Math mode stuff s|\\_|_|g; s|\\{|{|g; s|\\}|}|g; # Indentation s|\\noindent ||g; # # Not all browers can handle the math stuff yet. Do this in the mean time. # stupidBrowserMath(); push @TEXT, $_; } close INFILE; return ($PAGE_TITLE, @TEXT); } ############################################################################ # # Main loop for processing a document # ############################################################################ sub processDocument { my($filename) = @_; my($line, $output); globalInit(); $MODE = "latex"; @MODE_STACK=($MODE); $PATHNAME = ""; if ($filename =~ /^(.*\/)[^\/]*$/) { $PATHNAME = $1; } $LINE_NO=0; $FILENAME=$filename; open (DOCUMENT, $filename) || die("$! $filename"); while ($_ = <DOCUMENT>) { $LINE_NO++; s|%.*$||; #skip comments s|\\\\|&newline()|oge if $MODE eq "latex"; # How to handle environment s|~?\\begin{($ENV0)}|&beginenv($1)|oge; s|~?\\begin{($ENV1)}{($PARAM)}|&beginenv($1,$2)|oge; s|~?\\begin{($ENV2)}{($PARAM)}{($PARAM)}|&beginenv($1,$2,$3)|oge; s|~?\\end{($PARAM)}|&endenv($1)|oge; # How to handle commands s/~?\\($COMMAND0)(\{\}|\b)/&command($1)/oge; s|~?\\($COMMAND1){($PARAM)}|&command($1,$2)|oge; s|~?\\($COMMAND2){($PARAM)}{($PARAM)}|&command($1,$2,$3)|oge; s|~?\\($COMMAND3){($PARAM)}{($PARAM)}{($PARAM)}|&command($1,$2,$3,$4)|oge; push @TEXT, $_; } close DOCUMENT; # Write out the sections foreach $file (keys %SECTION_TEXT) { my($output) = $SECTION_TEXT{$file}; my($title, $localtoc, @text) = @{$output}; writeSection($file, $title, $localtoc, @text); } # Write out the main page writeDocument($filename); } #main foreach $file (@ARGV) { processDocument($file) }