summaryrefslogtreecommitdiff
path: root/manual/tools/caml-tex
blob: 7eea11b56314f8e96bde7f6150b4585c8bb9e74e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/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 STDERR $lastread;
	    $lastread = <TOPLEVEL>;
	  }
        }
      }
    }
    else {
      print OUT $_;
    }
  }
  close(IN);
}

close(TOPLEVEL);