#!/usr/local/bin/perl
eval "exec perl -S  $0 $*"
                         if $running_under_some_shell;
# paper2html
# Perceived by Matthias Schwab
# Written by Joel Schroeder 4/9/96
#
# keywords web html report tex redoc

$usage = "Usage: $0 srcdir urlpth [tex=filename.tex] [-b] [-a] [-s] [-p] [-t] [-g] [-c] [-P] [-T] > file.html\n";
$selfdoc = "
Convert a texfile in the current directory to html format.
  tex=filename.tex  convert filename.tex (default is paper.tex)
  -b or --book      assume book format (default is report)
  -a or --no-author suppresses the author listing (good for books)
You probably won't need the following four options:
  -s or --skip      do not create files which already exist
  -p or --no-ps     suppresses creation of the .ps.gz file
  -t or --no-tar    suppresses creation of the .tar.gz file
  -g or --gmake     do not guess: use gmake
  -c or --cake      do not guess: use  cake
  -P		    as -p but also suppresses the hyperlink
  -T		    as -t but also suppresses the hyperlink
  

file.html:
   Contains the title, author, and abstract with hyperlinks to:
       The paper in post-script format (srcdir/invokedir.ps.gz)
       The reproducible package (srcdir/invokedir.tar.gz)
   (invokedir is the invocation directory.)
srcdir:
   The newly created .ps.gz and .tar.gz files go into srcdir.
urlpth:
   urlpth should specify srcdir in url format (used in file.html)
   (Note: url paths might not be identical to Unix paths.)
   urlpth can be absolute or relative (to file.html).

EXAMPLE:

example% pwd
/home/oas/sep/joel/computers
example% paper2html /sepwww/pub/sep/joel/computerspaper . tex=computers.tex > /sepwww/pub/sep/joel/computerspaper/index.html
example% ls /sepwww/pub/sep/joel/computerspaper
index.html      computers.ps.gz       computers.tar.gz

SEE ALSO: 
    book2web, report2web\n";


if ((@ARGV < 2) || (@ARGV > 7)) {
  die "$usage$selfdoc";
}

$srcdir      = $ARGV[0];
$urlpth      = $ARGV[1];
$book_form   = 0;
$no_tar      = 0;
$no_ps       = 0;
$no_tar_link = 0;
$no_ps_link  = 0;
$no_author   = 0;
$skip        = 0;
$texfile     = "paper.tex";
while($ARGV[0]) {
  $_ = shift;
  SWITCH: {
    if (s/^tex=//)      { $texfile   = $_; last SWITCH; }
    if (/^-b/)          { $book_form = 1;  last SWITCH; }
    if (/^--book/)      { $book_form = 1;  last SWITCH; }
    if (/^-t/)          { $no_tar    = 1;  last SWITCH; }
    if (/^--no-tar/)    { $no_tar    = 1;  last SWITCH; }
    if (/^-p/)          { $no_ps     = 1;  last SWITCH; }
    if (/^--no-ps/)     { $no_ps     = 1;  last SWITCH; }
    if (/^-s/)          { $skip      = 1;  last SWITCH; }
    if (/^--skip/)      { $skip      = 1;  last SWITCH; }
    if (/^-c/)          { $use_cake  = 1;  last SWITCH; }
    if (/^--cake/)      { $use_cake  = 1;  last SWITCH; }
    if (/^-g/)          { $use_make  = 1;  last SWITCH; }
    if (/^--gmake/)     { $use_make  = 1;  last SWITCH; }
    if (/^-T/)          { $no_tar    = 1;  $no_tar_link = 1; last SWITCH; }
    if (/^-P/)          { $no_ps     = 1;  $no_ps_link  = 1; last SWITCH; }
    if (/^-a/)          { $no_author = 1;  last SWITCH; }
    if (/^--no-author/) { $no_author = 1;  last SWITCH; }
    $no_op = 1;
  }
}

# set $currdir = the final directory name in pwd
$currdir = `pwd`;
$currdir =~ s#(/.*)*/##;
chop($currdir);

$paper        = $texfile;
$paper        =~ s/(.*)\.tex/\1/;
$psfile       = "$paper.ps";
$expfile      = "junk.paper.tex";
$subfile      = "junk.tex.varsub";
$titlejunk    = "junk.title";
$authorjunk   = "junk.author";
$abstractjunk = "junk.abstract";

# expand the include in $texfile and save the result to $expfile
`septexexpand $texfile > $expfile`;

# perform variable substitution on $expfile
&texsub($expfile, $subfile);

# get the title, author, and abstract
# TITLE
if (system("grep \'\\\\title\' $subfile > /dev/null") == 0) {
    &getdatum("title", $subfile, $titlejunk);
}
else {
    &getdatum("chapter", $subfile, $titlejunk);
}

# AUTHOR
if ($no_author == 0) {
    &getdatum("author", $subfile, $authorjunk);
}

# ABSTRACT
if (system("grep \'^\\\\ABS\' $subfile > /dev/null") == 0) {
    &getabstract($subfile, $abstractjunk);
}
else {
    if (system("grep \'\\\\mhead{INTRODUCTION}\' $subfile > /dev/null") == 0) {
	&getintro($subfile, $abstractjunk);
    }
    else {
	&getbegin($subfile, $abstractjunk, 150);
    }
}

# convert from tex format to plain text
$abstract = `detex $abstractjunk`; &more_detex(*abstract);
$title    = `detex $titlejunk`;    &more_detex(*title);
if ($no_author == 0) {
    $author   = `detex $authorjunk`;   &more_detex(*author);
}

# remove intermediate files
`/usr/bin/rm $abstractjunk`;
`/usr/bin/rm $titlejunk`;
`/usr/bin/rm $authorjunk`;
`/usr/bin/rm $subfile`;
`/usr/bin/rm $expfile`;

# check for cake or make
$make = "gmake"; # set default to gmake
if (system("gmake -n -s clean > /dev/null") == 0) {
    $make = "gmake";
}
else {
    if (system("cake -n -s clean > /dev/null") == 0) {
	$make = "cake";
    }
}
if ($use_cake == 1) { $make =  "cake"; }
if ($use_make == 1) { $make = "gmake"; }

# create .ps.gz version of paper.tex for hyper-linking
$ps_made = 0;
$skip_this_one = $skip && (-f "$srcdir/$currdir.ps.gz");
if (($no_ps == 0) && !($skip_this_one)) {
    if ($book_form) {
	&create_junk_tex;
	print STDERR "** texpr -i -l -d -bib -2 junk.tex 1>&2\n";
        system("texpr -i -l -d -bib -2 junk.tex 1>&2");
        if (system("$make -n -s junk.ps > /dev/null") == 0)
	{
	    $ps_made = 1;
	    print STDERR "** $make junk.ps > /dev/null\n";
	    `$make junk.ps > /dev/null`;
	    print STDERR "** cp junk.ps $currdir.ps\n";
	    `cp junk.ps $currdir.ps`;
	    print STDERR "** /usr/bin/rm junk.ps\n";
	    `/usr/bin/rm junk.ps`;
	}
	print STDERR "** /usr/bin/rm junk.tex\n";
	`/usr/bin/rm junk.tex`;
    }
    else { if (system("$make -n -s $psfile > /dev/null") == 0)
    {
	$ps_made = 1;
	print STDERR "** $make clean   > /dev/null\n";
	`$make clean   > /dev/null`;
	print STDERR "** $make $psfile 1>&2\n";
	system("$make $psfile 1>&2");
	print STDERR "** cp $psfile $currdir.ps\n";
	`cp $psfile $currdir.ps`;
    }}
    if ($ps_made) {
	print STDERR "** gzip $currdir.ps\n";
	`gzip $currdir.ps`;
	print STDERR "** cp $currdir.ps.gz $srcdir/.\n";
	`cp $currdir.ps.gz $srcdir/.`;
	print STDERR "** /usr/bin/rm $currdir.ps.gz\n";
	`/usr/bin/rm $currdir.ps.gz`;
    }
}
   
# create .tar.gz file
$skip_this_one = $skip && (-f "$srcdir/$currdir.tar.gz");
if (($no_tar == 0) && !($skip_this_one)) {
    print STDERR "** $make clean > /dev/null\n";
    `$make clean > /dev/null`;
    print STDERR "** cd ..; tar hcf junk.tar ./$currdir; /usr/bin/mv junk.tar $currdir/$currdir.tar\n";
    `cd ..; tar hcf junk.tar ./$currdir; /usr/bin/mv junk.tar $currdir/$currdir.tar`;
    print STDERR "** gzip $currdir.tar\n";
    `gzip $currdir.tar`;
    print STDERR "** cp $currdir.tar.gz $srcdir/$currdir.tar.gz\n";
    `cp $currdir.tar.gz $srcdir/$currdir.tar.gz`;
    print STDERR "** /usr/bin/rm $currdir.tar.gz\n";
    `/usr/bin/rm $currdir.tar.gz`;
}

$psname = "$srcdir/$currdir.ps.gz";
$pslink = "$urlpth/$currdir.ps.gz";
if (($no_ps_link == 0) && (-f $psname)) { # set up a hyperlink
    $size = (stat($psname))[7];
    $size = int($size/1024);
    $line1 = "<A HREF =$pslink>$title (ps ${size}K)</A>";
}
else {
    $line1 = "<STRONG>$title</STRONG>";
}

# create html file
print "$line1";

$tarname = "$srcdir/$currdir.tar.gz";
$tarlink = "$urlpth/$currdir.tar.gz";
if (($no_tar_link == 0) && (-f $tarname)) {
    $tarsize = (stat($tarname))[7];
    $tarsize = int($tarsize/1024);
    print " , <A HREF =$tarlink>(src ${tarsize}K)</A>";
}
print "\n<BR><SMALL>\n";
if ($no_author == 0) {
    print "<STRONG>by $author</STRONG>\n";
}
print "<P>$abstract</SMALL>\n<P>\n\n";

exit;

# SUBROUTINES

# texsub attempts to perform variable substitutions on a tex file
sub texsub{
   local($infile, $outfile) = @_;
   open(IFILE, "<$infile");
   open(OFILE, ">$outfile");
   %curr_def_tokens = ();
   while (<IFILE>) {
	# check the line for "\def"
	if (/^\\def\\([^{]*){(.*)}$/) {
	     $curr_def_tokens{$1} = $2;
	   }
	else {
	     foreach $token (sort keys(%curr_def_tokens)) {
		  s/{\\$token}/$curr_def_tokens{$token}/g;
		  s/\\$token([^a-zA-Z])/$curr_def_tokens{$token}\1/g;
	     }    
	     print OFILE $_;
	}
   }
   close(IFILE);
   close(OFILE);
}

# Retrieves the abstract from a tex-file.
sub getabstract{
   local($infile, $outfile) = @_;
   open(IFILE, "<$infile");
   open(OFILE, ">$outfile");
   $not_found = 1;
   $tmp1 = $*; $tmp2 = $/;
   $* = 1; $/ = "{"; # set input record separator to {
   while (<IFILE>) {
     if ($_ =~ /^\\ABS\s*\{/) {
	  $* = $tmp1; $/ = $tmp2;
	  $str = "{".<IFILE>;
	  &close_bracket(*str, *IFILE);
          print OFILE $str;
	  $not_found = 0;
          last;
     }
     if ($_ =~ /^\\mhead\s*\{\s*INTRODUCTION\s*\}/) {
	  foreach $n (1..5) { # use the first five lines
	      $* = $tmp1; $/ = $tmp2;
	      if (<IFILE>) { print OFILE $_; }
	  }
	  $not_found = 0;
          last;
      }
   }

   if ($not_found) {
       print OFILE "No abstract.\n";
   }
   $* = $tmp1; $/ = $tmp2;
   close(IFILE);
   close(OFILE);
}

# Retrieves the introduction from a tex-file.
sub getintro{
   local($infile, $outfile) = @_;
   open(IFILE, "<$infile");
   open(OFILE, ">$outfile");
   while (<IFILE>) {
     if ($_ =~ /^\\mhead\s*\{\s*INTRODUCTION\s*\}/) {
	 $n = 0;
	 while (<IFILE>) {
	     $n = $n + split;
	     print OFILE $_;
	     if ($n > 100) { # get only the first 100 words
		 last;
	     }
	 }
	 print OFILE " ... ";
	 last;
     }
   }
   close(IFILE);
   close(OFILE);
}

sub getbegin{
    local($infile, $outfile, $num_tokens) = @_;
    open(IFILE, "<$infile");
    open(OFILE, ">$outfile");
    $n = 0;
    while (<IFILE>) {
	if ((/^\\footnote\{/) ||
	    (/^\\chapterlabel\{/) ||
	    (/^\\pagenumbering\{/) ||
	    (/^\\def\\/) ||
	    (/^\\sx\{/) ||
	    (/^\\todo\{/) ||
	    (/^\\index\{/) ||
	    (/^\\chapter\{/))
        {
	    $str = $_;
	    close_bracket(*str, *IFILE);
	    $str =~ /\}([^}]*)$/;
	    print OFILE $1;
	    next;
	}
	print OFILE $_;
	$n = $n + split;
	if ($n >= $num_tokens) { last; }
    }
    print OFILE " ...\n";
    close(IFILE);
    close(OFILE);
}

# Retrieves the portion of a tex-file corresponding to \$datum_name
# For example "\author" or "\title"
sub getdatum{
   local($datum_name, $infile, $outfile) = @_;
   open(IFILE, "<$infile");
   open(OFILE, ">$outfile");
   $not_found = 1;
   $tmp1 = $*; $tmp2 = $/;
   $* = 1; $/ = "{"; # set input record separator to {
   while (<IFILE>) {
     if ( $_ =~ /^\\$datum_name\s*\{/ ) {
	  $* = $tmp1; $/ = $tmp2; # reset old parsing values
	  $str = "{".<IFILE>;
	  &close_bracket(*str, *IFILE);
          print OFILE $str;
	  $not_found = 0;
          last;
     }
   }
   if ($not_found) {
      print OFILE "$datum_name: not found.\n";
   }
   $* = $tmp1; $/ = $tmp2; # reset old parsing values
   close(IFILE);
   close(OFILE);
}

# Search for closing brackets (allowing nesting)
sub close_bracket{
   local(*str, *IFILE) = @_;
   $nest_level = 0;
   &nest_depth(*nest_level, $str);
   if ($nest_level > 0) {
       while (<IFILE>) {
	   $str = $str.$_;
	   &nest_depth(*nest_level, $_);
	   if ($nest_level <= 0) { last; }
       }
   }
}

sub nest_depth{
   local(*count, $str) = @_;
   $count = $count + ($str =~ s/{//g);
   $count = $count - ($str =~ s/}//g);
}

# Perform certain steps of the conversion from tex format to
# plain text that "detex" fails to do.
sub more_detex{
   local(*texstring) = @_;
   $texstring =~ s/~/ /g;
}

# this expands the includes of a .tex file
# on entry, both IFILE and OFILE should be open
sub texexp{
   local(*IFILE, *OFILE) = @_;
   while (<IFILE>) {
        s/\\sepinclude/\\input/;
        s/\\include/\\input/;
        s/\\sepinput/\\input/;
	if (s/\\input\s*{([^}]+)}.*\n$/\1/) {
	     if (open(IFILE2, "<$_") || open(IFILE2, "<$_.tex")) {
		  &texexp(*IFILE2, *OFILE);
	     }
	     else {
		  print STDERR "File not found: $_\n";
	     }
	}
	else {
	     print OFILE $_;
	}
   }
   close (IFILE);		  
}

sub create_junk_tex{
    open(OFILE,">junk.tex");

    print OFILE "\\documentstyle\[12pt,xtex,fgdp\]\{book\}";
    print OFILE "\n\n";
    print OFILE "\\begin\{document\}\n";
    print OFILE "\\interactive\n";
    print OFILE "\\noshowiex\n";
    print OFILE "\n";
#    print OFILE "\\long\\def\\HideThis#1\{\}\n";
    print OFILE "\\long\\def\\HIDE#1\{#1\}\n";
    print OFILE "\n";
    print OFILE "\\def\\WHERE\{..\}\n";
    print OFILE "\\def\\figdir\{./Fig\}\n";
    print OFILE "\\def\\LIB\{../Lib\}\n";
    print OFILE "\n";
    if (-f "../Adm/macros.tex") {
	print OFILE "\\sepinput\{../Adm/macros\}\n";
    }
    print OFILE "\\includepf\{.\}\{$paper\}\n";
    print OFILE "\\end\{document\}\n";

    close(OFILE);
}
