source: git/doc/doc2tex.pl @ 460c1e1

spielwiese
Last change on this file since 460c1e1 was 460c1e1, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* increased version 1o 1-3-4 * parsing of help strings by doc2tex * much better texi2html * new directory layout for install in source tree git-svn-id: file:///usr/local/Singular/svn/trunk@3292 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 24.4 KB
Line 
1#!/usr/local/bin/perl
2# $Id: doc2tex.pl,v 1.9 1999-07-19 12:06:13 obachman Exp $
3###################################################################
4#  Computer Algebra System SINGULAR
5#
6#  doc2tex: utility to generate the Singular manual
7#
8####
9# @c example [error]
10#    -> the text till the next @c example is feed into Singular,
11#       the text is then substituted by
12#       @c computed example $example $doc_file:$line
13#       <text from the input>
14#       @expansion{} <corresponding output>
15#       ....
16#       @c end computed example $example $doc_file:$line
17#       reuse computed examples if ($reuse && -r $example.inc)
18#       cut absolute directory names from the loaded messages
19#       substituted @,{ and } by @@, @{ resp. @}
20#       wrap around output lines  longer than $ex_length = 73;
21#       Processing is aborted if error occures in Singular run,
22#       unless 'error' is specified
23#
24####
25# @c include file
26#    -> copy content of file into output file protecting texi special chars
27#
28####
29# @c ref
30# ....
31# @c ref
32#    -> scans intermediate lines for @ref{..} strings
33#    Creates menu of (sorted) refs for ifinfo
34#    Creates comma-separated (sorted) refs for iftex, prepended with
35#    the text before first @ref.
36#
37####
38# @c lib libname.lib[:proc] [no_ex, lib_fun, lib_ex]
39#   Without :proc
40#   --> includes info of libname.lib in output file
41#   --> includes function names of info into function index
42#   --> if lib_fun is given, includes listing of functions and
43#                      their help into output file
44#   --> if lib_ex is given, includes computed examples of functions, as well
45#   With :proc
46#   --> includes content of procedure 'proc' from library libname:lib
47#
48#   Optional no_ex, lib_fun, lib_ex arguments overwrite respective
49#    command-line arguments
50#
51#
52###################################################################
53
54#
55# default settings of command-line arguments
56#
57$Singular = "../Singular/Singular"; # should be overwritten
58$libparse = "../Singular/libparse"; # change in final version
59$Singular_opts = " -teqr12345678";
60$clean = 0;
61$verbose = 1;
62$reuse = 1;
63$no_ex = 0;
64$lib_fun = 0;
65$lib_ex = 0;
66$doc_subdir = "./d2t_singular";
67@include_dirs = (".", "../Singular/LIB");
68$doc_examples_db = "$doc_subdir/examples";
69
70#
71# misc. defaults
72#
73$ex_length = 73;
74$ERROR = "\n**** Error:";
75$WARNING = "\n** Warning:";
76
77#
78# flush stdout and stderr after every write
79#
80select(STDERR);
81$| = 1;
82select(STDOUT);
83$| = 1;
84
85#
86# get file to convert
87#
88$doc_file = pop(@ARGV);
89if ($doc_file =~  /(.+)\..*$/)
90{
91  die "*** Error: Need .doc file as input\n" . &Usage 
92    unless ($doc_file =~ /(.+)\.doc$/);
93}
94else
95{
96  if ($doc_file =~ /^-h(elp)?$/) { print &Usage; exit;}
97  $doc_file .= ".doc";
98}
99
100#
101# parse command line options
102#
103$args = join(" ", @ARGV);
104while (@ARGV && $ARGV[0] =~ /^-/) 
105{
106  $_ = shift(@ARGV);
107  if (/^-S(ingular)?$/)  { $Singular = shift(@ARGV); next;}
108  if (/^-l(ibparse)?$/)  { $libparse = shift(@ARGV); next;}
109  if (/^-o(output)?$/)   { $tex_file = shift(@ARGV); next;}
110  if (/^-no_r(euse)?$/)  { $reuse = 0; next;}
111  if (/^-c(lean)?$/)     { $clean = 1; next;}
112  if (/^-no_e(x)?$/)     { $no_ex = 1; next;}
113  if (/^-lib_fu(n)?$/)   { $lib_fun = 1;next;}
114  if (/^-lib_e(x)?$/)    { $lib_ex = 1; next;}
115  if (/^-s(ubdir)?$/)    { $doc_subdir = shift(@ARGV); next;}
116  if (/^-I$/)            { unshift(@include_dirs, shift(@ARGV)); next;}
117  if (/^-v(erbose)?$/)   { $verbose = shift(@ARGV); next;}
118  if (/^-h(elp)?$/)      { print &Usage; exit;}
119  die &Usage;
120}
121$verbose = ($verbose < 0 ? 0 : $verbose);
122
123#
124# construct filenames
125#
126($doc_dir = $doc_file) =~ s/(.+)\.doc$/$1/;
127if ($doc_dir =~ /(.*)\//)
128{
129  $doc = $';
130  $doc_dir = $1;
131}
132else
133{
134  $doc = $doc_dir;
135  $doc_dir = ".";
136}
137$tex_file = "$doc_dir/$doc.tex" unless ($tex_file);
138               
139#
140# open files
141#
142open(DOC, "<$doc_file") 
143  || Error("can't open $doc_file for reading: $!\n" . &Usage);
144open(TEX, ">$tex_file") || Error("can't open $tex_file for writing: $!\n");
145print "d2t: Generating $tex_file from $doc_file ...\n" if ($verbose > 1);
146print "d2t: $doc_file ==> $tex_file\n" if ($verbose == 1);
147if (-d $doc_subdir)
148{
149  print "d2t: Using $doc_subdir for intermediate files\n" 
150    if ($verbose > 1);
151}
152else
153{
154  mkdir($doc_subdir, oct(755)) 
155    || Error("can't create directory $doc_subdir: $!\n");
156  print "d2t: Created $doc_subdir for intermediate files\n" 
157    if ($verbose > 1);
158}
159
160dbmopen(%EXAMPLES, $doc_examples_db, oct(755)) || die "$ERROR: can't open examples data base: $!\n";
161
162#######################################################################
163#
164# go !
165#
166while (<DOC>)
167{
168  $line++;
169 
170  if (/^\@c\s*example/)     {&HandleExample; next;}
171  if (/^\@c\s*include\s+/)  {&HandleInclude; next;}
172  if (/^\@c\s*ref\s*$/)     {&HandleRef; next;}
173  if (/^\@c\s*lib\s+/)      {&HandleLib; next;}
174  if (/^\@setfilename/)     {print TEX "\@setfilename $doc.hlp\n"; next;}
175                             
176  print TEX $_;
177
178  if (/^\@bye$/)            {last;}
179}
180
181#
182# wrap up
183#
184close(TEX);
185dbmclose(%EXAMPLES);
186print "\nd2t: Finished generation of $tex_file \n" if ($verbose > 1);
187print "\n" if ($verbose == 1);
188
189
190######################################################################
191# @c example [error]
192#    -> the text till the next @c example is feed into Singular,
193#       the text is then substituted by
194#       @c computed example $example $doc_file:$line
195#       <text from the input>
196#       @expansion{} <corresponding output>
197#       ....
198#       @c end computed example $example $doc_file:$line
199#       reuse computed examples if ($reuse && -r $example.inc)
200#       cut absolute directory names from the loaded messages
201#       substituted @,{ and } by @@, @{ resp. @}
202#       wrap around output lines  longer than $ex_length = 73;
203#       Processing is aborted if error occures in Singular run,
204#       unless 'error' is specified
205sub HandleExample
206{
207  my($lline, $thisexample, $include, $error_ok);
208 
209  $lline = $line;
210  $example++;
211
212  if ($no_ex)
213  {
214    print "{$example}" if ($verbose);
215    print TEX "\@c skipped computation of example $example $doc_file:$lline \n";
216   
217  }
218
219  $thisexample = '';
220  $error_ok = 1 if /error/;
221  # print content in example file till next @c example
222  while (<DOC>)
223  {
224    $line++;
225    last if (/^\@c\s*example\s*$/);
226    s/^\s*//; # remove preceeding white spaces
227    if ($no_ex)
228    {
229      &protect_texi;
230      print TEX $_;
231    }
232    else
233    {
234      $thisexample .= $_ unless (/^\s*$/);
235    }
236  }
237  Error("no matching '\@c example' found for $doc_file:$lline\n")
238    unless (/^\@c\s*example\s*$/);
239
240  # done, if no examples
241  return if ($no_ex);
242
243  # check whether it can be reused
244  $include = $EXAMPLES{$thisexample};
245  if ($reuse && ($include = $EXAMPLES{$thisexample}))
246  {
247    print "<$example>" if ($verbose);
248    print TEX "\@c reused example $example $doc_file:$lline \n";
249  }
250  else
251  {
252    print "($example" if ($verbose == 1);
253    my ($ex_file, $res_file, $inc_file);
254    $inc_file = "$doc_subdir/$doc"."_$example.inc";
255    $ex_file = "$doc_subdir/$doc"."_$example.tst";
256    $res_file = "$doc_subdir/$doc"."_$example.res";
257
258    print TEX "\@c computed example $example $doc_file:$lline \n";
259
260    # run singular
261    open(EX, ">$ex_file") || Error("can't open $ex_file for writing: $!\n");
262    print EX "$thisexample\$\n";
263    close(EX);
264
265    &System("$Singular $Singular_opts $ex_file > $res_file");
266    print ")" if ($verbose == 1);
267
268    open(RES, "<$res_file") || Error("can't open $res_file for reading: $!\n");
269    open(INC, ">$inc_file") || Error("can't open $inc_file for writing: $!\n");
270
271    $include = '';
272    # get result, manipulate it and put it into inc file
273    while (<RES>)
274    {
275      last if (/^$ex_file\s*([0-9]+)..\$/);
276      # check for error
277      Error("while running example $example from $doc_file:$lline.\nCall: '$Singular $Singular_opts $ex_file > $res_file'\n")
278        if (/error occurred/ && ! $error_ok);
279      # remove stuff from echo
280      if (/^$ex_file\s*([0-9]+)../)
281      {
282        $_ = $';
283        &protect_texi;
284      }
285      else
286      {
287        local($to_do, $done);
288        # remove absolute path names from laoded messages
289        s/^(\/\/ \*\* loaded )(.*)\/(.+).lib(.*)/$1$3.lib$4/;
290        # shorten error occurred in messages
291        s/\? error occurred in [^ ]* line/\? error occurred in line/;
292        # break after $ex_length characters
293        $to_do = $_;
294        while (length($to_do) > $ex_length && $to_do =~ /\w/)
295        {
296          $done .= substr($to_do, 0, $ex_length)."\\\n   ";
297          $to_do = substr($to_do, $ex_length + 1);
298        }
299        $_ = $done.$to_do if($done);
300        &protect_texi;
301        $_ = "\@expansion{} ".$_;
302      }
303      $include .= $_;
304      print INC $_;
305    }
306    close(RES);
307    close(INC);
308    unlink $ex_file, $res_file, $inc_file if ($clean);
309    $EXAMPLES{$thisexample} = $include;
310  }
311  print TEX $include;
312  print TEX "\@c end example $example $doc_file:$lline\n";
313}
314 
315######################################################################
316# @c include file
317#    -> copy content of file into output file protecting texi special chars
318sub HandleInclude
319{
320  s/^\@c\s*include\s+([^\s]+)\s/$1/;
321  s/\s*$//;
322  unless (&Open(*INC, "<$_"))
323  {
324    warn "$WARNING HandleInclude: can't open $_ for reading\n";
325    print TEX "\@c include file $_ not found\n";
326    return;
327  }
328  print "<$_>" if ($verbose);
329  print TEX "\@c begin included file $_ from $doc_file:$line\n";
330  while (<INC>)
331  {
332    &protect_texi;
333    print TEX $_;
334  }
335  print TEX "\@c end included file from $doc_file:$line\n";
336  close (INC);
337}
338
339######################################################################
340# @c ref
341# ....
342# @c ref
343#    -> scans intermediate lines for @ref{..} strings
344#    Creates menu of (sorted) refs for ifinfo
345#    Creates comma-separated (sorted) refs for iftex, prepended with
346#    the text before first @ref.
347
348sub HandleRef
349{
350  local(%refs, @refs, $header, $lline, $lref);
351 
352  print TEX "\@c inserted refs from $doc_file:$line\n";
353 
354  # scan lines use %ref to remove duplicates
355  $lline = $line;
356  while (<DOC>)
357  {
358    $line++;
359    last if (/^\@c\s*ref\s*$/);
360   
361    while (/\@ref{(.*?)}/)
362    {
363      $refs{$1} = 1;
364      $_ = $';
365      unless ($header)
366      {
367        $header = $`;
368        $header = " " unless ($header);
369      }
370    }
371  }
372  die "$ERRROR no matching \@c ref found for $doc_file:$lline\n" 
373    unless (/^\@c\s*ref\s*$/);
374  # sort refs
375  @refs = sort(keys(%refs));
376  # put them out
377  print TEX "\@ifinfo\n\@menu\n";
378  foreach $ref (@refs) {print TEX "* ".$ref."::\n";}
379  print TEX "\@end menu\n\@end ifinfo\n\@iftex\n";
380
381  if ($header ne " ")
382  {
383    print TEX "$header\n" unless ($header eq " ");
384  }
385  else
386  {
387    print TEX "\@strong{See also:}\n";
388  }
389  $lref = pop(@refs);
390  foreach $ref (@refs) {print TEX "\@ref{".$ref."};\n";}
391  print TEX "\@ref{".$lref."}.\n" if ($lref); 
392  print TEX "\@end iftex\n\@c end inserted refs from $doc_file:$lline\n";
393}
394
395###################################################################
396#
397# @c lib libname.lib [no_ex, lib_fun, lib_ex]
398#   --> includes info of libname.lib in output file
399#   --> includes function names of info into function index
400#   --> if lib_fun is given, includes listing of functions and
401#                      their help into output file
402#   --> if lib_ex is given, includes computed examples of functions, as well
403#
404# Optional no_ex, lib_fun, lib_ex arguments overwrite respective
405# command-line arguments
406#
407
408sub HandleLib
409{
410  local($lib, $lib_name, $ltex_file, $l_ex, $l_fun, $no_node, $section);
411  my ($func);
412
413  if (/^\@c\s*lib\s+([^\.]+)\.lib(.*)/)
414  {
415    $lib = $1;
416    $lib_name = $lib.".lib";
417    $_ = $2;
418  }
419  else
420  {
421    warn "$WARNING need .lib file to process '$_'\n";
422    print TEX $_;
423    return;
424  }
425
426  $func = $1 if (/^:(.*?) /);
427  $l_fun = 1 if (($lib_fun || (/lib_fun/)) && !/no_fun/);
428  $l_ex = 1 if (($lib_ex || /lib_ex/) && !/no_ex/ && $l_fun);
429  if (/(\w+)section/)
430  {
431    $section = $1. 'section';
432  }
433  else
434  {
435    $section = "subsection";
436  }
437  $ltex_file = "$doc_subdir/$lib"."_lib";
438  unless ($l_ex)
439  {
440    if ($l_fun)
441    {
442      $ltex_file .= "_noEx";
443    }
444    else
445    {
446      $ltex_file .= "_noFun";
447    }
448  }
449  $ltex_file .= ".tex";
450 
451  Error("can't open $lib.lib for reading: $!\n") 
452    unless  ($lib_dir = &Open(*LIB, "<$lib.lib"));
453  close (LIB);
454  if ($reuse && open(LTEX, "<$ltex_file") && 
455      IsNewer($ltex_file, "$lib_dir/$lib.lib"))
456  {
457    unless ($func)
458    {
459      print "<lib $lib>" if ($verbose);
460      print TEX "\@c reused lib docu for $lib_name $doc_file:$line \n";
461    }
462  }
463  elsif (&GenerateLibDoc($lib, $ltex_file, $l_fun, $l_ex))
464  {
465    print TEX "\@c generated lib docu for $lib_name $doc_file:$line \n"
466      unless $func;
467    open(LTEX, "<$ltex_file") 
468      || Error("can't open $ltex_file for reading: $!\n");
469  }
470  if ($func)
471  {
472    print "<$lib:$func" if $verbose;
473    print TEX "\@c generated lib proc docu for $lib_name:$func $doc_file:$line \n";
474    my $found = 0;
475    while (<LTEX>)
476    {
477      $found = 1 if /c ---content $func---/;
478      print TEX $_ if $found;
479      last if $found && /c ---end content $func---/;
480    }
481    if ($found)
482    {
483      Error("no end content found for lib proc docu for $lib_name:$func $doc_file:$line \n")
484        unless (/c ---end content $func---/);
485      print TEX "\@c generated lib proc docu for $lib_name:$func $doc_file:$line \n";
486    }
487    else
488    {
489      Error("did not find lib proc docu for $lib_name:$func $doc_file:$line \n");
490    }
491    print ">" if $verbose;
492  }
493  else
494  {
495    while (<LTEX>) {print TEX $_;}
496    print TEX "\@c end generated lib docu for $lib_name $doc_file:$line \n";
497  }
498  close(LTEX);
499  unlink $ltex_file if ($clean);
500}
501 
502sub GenerateLibDoc
503{
504  my($lib, $tex_file, $l_fun, $l_ex) = @_;
505  my($lib_dir, $scall, $pl_file, $doc_file, $i, $example,$largs, $ref);
506  # vars from executing the library perl scrip
507  local($info, $libary, $version, @procs, %example, %help, $table_is_open);
508 
509  print "(lib $lib: " if ($verbose == 1);
510  # construct doc/tex file name
511  $doc_file = "$doc_subdir/$lib"."_lib";
512  $doc_file .= "_noFun" unless ($l_fun);
513  $doc_file .= ".doc";
514
515  Error("can't open $lib.lib for reading: $!\n")
516    unless  ($lib_dir = &Open(*LIB, "<$lib.lib"));
517  close (LIB);
518  if (-r $doc_file && $reuse && IsNewer($doc_file, "$lib_dir/$lib.lib"))
519  {
520    print "<doc>" if ($verbose == 1);
521  }
522  else
523  {
524    # generate perl file, if necessary
525    $pl_file = "$doc_subdir/$lib"."_lib.pl";
526    if (-r $pl_file && $reuse && IsNewer($pl_file, "$lib_dir/$lib.lib"))
527    {
528      print "<pl>" if ($verbose == 1);
529    }
530    else
531    {
532      print "(pl" if ($verbose == 1);
533      &System("$libparse -i $lib_dir/$lib.lib > $pl_file");
534      print ")" if ($verbose == 1);
535    }
536
537    print "(doc" if ($verbose == 1);
538   
539    do $pl_file;
540    Error("error while executing $pl_file: $@\n") if ($@);
541    unlink ($pl_file) if ($clean);
542   
543    # generate doc file
544    open(LDOC, ">$doc_file") || die"$ERROR can't open $doc_file for writing: $!\n";
545   
546    # print header
547    print LDOC "\@c library version: $version\n";
548    print LDOC "\@c library file: $library\n";
549    undef @procs;
550    $ref = OutLibInfo(\*LDOC, $info, $l_fun);
551    OutRef(\*LDOC, $ref) if $ref;
552    # print menu of available functions
553    if ($l_fun)
554    {
555      # print help and example of each function
556      for ($i = 0; $i <= $#procs; $i++)
557      {
558        # print node and section heading
559        print LDOC "\n\@c ------------------- " . $procs[$i]." -------------\n";
560        print LDOC "\@node " . $procs[$i].",";
561        print LDOC " ".$procs[$i+1] if ($i < $#procs);
562        print LDOC ",";
563        print LDOC " ".$procs[$i-1] if ($i > 0);
564        print LDOC ", " . $lib ."_lib\n";
565        print LDOC "\@$section " . $procs[$i] . "\n";
566        print LDOC "\@cindex ". $procs[$i] . "\n";
567
568        print LDOC "\@c ---content $procs[$i]---\n";
569        print LDOC "Procedure from library \@code{$lib.lib} (\@pxref{${lib}_lib}).\n\n";
570        if ($help{$procs[$i]} =~ /^\@/)
571        {
572          print LDOC $help{$procs[$i]};
573          $ref = '';
574        }
575        else
576        {
577          print LDOC "\@table \@asis\n";
578          $table_is_open = 1;
579          # print help
580          $ref = OutInfo(\*LDOC, $help{$procs[$i]});
581          print LDOC "\@end table\n";
582        }
583        # print example
584        if ($example = &CleanUpExample($lib, $example{$procs[$i]}))
585        {
586          print LDOC "\@strong{Example:}\n";
587          print LDOC "\@smallexample\n\@c example\n";
588          print LDOC $example;
589          print LDOC "\n\@c example\n\@end smallexample\n";
590        }
591        OutRef(\*LDOC, $ref) if $ref;
592        print LDOC "\@c ---end content $procs[$i]---\n";
593      }
594    }
595    close(LDOC);
596    print ")" if ($verbose == 1);
597  }
598
599  $largs = "-no_ex" unless ($l_ex);
600  # call doc2tex on generated doc file
601  print "\n" if ($verbose == 1);
602  dbmclose(%EXAMPLES);
603  &System("$0 $args $largs -o $tex_file $doc_file");
604  dbmopen(%EXAMPLES, $doc_examples_db, oct(755)) 
605    || die "$ERROR: can't open examples data base: $!\n";
606 
607  unlink($doc_file) if ($clean);
608  return 1;
609}
610
611###########################################################################
612# parse and print-out libinfo
613sub OutLibInfo
614{
615  my ($FH, $info, $l_fun) = @_;
616  print $FH "\@c ---content LibInfo---\n";
617    if ($info =~ /^\@/)
618  {
619    print $FH $info;
620    return;
621  }
622  print $FH "\@table \@asis\n";
623  $table_is_open = 1;
624 
625  my ($ref) = OutInfo($FH, $info, $l_fun);
626
627  print $FH "\@end table\n" if $table_is_open;
628  print $FH "\@c ---end content LibInfo---\n";
629  $table_is_open = 0;
630  return $ref;
631}
632
633sub OutInfo
634{
635  my ($FH, $info, $l_fun) = @_;
636  if ($info =~ /^\@/)
637  {
638    print $FH $info;
639    return;
640  }
641  $info =~ s/^\s*//;
642  $info =~ s/\s*$//;
643  $info .= "\n";
644
645  my ($item, $text, $line, $ref);
646  while ($info =~ m/(.*\n)/g)
647  {
648    $line = $1;
649    if ($1 =~ /^(\w.+?):(.*\n)/)
650    {
651      $ref .= OutInfoItem($FH, $item, $text, $l_fun) if $item && $text;
652      $item = $1;
653      $text = $2;
654    }
655    else
656    {
657      $text .= $line;
658    }
659  }
660  $ref .= OutInfoItem($FH, $item, $text, $l_fun) if $item && $text;
661  return $ref;
662}
663
664sub FormatInfoText
665{
666  my $length = shift;
667  $length = 0 unless $length;
668  # insert @* infront of all lines whose previous line is shorter than
669  # 60 characters
670  $_ = ' ' x $length . $_;
671  if (/^(.*)\n/)
672  {
673    $_ .= "\n";
674    my $pline;
675    my $line;
676    my $ptext = $_;
677    my $text = '';
678    while ($ptext =~ /(.*)\n/g)
679    {
680      $line = $1;
681      # break line if
682      $text .= '@*' 
683        if ($line =~ /\w/ && $pline =~ /\w/ # line and prev line are not empty
684            && $line !~ /^\s*\@\*/  # line does not start with @*
685            && $pline !~ /\@\*\s*/  # prev line does not end with @*
686            &&
687            ((length($pline) < 60  && # prev line is shorter than 60 chars
688              $pline !~ /\@code{.*?}/ # and does not contain @code, @math
689              && $pline !~ /\@math{.*?}/) 
690             ||
691             $line =~ /^\s*\w*\(.*?\)/ # $line starts with \w*(..)
692             ||
693             $pline =~ /^\s*\w*\(.*?\)[\s;:]*$/)); # prev line is only \w(..)
694      $line =~ s/\s*$//;
695      $text .= "$line\n";
696      $pline = $line;
697    }
698    $_ = $text;
699  }
700  s/\t/ /g;
701  s/\n +/\n/g;
702  s/\s*$//g;
703  s/ +/ /g;  # replace double whitespaces by one
704  s/(\w+\(.*?\))/\@code{$1}/g;
705  s/\@\*\s*/\@\*/g;
706  s/(\@[^\*])/\@$1/g; # escape @ signs, except @*
707  s/{/\@{/g; # escape {}
708  s/}/\@}/g;
709  # unprotect @@math@{@}, @code@{@}
710  s/\@\@math\@{(.*?)\@}/\@math{$1}/g;
711  s/\@\@code\@{(.*?)\@}/\@code{$1}/g;
712}
713
714sub OutInfoItem
715{
716  my ($FH, $item, $text, $l_fun) = @_;
717
718  $item = lc $item;
719  $item = ucfirst $item;
720
721  if ($item =~ /see also/i)
722  {
723    # return references
724    return $text;
725  }
726  elsif ($item =~ m/example/i)
727  {
728    # forget about example, since it comes explicitely
729    return '';
730  }
731  elsif ($item =~ m/procedure/i)
732  {
733    if ($l_fun && $table_is_open)
734    {
735      print $FH "\@end table\n\n";
736      $table_is_open = 0;
737    }
738    $text =~ s/^\s*//;
739    $text =~ s/\s*$//;
740    $text =~ s/.*$// if ($text=~/parameters.*brackets.*are.*optional.*$/);
741    $text .= "\n";
742   
743    my ($proc, $pargs, $pinfo, $line);
744    if ($l_fun)
745    {
746      print $FH "\@strong{$item:}\n\@menu\n";
747    }
748    else
749    {
750      print $FH "\@item \@strong{$item:}\n\@table \@asis\n";
751    }
752    while ($text =~ /(.*\n)/g)
753    {
754      $line = $1;
755      if ($1 =~ /^\s*(\w+)\((.*?)\)/)
756      {
757        OutProcInfo($FH, $proc, $procargs, $pinfo, $l_fun) if $proc && $pinfo;
758        $proc = $1;
759        $procargs = $2;
760        $pinfo = $';
761      }
762      else
763      {
764        $pinfo .= $line; 
765      }
766    }
767    OutProcInfo($FH, $proc, $procargs, $pinfo, $l_fun) if $proc && $pinfo;
768    print $FH ($l_fun ? "\@end menu\n" : "\@end table\n");
769    return '';
770  }
771
772  if (! $table_is_open)
773  {
774    print $FH "\@table \@asis\n";
775    $table_is_open = 1;
776  }
777  print $FH '@item @strong{'. "$item:}\n";
778  # prepare text:
779  local $_ = $text;
780  if (($item =~ m/^library/i)  && m/\s*(\w*)\.lib/)
781  {
782    print $FH "$1.lib\n";
783    $text = $';
784    if ($text =~ /\w/)
785    {
786      print $FH '@item @strong{Purpose:'."}\n";
787      print $FH lc $text;
788    }
789  }
790  else
791  {
792    # just print the text
793    FormatInfoText(length($item) + 1);
794    print $FH "$_\n";
795  }
796  return '';
797}
798
799sub OutProcInfo
800{
801  my($FH, $proc, $procargs, $pinfo, $l_fun) = @_;
802  local $_ = $pinfo;
803  s/^[;\s]*//;
804  s/\n/ /g;
805  FormatInfoText();
806 
807  if ($l_fun)
808  {
809    print $FH "* ${proc}:: $_\n";
810    push @procs, $proc;
811  }
812  else
813  {
814    print $FH "\@item \@code{$proc($procargs)}  ";
815    print $FH "\n\@cindex $proc\n$_\n";
816  }
817}
818
819sub OutRef
820{
821  my ($FH, $refs) = @_;
822  $refs =~ s/^\s*//;
823  $refs =~ s/\s*$//;
824  $refs =~ s/\n/,/g;
825  my @refs = split (/[,;\.]+/, $refs);
826  my $ref;
827
828  print $FH "\@c ref\nSee\n";
829  $ref = shift @refs;
830  print $FH "\@ref{$ref}";
831  for $ref (@refs)
832  {
833    $ref =~ s/^\s*//;
834    $ref =~ s/\s*$//;
835    print $FH ", \@ref{$ref}"  if ($ref =~ /\w/);
836  }
837  print $FH "\n\@c ref\n";
838}
839
840sub CleanUpExample
841{
842  local($lib, $example) = @_;
843 
844  # find portion in {}
845  $example =~ s/^[^{]*{(.*)}[^}]*$/$1/s;
846
847  if ($example =~ /EXAMPLE: \(not executed\)/)
848  {
849    # erase first three lines
850    $example =~ s/^.*\n.*\n.*\n/\n/;
851    # erase enclosing " " in every line
852    $example =~ s/\n\s*"/\n/g;
853    $example =~  s/";\n/\n/g;
854  }
855  # erase EXAMPLE, echo and pause statements
856  $example =~ s/"EXAMPLE.*"[^;]*;//g;
857  $example .= "\n";
858  my ($mexample, $line);
859  while ($example =~ m/(.*)\n/g)
860  {
861    $line = $1;
862    $line =~ s|echo[^;]*;||g if $line !~ m|(.*)//(.*)echo[^;]*;|;
863    $line =~ s|pause\(.*?\)[^;]*;||g if $line !~ m|(.*)//(.*)pause\(.*?\)[^;]*;|;
864    $mexample .= "$line\n";
865  }
866  $example = $mexample;
867 
868  # prepend LIB command
869  $example = "LIB \"$lib.lib\";\n".$example 
870    if ($example && $lib ne "standard");
871  # erase empty lines
872  $example =~ s/^\s*\n//g;
873  # erase spaces from beginning of lines
874  $example =~ s/\n\s*/\n/g;
875  $example =~ s/\s*$//g;
876  return $example;
877}
878
879###################################################################
880#
881# Auxiallary functions
882#
883sub IsNewer
884{
885  my $f1 = shift;
886  my $f2 = shift;
887  my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime)
888    = stat($f1);
889  my $m1 = $mtime;
890  ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime) = stat($f2);
891
892  return ($m1 > $mtime);
893}
894
895####################################################################
896# Auxillary routines
897#
898
899# protect texi special characters
900sub protect_texi
901{
902  s/\@/\@\@/g;
903  s/{/\@{/g;
904  s/}/\@}/g;
905}       
906
907# open w.r.t. include_dirs
908sub Open
909{
910  local(*FH, $file) = @_;
911  local($mode);
912  $file =~ s/^(.{1})(.*)/$2/;
913  $mode = $1;
914
915  foreach $dir (@include_dirs)
916  {
917    return $dir if(open(FH, $mode.$dir."/".$file));
918  }
919}
920   
921# system call with echo on verbose > 1 and die on fail
922sub System
923{
924  local($call) = @_;
925  print "\nd2t system: $call\n" if ($verbose > 1);
926  Error("non-zero exit status of system call: '$call': $!\n")
927    if (system($call));
928}
929
930sub Error
931{
932  print "$ERROR $_[0]";
933  close(TEX);
934  unlink $tex_file if $tex_file && -e $tex_file;
935  exit(1);
936}
937
938#
939# leave this here --otherwise fontification in my emacs gets screwd up
940#
941sub Usage
942{
943  return <<EOT;
944This is doc2tex: a utility to generate Singular texinfo from doc file
945To convert a doc file to texinfo: $0 [options] input_file.doc
946where options can be (abbreviated to shortest possible prefix):
947  -Singular prog: use 'prog' as Singular program to generate ex output
948                          (default: '../Singular/Singular')
949  -libparse prog: use 'prog' as libparse program to generate lib docu
950                          (default: '../Singular/libparse')
951  -output file  : use 'file' as output file
952                          (default: input_file.tex)
953  -clean        : delete intermediate files
954  -no_reuse     : don't reuse intermediate files
955  -no_ex        : skip computation of examples
956  -lib_fun      : include help for library functions
957  -lib_ex       : include example for library functions
958  -subdir  dir  : put intermediate files into 'dir'
959                          (default: './d2t_singular')
960  -I dir        : look also into 'dir' for include  and lib files
961                          (default: ".", "../Singular/LIB")
962  -verbose  val : Set verbosity to 'val' (0=quiet, 1=prot, >1=all)
963  -help         : print help and exit
964EOT
965}
966
Note: See TracBrowser for help on using the repository browser.