source: git/doc/pl2doc.pl @ 4e425a

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