#!/usr/bin/env perl

sub printTeX
{ s/`([@\w]+)\s*<->([a-z]\w*)/\\index\{\l\1,\\both\{\2\}\}`\\classboth\{\1\}\{\2\}/g;
  s/`([@\w]+)\s*<-([a-z]\w*)/\\index\{\l\1,\\get\{\2\}\}`\\classget\{\1\}\{\2\}/g;
  s/`([@\w]+)\s*->([a-z]\w*)/\\index\{\l\1,\\send\{\2\}\}`\\classsend\{\1\}\{\2\}/g;
  s/<->([a-z]\w*)/\\both\{\1\}/g;
  s/<-([a-z]\w*)/\\get\{\1\}/g;
  s/->([a-z]\w*)/\\send\{\1\}/g;
  s/(^|\s|\()([a-z]\w+)\/((\d+|\[\d+(-|,)\d+\]))/\1\\index\{\2\/\3\}\\predref\{\2\}\{\3\}/g;
  s/(\s+|^)([a-z]\w+)\/\/((\d+|\[\d+(-|,)\d+\]))/\1\\index\{\2\/\/\3\}\\dcgref\{\2\}\{\3\}/g;
  s/(\w\.\w)\.(\s+[a-z])/\1.\\\2/g;
  s/(^|[^'"\$])<(\w[-~a-z]*\w)>/\1\\bnfmeta\{\2\}/g;
  s/\\class\{([<\\=>]*)\}/\\verb!\1!/g;
  s/==>/\$\\longrightarrow\$/g;
  s/^((\\index\{[^\}]+\})+) *$/\1%/;
  s/(\\index\{[^\}]*)\\index\{[^\}]*\}([^\}]*\})/\1\2/g;
  s/(\\class(get|send|both)\{)\\index\{[^\}]*\}/\1/g;
  s/(PL_[a-z_0-9]*)\(([^\)]*)\)/\\cfuncref\{\1\}\{\2\}/g;

# Prolog special arguments ...
# TBD: pick these up automatically from pl.sty

  s/\\file\{([^\}]*\\bnfmeta[^\}]*)\}/\\metafile\{\1\}/g;
  s/\\file\{([^\}]*\\arg[^\}]*)\}/\\metafile\{\1\}/g;
  s/\\file\{([^\}]+)\}/\\file@\1@/g;
  s/\\htmloutput\{([^\}]+)\}/\\htmloutput@\1@/g;

  s/\{#!\}/\{\\Sexe\}/g;
  s/\{#>\}/\{\\Scgt\}/g;
  s/\{#>=\}/\{\\Scge\}/g;
  s/\{#<\}/\{\\Sclt\}/g;
  s/\{#=<\}/\{\\Scle\}/g;
  s/\{#=\}/\{\\Sceq\}/g;
  s/\{#\\=\}/\{\\Scne\}/g;
  s/\{#\\\}/\{\\Snot\}/g;
  s/\{#\\\/\}/\{\\Sor\}/g;
  s/\{#\/\\\}/\{\\Sand\}/g;
  s/\{#<=>\}/\{\\Sequiv\}/g;
  s/\{#<=\}/\{\\Slimpl\}/g;
  s/\{#=>\}/\{\\Srimpl\}/g;
  s/\{#<==\}/\{\\Slimplies\}/g;
  s/\{#==>\}/\{\\Srimplies\}/g;
  s/\{#<==>\}/\{\\Scequal\}/g;
  s/\{#=\\=\}/\{\\Scine\}/g;
  s/\{#=:=\}/\{\\Scieq\}/g;
  s/\{#\}/\{\\Shash\}/g;
  s/\{!\}/\{\\Scut\}/g;
  s/\{,\}/\{\\Scomma\}/g;
  s/\{->\}/\{\\Sifthen\}/g;
  s/\{\*->\}/\{\\Ssoftcut\}/g;
  s/\{\.\}/\{\\Sdot\}/g;
  s/\{;\}/\{\\Ssemicolon\}/g;
  s/\{<\}/\{\\Slt\}/g;
  s/\{><\}/\{\\Sxor\}/g;
  s/\{=\}/\{\\Seq\}/g;
  s/\{=\.\.\}/\{\\Suniv\}/g;
  s/\{=:=\}/\{\\Saeq\}/g;
  s/\{=<\}/\{\\Sle\}/g;
  s/\{<=\}/\{\\Sel\}/g;
  s/\{==\}/\{\\Sequal\}/g;
  s/\{=@=\}/\{\\Sstructeq\}/g;
  s/\{\\=@=\}/\{\\Sstructneq\}/g;
  s/\{=\\=\}/\{\\Sane\}/g;
  s/\{>\}/\{\\Sgt\}/g;
  s/\{>=\}/\{\\Sge\}/g;
  s/\{>=<\}/\{\\Seqbowtie\}/g;
  s/\{>:<\}/\{\\Smappunify\}/g;
  s/\{:<\}/\{\\Smapselect\}/g;
  s/\{@<\}/\{\\Stlt\}/g;
  s/\{@=<\}/\{\\Stle\}/g;
  s/\{@>\}/\{\\Stgt\}/g;
  s/\{@>=\}/\{\\Stge\}/g;
  s/\{\\\+\}/\{\\Snot\}/g;
  s/\{\\=\}/\{\\Sne\}/g;
  s/\{\\==\}/\{\\Snequal\}/g;
  s/\{\^\}/\{\\Shat\}/g;
  s/\{\|\}/\{\\Sbar\}/g;
  s/\{\*\}/\{\\Stimes\}/g;
  s/\{\*\*\}/\{\\Spow\}/g;
  s/\{\+\}/\{\\Splus\}/g;
  s/\{-\}/\{\\Sminus\}/g;
  s/\{\/\}/\{\\Sdiv\}/g;
  s/\{\/\/\}/\{\\Sidiv\}/g;
  s/\{\/\\\}/\{\\Sand\}/g;
  s/\{<<\}/\{\\Slshift\}/g;
  s/\{>>\}/\{\\Srshift\}/g;
  s/\{\\\}/\{\\Sneg\}/g;
  s/\{\\\/\}/\{\\Sor\}/g;
  s/\{\$\}/\{\\Sdollar\}/g;
  s/\{\?\}/\{\\Squest\}/g;
  s/\{:\}/\{\\Smodule\}/g;
  s/\{:-\}/\{\\Sneck\}/g;
  s/\{\?-\}/\{\\Sdirective\}/g;
  s/\{-->\}/\{\\Sdcg\}/g;
  s/\{~\}/\{\\Stilde\}/g;
  s/\{%\}/\{\\Spercent\}/g;
  s/\{\{\}\}/\{\\Scurl\}/g;
  s/\{\[\|\]\}/\{\\Scons\}/g;
  s/\{xXX..\\\}/\{\\SxXX\}/g;

  s/\\file@([^@]+)@/\\file\{\1\}/g;
  s/\\htmloutput@([^@]+)@/\\htmloutput\{\1\}/g;

  print;
}


sub expandTabs
{ while ( ($i = index($_, "\t")) != $[-1 )
  { $nspaces = 8 - $i % 8;
    for( $spaces="", $i=0; $i<$nspaces; $i++ )
    { $spaces .= " ";
    }
    s/\t/$spaces/;
  }
}


sub
expandSpecials
{ s/\^/\\verb!^!/g;
  s/\|/\\verb!|!/g;
}


sub printCode
{ print;
  while (<ARGV> )
  { &expandTabs;
    print;
    if ( /\\end\{(code|verbatim)\}/ )
    { return;
    }
  }
}


sub printPceCode
{ $line = 0;
  print;
  while (<ARGV> )
  { $line++;
    &expandTabs;
    if ( /\\end\{pcecode\}/ )
    { print;
      return;
    }
    chomp;
    print "\\lineno{$line}\\verb`$_`\n";
  }
}


sub skiptonext
{ while (<ARGV>)
  { if ( ! /^\s*$/ )
    { return;
    }
    last;
  }
  while (<ARGV>)
  { if ( ! /^\s*$/ )
    { return;
    }
  }
}

#	MAIN PROGRAM

while (<>)
{ while ( /\\begin\{pcecode\}/ )
  { &printPceCode;
    print "\n\\noindent\n";
    &skiptonext;
  }
  while ( /\\begin\{(code|verbatim)\}/ )
  { &printCode;
    print "\n\\noindent\n";
    &skiptonext;
  }
  &printTeX;
}
