source: git/doc/pl2doc.pl @ 8a0ba8

spielwiese
Last change on this file since 8a0ba8 was 8a0ba8, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* added lib2doc utility git-svn-id: file:///usr/local/Singular/svn/trunk@3373 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 10.1 KB
Line 
1#!/usr/local/bin/perl
2# $Id: pl2doc.pl,v 1.6 1999-07-28 11:36:32 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$ref = OutLibInfo(\*LDOC, $info, ! $no_fun);
58OutRef(\*LDOC, $ref) if $ref;
59
60###################################################################
61# print  summary
62#
63# print subsections for help of procs
64unless ($no_fun)
65{
66  if ($db_file)
67  {
68    $db_file = $1 if ($db_file =~ /(.*)\..*$/);
69    dbmopen(%CHECKSUMS, $db_file, oct(755)) ||
70      die "Error: can't open chksum data base $db_file";
71  }
72  # print help and example of each function
73  for ($i = 0; $i <= $#procs; $i++)
74  {
75    # print node and section heading
76    print LDOC "\n\@c ------------------- " . $procs[$i]." -------------\n";
77    print LDOC "\@node " . $procs[$i].",";
78    print LDOC " ".$procs[$i+1] if ($i < $#procs);
79    print LDOC ",";
80    print LDOC " ".$procs[$i-1] if ($i > 0);
81    print LDOC ", " . $lib ."_lib\n";
82    print LDOC "\@subsection " . $procs[$i] . "\n";
83    print LDOC "\@cindex ". $procs[$i] . "\n";
84    $CHECKSUMS{$procs[$i]} = $chksum{$procs[$i]} if ($db_file);
85    print LDOC "\@c ---content $procs[$i]---\n";
86    print LDOC "Procedure from library \@code{$lib.lib} (\@pxref{${lib}_lib}).\n\n";
87    if ($help{$procs[$i]} =~ /^\@/)
88    {
89      print LDOC $help{$procs[$i]};
90      $ref = '';
91    }
92    else
93    {
94      print LDOC "\@table \@asis\n";
95      $table_is_open = 1;
96      # print help
97      $ref = OutInfo(\*LDOC, $help{$procs[$i]});
98      print LDOC "\@end table\n";
99    }
100    # print example
101    if ($ex = &CleanUpExample($lib, $example{$procs[$i]}))
102    {
103      print LDOC "\@strong{Example:}\n";
104      print LDOC "\@smallexample\n\@c example\n";
105      print LDOC $ex;
106      print LDOC "\n\@c example\n\@end smallexample\n";
107    }
108    OutRef(\*LDOC, $ref) if $ref;
109    print LDOC "\@c ---end content $procs[$i]---\n";
110  }
111  dbmclose(%CHECKSUMS);
112}
113
114#
115# und Tschuess
116#
117if ($doc)
118{
119 print LDOC <<EOT;
120
121\@bye
122EOT
123}
124 
125close(LDOC);
126exit(0);
127
128###########################################################################
129#
130# parse and print-out libinfo
131#
132sub OutLibInfo
133{
134  my ($FH, $info, $l_fun) = @_;
135  print $FH "\@c ---content LibInfo---\n";
136    if ($info =~ /^\@/)
137  {
138    print $FH $info;
139    return;
140  }
141  print $FH "\@table \@asis\n";
142  $table_is_open = 1;
143 
144  my ($ref) = OutInfo($FH, $info, $l_fun);
145
146  print $FH "\@end table\n" if $table_is_open;
147  print $FH "\@c ---end content LibInfo---\n";
148  $table_is_open = 0;
149  return $ref;
150}
151
152sub OutInfo
153{
154  my ($FH, $info, $l_fun) = @_;
155  if ($info =~ /^\s*\@/)
156  {
157    print $FH $info;
158    return;
159  }
160  $info =~ s/^\s*//;
161  $info =~ s/\s*$//;
162  $info .= "\n";
163
164  my ($item, $text, $line, $ref);
165  while ($info =~ m/(.*\n)/g)
166  {
167    $line = $1;
168    if ($1 =~ /^(\w.+?):(.*\n)/)
169    {
170      $ref .= OutInfoItem($FH, $item, $text, $l_fun) if $item && $text;
171      $item = $1;
172      $text = $2;
173    }
174    else
175    {
176      $text .= $line;
177    }
178  }
179  $ref .= OutInfoItem($FH, $item, $text, $l_fun) if $item && $text;
180  return $ref;
181}
182
183sub FormatInfoText
184{
185  my $length = shift;
186  $length = 0 unless $length;
187  # insert @* infront of all lines whose previous line is shorter than
188  # 60 characters
189  $_ = ' ' x $length . $_;
190  if (/^(.*)\n/)
191  {
192    $_ .= "\n";
193    my $pline;
194    my $line;
195    my $ptext = $_;
196    my $text = '';
197    while ($ptext =~ /(.*)\n/g)
198    {
199      $line = $1;
200      # break line if
201      $text .= '@*' 
202        if ($line =~ /\w/ && $pline =~ /\w/ # line and prev line are not empty
203            && $line !~ /^\s*\@\*/  # line does not start with @*
204            && $pline !~ /\@\*\s*/  # prev line does not end with @*
205            &&
206            ((length($pline) < 60  && # prev line is shorter than 60 chars
207              $pline !~ /\@code{.*?}/ # and does not contain @code, @math
208              && $pline !~ /\@math{.*?}/) 
209             ||
210             $line =~ /^\s*\w*\(.*?\)/ # $line starts with \w*(..)
211             ||
212             $pline =~ /^\s*\w*\(.*?\)[\s;:]*$/)); # prev line is only \w(..)
213      $line =~ s/\s*$//;
214      $text .= "$line\n";
215      $pline = $line;
216    }
217    $_ = $text;
218  }
219  s/\t/ /g;
220  s/\n +/\n/g;
221  s/\s*$//g;
222  s/ +/ /g;  # replace double whitespaces by one
223  s/(\w+\(.*?\))/\@code{$1}/g;
224  s/\@\*\s*/\@\*/g;
225  s/(\@[^\*])/\@$1/g; # escape @ signs, except @*
226  s/{/\@{/g; # escape {}
227  s/}/\@}/g;
228  # unprotect @@math@{@}, @code@{@}
229  while (s/\@\@math\@{(.*?)\@}/\@math{$1}/g) {} 
230  while (s/\@\@code\@{(.*?)\@}/\@code{$1}/g) {}
231  # remove @code{} inside @code{} and inside @math{}
232  while (s/\@math{([^}]*)\@code{(.*?)}(.*)?}/\@math{$1$2$3}/g) {}
233  while (s/\@code{([^}]*)\@code{(.*?)}(.*)?}/\@code{$1$2$3}/g) {}
234}
235
236sub OutInfoItem
237{
238  my ($FH, $item, $text, $l_fun) = @_;
239
240  $item = lc $item;
241  $item = ucfirst $item;
242
243  if ($item =~ /see also/i)
244  {
245    # return references
246    return $text;
247  }
248  elsif ($item =~ m/example/i)
249  {
250    # forget about example, since it comes explicitely
251    return '';
252  }
253  elsif ($item =~ m/procedure/i)
254  {
255    if ($l_fun && $table_is_open)
256    {
257      print $FH "\@end table\n\n";
258      $table_is_open = 0;
259    }
260    $text =~ s/^\s*//;
261    $text =~ s/\s*$//;
262    $text =~ s/.*$// if ($text=~/parameters.*brackets.*are.*optional.*$/);
263    $text .= "\n";
264   
265    my ($proc, $pargs, $pinfo, $line);
266    if ($l_fun)
267    {
268      print $FH "\@strong{$item:}\n\@menu\n";
269    }
270    else
271    {
272      print $FH "\@item \@strong{$item:}\n\@table \@asis\n";
273    }
274    while ($text =~ /(.*\n)/g)
275    {
276      $line = $1;
277      if ($1 =~ /^\s*(\w+)\((.*?)\)/)
278      {
279        OutProcInfo($FH, $proc, $procargs, $pinfo, $l_fun) if $proc && $pinfo;
280        $proc = $1;
281        $procargs = $2;
282        $pinfo = $';
283      }
284      else
285      {
286        $pinfo .= $line; 
287      }
288    }
289    OutProcInfo($FH, $proc, $procargs, $pinfo, $l_fun) if $proc && $pinfo;
290    print $FH ($l_fun ? "\@end menu\n" : "\@end table\n");
291    return '';
292  }
293
294  if (! $table_is_open)
295  {
296    print $FH "\@table \@asis\n";
297    $table_is_open = 1;
298  }
299  print $FH '@item @strong{'. "$item:}\n";
300  # prepare text:
301  local $_ = $text;
302  if (($item =~ m/^library/i)  && m/\s*(\w*)\.lib/)
303  {
304    print $FH "$1.lib\n";
305    $text = $';
306    if ($text =~ /\w/)
307    {
308      print $FH '@item @strong{Purpose:'."}\n";
309      print $FH lc $text;
310    }
311  }
312  else
313  {
314    # just print the text
315    FormatInfoText(length($item) + 1);
316    print $FH "$_\n";
317  }
318  return '';
319}
320
321sub OutProcInfo
322{
323  my($FH, $proc, $procargs, $pinfo, $l_fun) = @_;
324  local $_ = $pinfo;
325  s/^[;\s]*//;
326  s/\n/ /g;
327  FormatInfoText();
328 
329  if ($l_fun)
330  {
331    print $FH "* ${proc}:: $_\n";
332    push @procs, $proc;
333  }
334  else
335  {
336    print $FH "\@item \@code{$proc($procargs)}  ";
337    print $FH "\n\@cindex $proc\n$_\n";
338  }
339}
340
341sub OutRef
342{
343  my ($FH, $refs) = @_;
344  $refs =~ s/^\s*//;
345  $refs =~ s/\s*$//;
346  $refs =~ s/\n/,/g;
347  my @refs = split (/[,;\.]+/, $refs);
348  my $ref;
349  print $FH "\@c ref\n";
350  $ref = shift @refs;
351  print $FH "\@ref{$ref}";
352  for $ref (@refs)
353  {
354    $ref =~ s/^\s*//;
355    $ref =~ s/\s*$//;
356    print $FH ", \@ref{$ref}"  if ($ref =~ /\w/);
357  }
358  print $FH "\n\@c ref\n\n";
359
360}
361
362sub CleanUpExample
363{
364  local($lib, $example) = @_;
365 
366  # find portion in {}
367  $example =~ s/^[^{]*{(.*)}[^}]*$/$1/s;
368
369  if ($example =~ /EXAMPLE: \(not executed\)/)
370  {
371    # erase first three lines
372    $example =~ s/^.*\n.*\n.*\n/\n/;
373    # erase enclosing " " in every line
374    $example =~ s/\n\s*"/\n/g;
375    $example =~  s/";\n/\n/g;
376  }
377  # erase EXAMPLE, echo and pause statements
378  $example =~ s/"EXAMPLE.*"[^;]*;//g;
379  $example .= "\n";
380  my ($mexample, $line);
381  while ($example =~ m/(.*)\n/g)
382  {
383    $line = $1;
384    $line =~ s|echo[^;]*;||g if $line !~ m|(.*)//(.*)echo[^;]*;|;
385    $line =~ s|pause\(.*?\)[^;]*;||g if $line !~ m|(.*)//(.*)pause\(.*?\)[^;]*;|;
386    $mexample .= "$line\n";
387  }
388  $example = $mexample;
389 
390  # prepend LIB command
391  $example = "LIB \"$lib.lib\";\n".$example 
392    if ($example && $lib ne "standard");
393  # erase empty lines
394  $example =~ s/^\s*\n//g;
395  # erase spaces from beginning of lines
396  $example =~ s/\n\s*/\n/g;
397  $example =~ s/\s*$//g;
398  return $example;
399}
400
401sub print_doc_header
402{
403  my $fh = shift;
404  ($hlp_file = $out_file) =~ s/doc$/hlp/;
405  print $fh <<EOT;
406\\input texinfo   \@c -*-texinfo-*-
407\@c %**start of header
408\@setfilename $hlp_file
409\@settitle Formatted manual of $lib.lib
410\@c %**end of header
411
412\@ifinfo
413This file documents contains the formatted documentation of $library
414\@end ifinfo
415
416\@titlepage
417\@title Formatted manual of $library
418\@end titlepage
419
420\@node Top, , , (dir)
421
422\@ifnottex
423This file contains the formatted documentation of $library
424\@end ifnottex
425
426\@menu
427* Singular libraries::
428\@end menu
429
430\@node Singular libraries,,,Top
431\@comment node-name,next, previous, up
432\@chapter Singular libraries
433
434\@menu
435* ${lib}_lib:: 
436\@end menu
437 
438\@node ${lib}_lib,,,Singular libraries
439\@section ${lib}_lib
440
441\@example
442-------BEGIN OF PART WHICH IS INCLUDED IN MANUAL-----
443\@end example
444
445
446EOT
447}
Note: See TracBrowser for help on using the repository browser.