source: git/doc/pl2doc.pl @ 2e0b620

spielwiese
Last change on this file since 2e0b620 was 2e0b620, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* small changes as we go along git-svn-id: file:///usr/local/Singular/svn/trunk@3396 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 11.8 KB
Line 
1#!/usr/local/bin/perl
2# $Id: pl2doc.pl,v 1.8 1999-08-03 16:35:37 obachman Exp $
3###################################################################
4#  Computer Algebra System SINGULAR
5#
6#  pl2doc.pl: utility to generate doc file out of pl for singular library
7#
8####
9$Usage = <<EOT;
10Usage: 
11$0 [-o out_file -db db_file -no_ex -no_fun -doc] library_perl_file.doc
12Convert library_perl_file.pl to library_perl_file.doc
13EOT
14
15###################################################################
16# parse command line options
17#
18while (@ARGV && $ARGV[0] =~ /^-/) 
19{
20  $_ = shift(@ARGV);
21  if (/^-o$/)    { $out_file = shift(@ARGV); next;}
22  if (/^-db$/) { $db_file = shift(@ARGV); next;}
23  if (/^-no_fun$/)    { $no_fun = 1;next;}
24  if (/^-doc$/)       { $doc = 1; next;}
25  if (/^-h(elp)?$/)   { print $Usage; exit;}
26 
27  die "Error: Unknown option: $_:$Usage\n";
28}
29
30
31###################################################################
32# Execute perl file
33#
34$pl_file = pop(@ARGV);
35die "Error: No perl file specified: $Usage\n" unless $pl_file;
36die "Error: Can't find perl file $pl_file: $Usage\n" unless -r $pl_file;
37require $pl_file;
38$lib = $library;
39$lib =~ s|.*/(.*)$|$1|;
40$lib =~ s|(.*)\.lib$|$1|;
41
42###################################################################
43# print  summary
44#
45unless ($out_file)
46{
47  ($out_file = $pl_file) =~ s/(.*)\..*$/$1/;
48  $out_file .= "_noFun" if ($no_fun);
49  $out_file .= ".doc";
50}
51open(LDOC, ">$out_file") || die"Error: can't open $out_file for writing: $!\n";
52print_doc_header(\*LDOC) if $doc;
53print LDOC "\@c ---content LibInfo---\n";
54print LDOC "\@c library version: $version\n";
55print LDOC "\@c library file: $library\n";
56print LDOC "\@cindex $lib.lib\n";
57print LDOC "\@cindex ${lib}_lib\n";
58undef @procs; # will be again defined by OutLibInfo
59$parsing = "info-string of lib $lib:";
60$ref = OutLibInfo(\*LDOC, $info, ! $no_fun);
61OutRef(\*LDOC, $ref) if $ref;
62print LDOC "\@c ---end content LibInfo---\n";
63
64###################################################################
65# print  summary
66#
67# print subsections for help of procs
68unless ($no_fun)
69{
70  if ($db_file)
71  {
72    $db_file = $1 if ($db_file =~ /(.*)\..*$/);
73    dbmopen(%CHECKSUMS, $db_file, oct(755)) ||
74      die "Error: can't open chksum data base $db_file";
75  }
76  # print help and example of each function
77  for ($i = 0; $i <= $#procs; $i++)
78  {
79    # print node and section heading
80    print LDOC "\n\@c ------------------- " . $procs[$i]." -------------\n";
81    print LDOC "\@node " . $procs[$i].",";
82    print LDOC " ".$procs[$i+1] if ($i < $#procs);
83    print LDOC ",";
84    print LDOC " ".$procs[$i-1] if ($i > 0);
85    print LDOC ", " . $lib ."_lib\n";
86    print LDOC "\@subsection " . $procs[$i] . "\n";
87    print LDOC "\@cindex ". $procs[$i] . "\n";
88    $CHECKSUMS{$procs[$i]} = $chksum{$procs[$i]} if ($db_file);
89    print LDOC "\@c ---content $procs[$i]---\n";
90    print LDOC "Procedure from library \@code{$lib.lib} (\@pxref{${lib}_lib}).\n\n";
91    if ($help{$procs[$i]} =~ /^\@/)
92    {
93      print LDOC $help{$procs[$i]};
94      $ref = '';
95    }
96    else
97    {
98      print LDOC "\@table \@asis\n";
99      $table_is_open = 1;
100      # print help
101      $parsing = "help-string of $lib:$procs[$i]:";
102      $ref = OutInfo(\*LDOC, $help{$procs[$i]});
103      print LDOC "\@end table\n";
104    }
105    # print example
106    if ($ex = &CleanUpExample($lib, $example{$procs[$i]}))
107    {
108      print LDOC "\@strong{Example:}\n";
109      print LDOC "\@smallexample\n\@c example\n";
110      print LDOC $ex;
111      print LDOC "\n\@c example\n\@end smallexample\n";
112    }
113    OutRef(\*LDOC, $ref) if $ref;
114    print LDOC "\@c ---end content $procs[$i]---\n";
115  }
116  dbmclose(%CHECKSUMS);
117}
118
119#
120# und Tschuess
121#
122if ($doc)
123{
124 print LDOC <<EOT;
125\@c ----------------------------------------------------------
126\@node Index, , Singular libraries, Top
127\@chapter Index
128\@printindex cp
129
130\@bye
131EOT
132}
133 
134close(LDOC);
135if ($error)
136{
137  print STDERR "ERROR: $error\n";
138  exit(1);
139}
140exit(0);
141
142###########################################################################
143#
144# parse and print-out libinfo
145#
146sub OutLibInfo
147{
148  my ($FH, $info, $l_fun) = @_;
149  if ($info =~ /^\@/)
150  {
151    print $FH $info;
152    return;
153  }
154  print $FH "\@table \@asis\n";
155  $table_is_open = 1;
156 
157  my ($ref) = OutInfo($FH, $info, $l_fun);
158
159  print $FH "\@end table\n" if $table_is_open;
160  $table_is_open = 0;
161  return $ref;
162}
163
164sub OutInfo
165{
166  my ($FH, $info, $l_fun) = @_;
167  if ($info =~ /^\@/)
168  {
169    print $FH $info;
170    return;
171  }
172  $info =~ s/^\s*//;
173  $info =~ s/\s*$//;
174  $info .= "\n";
175
176  my ($item, $text, $line, $ref);
177  while ($info =~ m/(.*\n)/g)
178  {
179    $line = $1;
180    if ($1 =~ /^(\w.+?):(.*\n)/)
181    {
182      $ref .= OutInfoItem($FH, $item, $text, $l_fun) if $item && $text;
183      $item = $1;
184      $text = $2;
185    }
186    else
187    {
188      $text .= $line;
189    }
190  }
191  $ref .= OutInfoItem($FH, $item, $text, $l_fun) if $item && $text;
192  return $ref;
193}
194
195sub FormatInfoText
196{
197  my $length = shift;
198  my ($pline, $line, $text, $ptext, $special);
199  my ($in_format, $in_example, $in_texinfo);
200
201  $length = 0 unless $length;
202  $_ .= "\n";
203  $ptext = $_;
204  while ($ptext =~ /(.*)\n/g)
205  {
206    $pline = $line;
207    $line = $1;
208    # check whether we are in protected env
209    if ($in_format || $in_example || $in_texinfo)
210    {
211      # end protected env?
212      if ($line =~ /^\s*\@end (format|example|texinfo)\s*$/)
213      {
214        if ($in_format && $1 eq 'format')
215        {
216          $in_format = 0;
217          $text .= "$line\n";
218        }
219        elsif ($in_example && $1 eq 'example')
220        {
221          $in_example = 0;
222          $text .= "\@end smallexample\n";
223        }
224        elsif ($in_texinfo && $1 eq 'texinfo')
225        {
226          $in_texinfo = 0;
227          $text .= "\n";
228        }
229        else
230        {
231          $error = "While parsing $parsing: \@end $1 found without matching \@$1" unless $error;
232        }
233        next;
234      }
235      else
236      {
237        $text .= "$line\n";
238        next;
239      }
240    }
241    # look for @example, @format, @texinfo
242    if ($line =~ /^\s*\@(example|format|texinfo)\s*$/)
243    {
244      $special = 1;
245      if ($1 eq 'example')
246      {
247        $text .= "\@smallexample\n";
248        $in_example = 1;
249      }
250      elsif ($1 eq 'format')
251      {
252        $text .= "$line\n";
253        $in_format = 1;
254      }
255      else
256      {
257        $text .= "\n";
258        $in_texinfo = 1;
259      }
260      next;
261    }
262    if ($line =~ /([^\@]|^)\@(code|math){(.*?)}/)
263    {
264      my $l = $line;
265      $l =~ s/^\s*//;
266      $l =~ s/\s$//;
267      while ($l =~ /([^\@]|^)\@(code|math){(.*?)}/)
268      {
269        $text .= CleanAscii($`.$1);
270        $text .= "\@$2\{$3\}";
271        $l = $';
272      }
273      $special = 1;
274      $text .= CleanAscii($l) . "\n";
275      next;
276    }
277    # break line if
278    $text .= '@*' 
279      if ($line =~ /\w/ 
280          && $pline =~ /\w/      # line and prev line are not empty
281          && $line !~ /^\s*\@\*/ # line does not start with @*
282          && $pline !~ /\@\*\s*/ # prev line does not end with @*
283          && length($pline) + $length < 60 # prev line is shorter than 60 chars
284          && ! $special);        # prev line was not special line
285    $line =~ s/^\s*//;
286    $line =~ s/\s$//;
287    $special = 0;
288    $text .= CleanAscii($line) . "\n";
289  }
290  $_ = $text;
291  s/^\s*//;
292  s/\s*$//;
293  $_ .= "\n";
294  if ($in_format || $in_texinfo || $in_example)
295  {
296    $error = "While parsing $parsing: no matching \@end " .
297      ($in_format ? "format" : ($in_texinfo ? "texinfo" : "example" )) .
298        " found"
299          unless $error;
300  }
301}
302
303sub CleanAscii
304{
305  my $a = shift;
306  $a =~ s/(\@([^\*]|$))/\@$1/g; # escape @ signs, except @*, @{, @}
307  $a =~ s/{/\@{/g; # escape {}
308  $a =~ s/}/\@}/g;
309  $a =~ s/\t/ /g;
310  $a =~ s/ +/ /g;         
311  return $a;
312}
313
314sub OutInfoItem
315{
316  my ($FH, $item, $text, $l_fun) = @_;
317  local $parsing  = $parsing . uc($item);
318
319  $item = lc $item;
320  $item = ucfirst $item;
321
322  if ($item =~ /see also/i)
323  {
324    # return references
325    return $text;
326  }
327  elsif ($item =~ m/example/i)
328  {
329    # forget about example, since it comes explicitely
330    return '';
331  }
332  elsif ($item =~ m/procedure/i)
333  {
334    if ($l_fun && $table_is_open)
335    {
336      print $FH "\@end table\n\n";
337      $table_is_open = 0;
338    }
339    $text =~ s/^\s*//;
340    $text =~ s/\s*$//;
341    $text =~ s/.*$// if ($text=~/parameters.*brackets.*are.*optional.*$/);
342    $text .= "\n";
343   
344    my ($proc, $pargs, $pinfo, $line);
345    if ($l_fun)
346    {
347      print $FH "\@strong{$item:}\n\@menu\n";
348    }
349    else
350    {
351      print $FH "\@item \@strong{$item:}\n\@table \@asis\n";
352    }
353    while ($text =~ /(.*\n)/g)
354    {
355      $line = $1;
356      if ($1 =~ /^\s*(\w+)\((.*?)\)/)
357      {
358        OutProcInfo($FH, $proc, $procargs, $pinfo, $l_fun) if $proc && $pinfo;
359        $proc = $1;
360        $procargs = $2;
361        $pinfo = $';
362      }
363      else
364      {
365        $pinfo .= $line; 
366      }
367    }
368    OutProcInfo($FH, $proc, $procargs, $pinfo, $l_fun) if $proc && $pinfo;
369    print $FH ($l_fun ? "\@end menu\n" : "\@end table\n");
370    return '';
371  }
372  elsif ($item =~ m/keywords/i || m/keyphrases/i)
373  {
374    # index entries
375    return OutKeywords($FH, $text);
376  }
377 
378  if (! $table_is_open)
379  {
380    print $FH "\@table \@asis\n";
381    $table_is_open = 1;
382  }
383  print $FH '@item @strong{'. "$item:}\n";
384  # prepare text:
385  local $_ = $text;
386  if (($item =~ m/^library/i)  && m/\s*(\w*)\.lib/)
387  {
388    print $FH "$1.lib\n";
389    $text = $';
390    if ($text =~ /\w/)
391    {
392      print $FH '@item @strong{Purpose:'."}\n";
393      print $FH lc $text;
394    }
395  }
396  else
397  {
398    # just print the text
399    FormatInfoText(length($item) + 1);
400    print $FH "$_\n";
401  }
402  return '';
403}
404
405sub OutProcInfo
406{
407  my($FH, $proc, $procargs, $pinfo, $l_fun) = @_;
408  local $_ = $pinfo;
409  s/^[;\s]*//;
410  s/\n/ /g;
411  FormatInfoText();
412  if ($l_fun)
413  {
414    print $FH "* ${proc}:: $_";
415    push @procs, $proc;
416  }
417  else
418  {
419    print $FH "\@item \@code{$proc($procargs)}  ";
420    print $FH "\n\@cindex $proc\n$_";
421  }
422}
423
424sub OutRef
425{
426  my ($FH, $refs) = @_;
427  $refs =~ s/^\s*//;
428  $refs =~ s/\s*$//;
429  $refs =~ s/\n/,/g;
430  my @refs = split (/[,;\.]+/, $refs);
431  my $ref;
432  print $FH "\@c ref\n";
433  $ref = shift @refs;
434  print $FH "\@ref{$ref}";
435  for $ref (@refs)
436  {
437    $ref =~ s/^\s*//;
438    $ref =~ s/\s*$//;
439    print $FH ", \@ref{$ref}"  if ($ref =~ /\w/);
440  }
441  print $FH "\n\@c ref\n\n";
442
443}
444
445sub OutKeywords
446{
447  my ($FH, $kws) = @_;
448  for $kw (split (/;/, $kws))
449  {
450    $kw =~ s/^\s*(.*?)\s*$/$1/;
451    print $FH "\@cindex $kw\n";
452  }
453}
454
455sub CleanUpExample
456{
457  local($lib, $example) = @_;
458 
459  # find portion in {}
460  $example =~ s/^[^{]*{(.*)}[^}]*$/$1/s;
461
462  if ($example =~ /EXAMPLE: \(not executed\)/)
463  {
464    # erase first three lines
465    $example =~ s/^.*\n.*\n.*\n/\n/;
466    # erase enclosing " " in every line
467    $example =~ s/\n\s*"/\n/g;
468    $example =~  s/";\n/\n/g;
469  }
470  # erase EXAMPLE, echo and pause statements
471  $example =~ s/"EXAMPLE.*"[^;]*;//g;
472  $example .= "\n";
473  my ($mexample, $line);
474  while ($example =~ m/(.*)\n/g)
475  {
476    $line = $1;
477    $line =~ s|echo[^;]*;||g if $line !~ m|(.*)//(.*)echo[^;]*;|;
478    $line =~ s|pause\(.*?\)[^;]*;||g if $line !~ m|(.*)//(.*)pause\(.*?\)[^;]*;|;
479    $mexample .= "$line\n";
480  }
481  $example = $mexample;
482 
483  # prepend LIB command
484  $example = "LIB \"$lib.lib\";\n".$example 
485    if ($example && $lib ne "standard");
486  # erase empty lines
487  $example =~ s/^\s*\n//g;
488  # erase spaces from beginning of lines
489  $example =~ s/\n\s*/\n/g;
490  $example =~ s/\s*$//g;
491  return $example;
492}
493
494sub print_doc_header
495{
496  my $fh = shift;
497  ($hlp_file = $out_file) =~ s/doc$/hlp/;
498  print $fh <<EOT;
499\\input texinfo   \@c -*-texinfo-*-
500\@c %**start of header
501\@setfilename $hlp_file
502\@settitle Formatted manual of $lib.lib
503\@paragraphindent 0
504\@c %**end of header
505
506\@ifinfo
507This file documents contains the formatted documentation of $library
508\@end ifinfo
509
510\@titlepage
511\@title Formatted manual of $library
512\@end titlepage
513
514\@node Top, , , (dir)
515
516\@ifnottex
517This file contains the formatted documentation of $library
518\@end ifnottex
519
520\@menu
521* Singular libraries::
522* Index::
523\@end menu
524
525\@node Singular libraries, Index,,Top
526\@comment node-name,next, previous, up
527\@chapter Singular libraries
528
529\@menu
530* ${lib}_lib:: 
531\@end menu
532 
533\@node ${lib}_lib,,,Singular libraries
534\@section ${lib}_lib
535
536\@example
537-------BEGIN OF PART WHICH IS INCLUDED IN MANUAL-----
538\@end example
539
540
541EOT
542}
Note: See TracBrowser for help on using the repository browser.