Re: ocaml-tex ?

Xavier Leroy (xleroy@pauillac.inria.fr)
Wed, 9 Oct 1996 10:49:42 +0200 (MET DST)

From: Xavier Leroy <xleroy@pauillac.inria.fr>
Message-Id: <199610090849.KAA23511@pauillac.inria.fr>
Subject: Re: ocaml-tex ?
To: Christine.Paulin@ens-lyon.fr (Christine Paulin)
Date: Wed, 9 Oct 1996 10:49:42 +0200 (MET DST)
In-Reply-To: <199610061538.RAA03927@aquavit.ens-lyon.fr> from "Christine Paulin" at Oct 6, 96 05:38:25 pm

[Christine Paulin was asking for a version of the caml-tex formatter
that works with Objective Caml. One is at the end of this message.]

> Je ne trouve pas dans la distribution trace d'un outil analogue a
> caml-tex compatible avec ocaml. Une modification naive du scrip caml-tex
> ne semble pas suffisante.

Nous avons une version modifiee de caml-tex pour Objective Caml qui
sert a fabriquer la documentation. Elle n'est pas dans la distribution
pour diverses raisons, en particulier parce que le perl script n'est
pas tres propre et qu'il faudrait trouver mieux. Je l'inclus a la fin
de ce message. Attention, ca marche avec Objective Caml 1.02 mais pas
1.01 (changement des prompts du system interactif).

- Xavier Leroy

#!/usr/local/bin/perl

$camllight = "TERM=dumb ocaml";
$camlbegin = "\\caml\n";
$camlend = "\\endcaml\n";
$camlin = "\\?";
$camlout = "\\:";
$camlblank = "\\;\n";

$linelen = 72;
$output = "";
$cut_at_blanks = 0;

while ($#ARGV >= 0) {
$_ = $ARGV[0];
last unless (/^-/);
$linelen = $ARGV[1], shift, shift, next if (/^-n$/);
$output = $ARGV[1], shift, shift, next if (/^-o$/);
$camllight = $ARGV[1], shift, shift, next if (/^-caml$/);
$cut_at_blanks = 1, shift, next if (/^-w$/);
printf STDERR ("Unknown option '%s', ignored\n", $_);
shift;
}

# First pass: extract the Caml phrases to evaluate

open(ML, "> .input.ml") || die("Cannot create .input.ml : $!");

foreach $infile (@ARGV) {
open(IN, $infile) || die("Cannot open $infile : $!");
while(<IN>) {
if (m/^\\begin{caml_(example|example\*|eval)}\s*$/) {
while(<IN>) {
last if m/^\\end{caml_(example|example\*|eval)}\s*$/;
print ML $_;
}
}
}
close(IN);
}

close(ML);

# Feed the phrases to a Caml toplevel

open(TOPLEVEL, "$camllight 2>&1 < .input.ml |") ||
die("Cannot start camllight : $!");

<TOPLEVEL>; <TOPLEVEL>; # skip the banner
$lastread = <TOPLEVEL>;
$lastread =~ s/^# //;

# Second pass: shuffle the TeX source and the output of the toplevel

if ($output) {
if ($output eq "-") {
open(OUT, ">&STDOUT");
} else {
open(OUT, ">$output") || die("Cannot create $output: $!");
}
}

foreach $infile (@ARGV) {
open(IN, $infile) || die("Cannot open $infile: $!");
if (! $output) {
$outfile = $infile;
$outfile =~ s/\.tex$//;
open(OUT, "> $outfile.ml.tex") || die("Cannot create $outfile.ml.tex: $!");
}
while(<IN>) {
if (m/^\\begin{caml_example(\*?)}\s*$/) {
$omit_answer = $1; # true if caml_example*, false if caml_example
print OUT $camlbegin;
$severalphrases = 0;
while(<IN>) {
last if m/\\end{caml_example\*?}\s*$/;
print OUT $camlblank if ($severalphrases);
while(1) {
s/\\/\\\\/g;
print OUT $camlin, $_;
last if m/;; *$/;
$_ = <IN>;
}
while ($lastread =~ s/^ //) { }
while($lastread) {
last if $lastread =~ s/^# //;
print STDERR $lastread;
if (! $omit_answer) {
while (length($lastread) > $linelen) {
if ($cut_at_blanks) {
$cutpos = rindex($lastread, ' ', $linelen);
if ($cutpos == -1) { $cutpos = $linelen; } else { $cutpos++; }
} else {
$cutpos = $linelen;
}
$line = substr($lastread, 0, $cutpos);
$line =~ s/\\/\\\\/g;
print OUT $camlout, $line, "\n";
$lastread = substr($lastread, $cutpos,
length($lastread) - $cutpos);
}
$lastread =~ s/\\/\\\\/g;
print OUT $camlout, $lastread;
}
$lastread = <TOPLEVEL>;
}
$severalphrases = 1;
}
print OUT $camlend;
}
elsif (m/^\\begin{caml_eval}\s*$/) {
while(<IN>) {
last if m/^\\end{caml_eval}\s*$/;
if (m/;; *$/) {
while ($lastread =~ s/^#//) { }
while($lastread) {
last if $lastread =~ s/^#//;
print $lastread;
$lastread = <TOPLEVEL>;
}
}
}
}
else {
print OUT $_;
}
}
close(IN);
}

close(TOPLEVEL);