source: git/doc/doc2tex.pl @ 877605

fieker-DuValspielwiese
Last change on this file since 877605 was 877605, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* new files: tricks.doc * new handling of images git-svn-id: file:///usr/local/Singular/svn/trunk@3277 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 23.5 KB
Line 
1#!/usr/local/bin/perl
2# $Id: doc2tex.pl,v 1.6 1999-07-15 14:15:06 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  unless (&Open(*INC, "<$_"))
322  {
323    warn "$WARNING HandleInclude: can't open $_ for reading\n";
324    print TEX "\@c include file $_ not found\n";
325    return;
326  }
327  print "<$_>" if ($verbose);
328  print TEX "\@c begin included file $_ from $doc_file:$line\n";
329  while (<INC>)
330  {
331    &protect_texi;
332    print TEX $_;
333  }
334  print TEX "\@c end included file from $doc_file:$line\n";
335  close (INC);
336}
337
338######################################################################
339# @c ref
340# ....
341# @c ref
342#    -> scans intermediate lines for @ref{..} strings
343#    Creates menu of (sorted) refs for ifinfo
344#    Creates comma-separated (sorted) refs for iftex, prepended with
345#    the text before first @ref.
346
347sub HandleRef
348{
349  local(%refs, @refs, $header, $lline, $lref);
350 
351  print TEX "\@c inserted refs from $doc_file:$line\n";
352 
353  # scan lines use %ref to remove duplicates
354  $lline = $line;
355  while (<DOC>)
356  {
357    $line++;
358    last if (/^\@c\s*ref\s*$/);
359   
360    while (/\@ref{([^\s]*)}/)
361    {
362      $refs{$1} = 1;
363      $_ = $';
364      unless ($header)
365      {
366        $header = $`;
367        $header = " " unless ($header);
368      }
369    }
370  }
371  die "$ERRROR no matching \@c ref found for $doc_file:$lline\n" 
372    unless (/^\@c\s*ref\s*$/);
373  # sort refs
374  @refs = sort(keys(%refs));
375  # put them out
376  print TEX "\@ifinfo\n\@menu\n";
377  foreach $ref (@refs) {print TEX "* ".$ref."::\n";}
378  print TEX "\@end menu\n\@end ifinfo\n\@iftex\n";
379
380  if ($header ne " ")
381  {
382    print TEX "$header\n" unless ($header eq " ");
383  }
384  else
385  {
386    print TEX "\@strong{See also:} ";
387  }
388  $lref = pop(@refs);
389  foreach $ref (@refs) {print TEX "\@ref{".$ref."};\n";}
390  print TEX "\@ref{".$lref."}.\n" if ($lref); 
391  print TEX "\@end iftex\n\@c end inserted refs from $doc_file:$lline\n";
392}
393
394###################################################################
395#
396# @c lib libname.lib [no_ex, lib_fun, lib_ex]
397#   --> includes info of libname.lib in output file
398#   --> includes function names of info into function index
399#   --> if lib_fun is given, includes listing of functions and
400#                      their help into output file
401#   --> if lib_ex is given, includes computed examples of functions, as well
402#
403# Optional no_ex, lib_fun, lib_ex arguments overwrite respective
404# command-line arguments
405#
406
407sub HandleLib
408{
409  local($lib, $lib_name, $ltex_file, $l_ex, $l_fun);
410  my ($func);
411
412  if (/^\@c\s*lib\s+([^\.]+)\.lib(.*)/)
413  {
414    $lib = $1;
415    $lib_name = $lib.".lib";
416    $_ = $2;
417  }
418  else
419  {
420    warn "$WARNING need .lib file to process '$_'\n";
421    print TEX $_;
422    return;
423  }
424
425  $func = $1 if (/^:(.*?) /);
426  $l_fun = 1 if (($lib_fun || (/lib_fun/)) && !/no_fun/);
427  $l_ex = 1 if (($lib_ex || /lib_ex/) && !/no_ex/ && $l_fun);
428
429  $ltex_file = "$doc_subdir/$lib"."_lib";
430  unless ($l_ex)
431  {
432    if ($l_fun)
433    {
434      $ltex_file .= "_noEx";
435    }
436    else
437    {
438      $ltex_file .= "_noFun";
439    }
440  }
441  $ltex_file .= ".tex";
442 
443  Error("can't open $lib.lib for reading: $!\n") 
444    unless  ($lib_dir = &Open(*LIB, "<$lib.lib"));
445  close (LIB);
446  if ($reuse && open(LTEX, "<$ltex_file") && 
447      IsNewer($ltex_file, "$lib_dir/$lib.lib"))
448  {
449    unless ($func)
450    {
451      print "<lib $lib>" if ($verbose);
452      print TEX "\@c reused lib docu for $lib_name $doc_file:$line \n";
453    }
454  }
455  elsif (&GenerateLibDoc($lib, $ltex_file, $l_fun, $l_ex))
456  {
457    print TEX "\@c generated lib docu for $lib_name $doc_file:$line \n"
458      unless $func;
459    open(LTEX, "<$ltex_file") 
460      || Error("can't open $ltex_file for reading: $!\n");
461  }
462  if ($func)
463  {
464    print "<$lib:$func" if $verbose;
465    print TEX "\@c generated lib proc docu for $lib_name:$func $doc_file:$line \n";
466    my $found = 0;
467    while (<LTEX>)
468    {
469      $found = 1 if /c ---content $func---/;
470      print TEX $_ if $found;
471      last if $found && /c ---end content $func---/;
472    }
473    if ($found)
474    {
475      Error("no end content found for lib proc docu for $lib_name:$func $doc_file:$line \n")
476        unless (/c ---end content $func---/);
477      print TEX "\@c generated lib proc docu for $lib_name:$func $doc_file:$line \n";
478    }
479    else
480    {
481      Error("did not find lib proc docu for $lib_name:$func $doc_file:$line \n");
482    }
483    print ">" if $verbose;
484  }
485  else
486  {
487    while (<LTEX>) {print TEX $_;}
488    print TEX "\@c end generated lib docu for $lib_name $doc_file:$line \n";
489  }
490  close(LTEX);
491  unlink $ltex_file if ($clean);
492}
493 
494sub GenerateLibDoc
495{
496  my($lib, $tex_file, $l_fun, $l_ex) = @_;
497  my($lib_dir, $scall, $pl_file, $doc_file, $i, $example,$largs, $ref);
498  # vars from executing the library perl scrip
499  local($info, $libary, $version, @procs, %example, %help, $table_is_open);
500 
501  print "(lib $lib: " if ($verbose == 1);
502  # construct doc/tex file name
503  $doc_file = "$doc_subdir/$lib"."_lib";
504  $doc_file .= "_noFun" unless ($l_fun);
505  $doc_file .= ".doc";
506
507  Error("can't open $lib.lib for reading: $!\n")
508    unless  ($lib_dir = &Open(*LIB, "<$lib.lib"));
509  close (LIB);
510  if (-r $doc_file && $reuse && IsNewer($doc_file, "$lib_dir/$lib.lib"))
511  {
512    print "<doc>" if ($verbose == 1);
513  }
514  else
515  {
516    # generate perl file, if necessary
517    $pl_file = "$doc_subdir/$lib"."_lib.pl";
518    if (-r $pl_file && $reuse && IsNewer($pl_file, "$lib_dir/$lib.lib"))
519    {
520      print "<pl>" if ($verbose == 1);
521    }
522    else
523    {
524      print "(pl" if ($verbose == 1);
525      &System("$libparse -i $lib_dir/$lib.lib > $pl_file");
526      print ")" if ($verbose == 1);
527    }
528
529    print "(doc" if ($verbose == 1);
530   
531    do $pl_file;
532    Error("error while executing $pl_file: $@\n") if ($@);
533    unlink ($pl_file) if ($clean);
534   
535    # generate doc file
536    open(LDOC, ">$doc_file") || die"$ERROR can't open $doc_file for writing: $!\n";
537   
538    # print header
539    print LDOC "\@c library version: $version\n";
540    print LDOC "\@c library file: $library\n";
541    undef @procs;
542    $ref = OutLibInfo(\*LDOC, $info, $l_fun);
543    OutRef(\*LDOC, $ref) if $ref;
544    # print menu of available functions
545    if ($l_fun)
546    {
547      # print help and example of each function
548      for ($i = 0; $i <= $#procs; $i++)
549      {
550        # print node and section heading
551        print LDOC "\n\@c ------------------- " . $procs[$i]." -------------\n";
552        print LDOC "\@node " . $procs[$i].",";
553        print LDOC " ".$procs[$i+1] if ($i < $#procs);
554        print LDOC ",";
555        print LDOC " ".$procs[$i-1] if ($i > 0);
556        print LDOC ", " . $lib ."_lib\n";
557        print LDOC "\@subsection " . $procs[$i] . "\n";
558        print LDOC "\@findex ". $procs[$i] . "\n";
559        print LDOC "\@cindex ". $procs[$i] . "\n" if ($lib eq "standard");
560
561        print LDOC "\@c ---content $procs[$i]---\n";
562        print LDOC "\@table \@asis\n";
563        $table_is_open = 1;
564        # print help
565        $ref = OutInfo(\*LDOC, $help{$procs[$i]});
566        print LDOC "\@end table\n";
567        $table_is_open = 0;
568        # print example
569        if ($example = &CleanUpExample($lib, $example{$procs[$i]}))
570        {
571          print LDOC "\@strong{Example:}\n";
572          print LDOC "\@smallexample\n\@c example\n";
573          print LDOC $example;
574          print LDOC "\n\@c example\n\@end smallexample\n";
575        }
576        OutRef(\*LDOC, $ref) if $ref;
577        print LDOC "\@c ---end content $procs[$i]---\n";
578      }
579    }
580    close(LDOC);
581    print ")" if ($verbose == 1);
582  }
583
584  $largs = "-no_ex" unless ($l_ex);
585  # call doc2tex on generated doc file
586  print "\n" if ($verbose == 1);
587  dbmclose(%EXAMPLES);
588  &System("$0 $args $largs -o $tex_file $doc_file");
589  dbmopen(%EXAMPLES, $doc_examples_db, oct(755)) 
590    || die "$ERROR: can't open examples data base: $!\n";
591 
592  unlink($doc_file) if ($clean);
593  return 1;
594}
595
596###########################################################################
597# parse and print-out libinfo
598sub OutLibInfo
599{
600  my ($FH, $info, $l_fun) = @_;
601  print $FH "\@c ---content LibInfo---\n";
602  print $FH "\@table \@asis\n";
603  $table_is_open = 1;
604 
605  my ($ref) = OutInfo($FH, $info, $l_fun);
606
607  print $FH "\@end table\n" if $table_is_open;
608  print $FH "\@c ---end content LibInfo---\n";
609  $table_is_open = 0;
610  return $ref;
611}
612
613sub OutInfo
614{
615  my ($FH, $info, $l_fun) = @_;
616  $info =~ s/^\s*//;
617  $info =~ s/\s*$//;
618  $info .= "\n";
619
620  my ($item, $text, $line, $ref);
621  while ($info =~ m/(.*\n)/g)
622  {
623    $line = $1;
624    if ($1 =~ /^(\w.+?):(.*\n)/)
625    {
626      $ref .= OutInfoItem($FH, $item, $text, $l_fun) if $item && $text;
627      $item = $1;
628      $text = $2;
629    }
630    else
631    {
632      $text .= $line;
633    }
634  }
635  $ref .= OutInfoItem($FH, $item, $text, $l_fun) if $item && $text;
636  return $ref;
637}
638
639sub FormatInfoText
640{
641  my $length = shift;
642  $length = 0 unless $length;
643  # insert @* infront of all lines whose previous line is shorter than
644  # 60 characters
645  $_ = ' ' x $length . $_;
646  if (/^(.*)\n/)
647  {
648    $_ .= "\n";
649    my $pline;
650    my $line;
651    my $ptext = $_;
652    my $text = '';
653    while ($ptext =~ /(.*)\n/g)
654    {
655      $line = $1;
656      $text .= '@*' 
657        if ($line =~ /\w/ && $pline =~ /\w/ && 
658            ((length($pline) < 60) || $line =~ /^\s*\w*\(.*?\)/));
659      $line =~ s/\s*$//;
660      $text .= "$line\n";
661      $pline = $line;
662    }
663    $_ = $text;
664  }
665  s/\t/ /g;
666  s/\n +/\n/g;
667  s/\s*$//g;
668  s/ +/ /g;  # replace double whitespaces by one
669  s/\@\*\s*/\@\*/g;
670  s/(\@[^\*])/\@$1/g; # escape @ signs, except @*
671  s/{/\@{/g;
672  s/}/\@}/g;
673}
674
675sub OutInfoItem
676{
677  my ($FH, $item, $text, $l_fun) = @_;
678
679  $item = lc $item;
680  $item = ucfirst $item;
681
682  if ($item =~ /see also/i)
683  {
684    # return references
685    return $text;
686  }
687  elsif ($item =~ m/example/i)
688  {
689    # forget about example, since it comes explicitely
690    return '';
691  }
692  elsif ($item =~ m/procedure/i)
693  {
694    if ($l_fun && $table_is_open)
695    {
696      print $FH "\@end table\n\n";
697      $table_is_open = 0;
698    }
699    $text =~ s/^\s*//;
700    $text =~ s/\s*$//;
701    $text =~ s/.*$// if ($text=~/parameters.*brackets.*are.*optional.*$/);
702    $text .= "\n";
703   
704    my ($proc, $pargs, $pinfo, $line);
705    if ($l_fun)
706    {
707      print $FH "\@strong{$item:}\n\@menu\n";
708    }
709    else
710    {
711      print $FH "\@item \@strong{$item:}\n\@table \@asis\n";
712    }
713    while ($text =~ /(.*\n)/g)
714    {
715      $line = $1;
716      if ($1 =~ /^\s*(\w+)\((.*?)\)/)
717      {
718        OutProcInfo($FH, $proc, $procargs, $pinfo, $l_fun) if $proc && $pinfo;
719        $proc = $1;
720        $procargs = $2;
721        $pinfo = $';
722      }
723      else
724      {
725        $pinfo .= $line; 
726      }
727    }
728    OutProcInfo($FH, $proc, $procargs, $pinfo, $l_fun) if $proc && $pinfo;
729    print $FH ($l_fun ? "\@end menu\n" : "\@end table\n");
730    return '';
731  }
732
733  if (! $table_is_open)
734  {
735    print $FH "\@table \@asis\n";
736    $table_is_open = 1;
737  }
738  print $FH '@item @strong{'. "$item:}\n";
739  # prepare text:
740  local $_ = $text;
741  if (($item =~ m/^library/i)  && m/\s*(\w*)\.lib/)
742  {
743    print $FH "$1.lib\n";
744    $text = $';
745    if ($text =~ /\w/)
746    {
747      print $FH "\n" . '@item @strong{Purpose:'."}\n";
748      print $FH lc $text;
749    }
750  }
751  else
752  {
753    # just print the text
754    FormatInfoText(length($item) + 1);
755    # if functions are in text, then make it in code
756    s/(\w+\(.*?\))/\@code{$1}/g
757      if ($item =~ /usage/i || $item =~ /Return/i);
758
759    print $FH "$_\n\n";
760  }
761  return '';
762}
763
764sub OutProcInfo
765{
766  my($FH, $proc, $procargs, $pinfo, $l_fun) = @_;
767  local $_ = $pinfo;
768  s/^[;\s]*//;
769  s/\n/ /g;
770  FormatInfoText();
771 
772  if ($l_fun)
773  {
774    print $FH "* ${proc}:: $_\n";
775    push @procs, $proc;
776  }
777  else
778  {
779    print $FH "\@item \@code{$proc($procargs)}  ";
780    print $FH "\n\@findex $proc\n$_\n";
781  }
782}
783
784sub OutRef
785{
786  my ($FH, $refs) = @_;
787  $refs =~ s/^\s*//;
788  $refs =~ s/\s*$//;
789  my @refs = split (/[\s,]+/, $refs);
790  my $ref;
791
792  print $FH "\@c ref\nSee\n";
793  $ref = shift @refs;
794  print $FH "\@ref{$ref}";
795  for $ref (@refs)
796  {
797    print $FH ", \@ref{$ref}";
798  }
799  print $FH "\n\@c ref\n";
800}
801
802sub CleanUpExample
803{
804  local($lib, $example) = @_;
805 
806  # find portion in {}
807  $example =~ s/^[^{]*{(.*)}[^}]*$/$1/s;
808
809  if ($example =~ /EXAMPLE: \(not executed\)/)
810  {
811    # erase first three lines
812    $example =~ s/^.*\n.*\n.*\n/\n/;
813    # erase enclosing " " in every line
814    $example =~ s/\n\s*"/\n/g;
815    $example =~  s/";\n/\n/g;
816  }
817  # erase EXAMPLE, echo and pause statements
818  $example =~ s/"EXAMPLE.*"[^;]*;//g;
819  $example .= "\n";
820  my ($mexample, $line);
821  while ($example =~ m/(.*)\n/g)
822  {
823    $line = $1;
824    $line =~ s|echo[^;]*;||g if $line !~ m|(.*)//(.*)echo[^;]*;|;
825    $line =~ s|pause\(.*?\)[^;]*;||g if $line !~ m|(.*)//(.*)pause\(.*?\)[^;]*;|;
826    $mexample .= "$line\n";
827  }
828  $example = $mexample;
829 
830  # prepend LIB command
831  $example = "LIB \"$lib.lib\";\n".$example 
832    if ($example && $lib ne "standard");
833  # erase empty lines
834  $example =~ s/^\s*\n//g;
835  # erase spaces from beginning of lines
836  $example =~ s/\n\s*/\n/g;
837  $example =~ s/\s*$//g;
838  return $example;
839}
840
841###################################################################
842#
843# Auxiallary functions
844#
845sub IsNewer
846{
847  my $f1 = shift;
848  my $f2 = shift;
849  my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime)
850    = stat($f1);
851  my $m1 = $mtime;
852  ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime) = stat($f2);
853
854  return ($m1 > $mtime);
855}
856
857####################################################################
858# Auxillary routines
859#
860
861# protect texi special characters
862sub protect_texi
863{
864  s/\@/\@\@/g;
865  s/{/\@{/g;
866  s/}/\@}/g;
867}       
868
869# open w.r.t. include_dirs
870sub Open
871{
872  local(*FH, $file) = @_;
873  local($mode);
874  $file =~ s/^(.{1})(.*)/$2/;
875  $mode = $1;
876
877  foreach $dir (@include_dirs)
878  {
879    return $dir if(open(FH, $mode.$dir."/".$file));
880  }
881}
882   
883# system call with echo on verbose > 1 and die on fail
884sub System
885{
886  local($call) = @_;
887  print "\nd2t system: $call\n" if ($verbose > 1);
888  Error("non-zero exit status of system call: '$call': $!\n")
889    if (system($call));
890}
891
892sub Error
893{
894  print "$ERROR $_[0]";
895  close(TEX);
896  unlink $tex_file if $tex_file && -e $tex_file;
897  exit(1);
898}
899
900#
901# leave this here --otherwise fontification in my emacs gets screwd up
902#
903sub Usage
904{
905  return <<EOT;
906This is doc2tex: a utility to generate Singular texinfo from doc file
907To convert a doc file to texinfo: $0 [options] input_file.doc
908where options can be (abbreviated to shortest possible prefix):
909  -Singular prog: use 'prog' as Singular program to generate ex output
910                          (default: '../Singular/Singular')
911  -libparse prog: use 'prog' as libparse program to generate lib docu
912                          (default: '../Singular/libparse')
913  -output file  : use 'file' as output file
914                          (default: input_file.tex)
915  -clean        : delete intermediate files
916  -no_reuse     : don't reuse intermediate files
917  -no_ex        : skip computation of examples
918  -lib_fun      : include help for library functions
919  -lib_ex       : include example for library functions
920  -subdir  dir  : put intermediate files into 'dir'
921                          (default: './d2t_singular')
922  -I dir        : look also into 'dir' for include  and lib files
923                          (default: ".", "../Singular/LIB")
924  -verbose  val : Set verbosity to 'val' (0=quiet, 1=prot, >1=all)
925  -help         : print help and exit
926EOT
927}
928
Note: See TracBrowser for help on using the repository browser.