File: build-docs.pl

package info (click to toggle)
aegean 0.16.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 8,444 kB
  • sloc: ansic: 12,050; python: 465; sh: 315; makefile: 308; perl: 151
file content (134 lines) | stat: -rwxr-xr-x 3,592 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env perl

# Copyright (c) 2010-2015, Daniel S. Standage and CONTRIBUTORS
#
# The AEGeAn Toolkit is distributed under the ISC License. See
# the 'LICENSE' file in the AEGeAn source code distribution or
# online at https://github.com/standage/AEGeAn/blob/master/LICENSE.
#
# Usage: perl build-docs.pl inc/core inc/ParsEval > docs/api.rst

use strict;
use warnings;
use Getopt::Long;

print "AEGeAn C API\n============\n\nThe AEGeAn Toolkit relies heavily on data
types implemented by the GenomeTools library. For data types beginning with
``Gt``, see the GenomeTools API documentation at
http://genometools.org/libgenometools.html.\n\n";

# Main procedure
my $dir;
foreach my $dirname(@ARGV)
{
  $dir = $dirname;
  opendir(my $dh, $dir) or die("open dir fail");
  while(my $entry = readdir($dh))
  {
    make_docs_from_file("$dir/$entry") if($entry =~ m/\.h$/);
  }
  closedir($dh);
}

# Generate class or module documentation from a header file
sub make_docs_from_file
{
  my $file = shift(@_);
  my $contents = do
  {
    local $/;
    open(my $fh, "<", $file) or die("open file fail: $file");
    <$fh>;
  };

  my @docblocks = $contents =~ m/(\/\*\*.+?\*\/.+?;)/sg;
  return if(@docblocks == 0);

  process_doc_blocks(@docblocks);
}

# Process a set of doc blocks from a class/module header file
sub process_doc_blocks
{
  my $summary = shift(@_);
  do {} while($summary =~ s/\s+\*\s+/ /g);

  if($summary =~ m/\@class/)
  {
    my($class, $description) = $summary =~ m/\/\*\* \@class (\S+) (.+)/;
    my $title = "Class $class";
    my $url = "https://github.com/standage/AEGeAn/blob/master/$dir/$class.h";
    printf("%s\n%s\n\n", $title, "-" x length($title));
    printf(".. c:type:: %s\n\n  %s See the `%s class header <%s>`_.\n\n",
           $class, $description, $class, $url);

    foreach my $block(@_)
    {
      process_doc_block($block);
    }
  }

  elsif($summary =~ m/\@module/)
  {
    my($module, $description) = $summary =~ m/\/\*\* \@module (\S+) (.+)/;
    my $title = "Module $module";
    my $url = "https://github.com/standage/AEGeAn/blob/master/$dir/$module.h";
    printf("%s\n%s\n\n", $title, "-" x length($title));
    printf("%s See the `%s module header <%s>`_.\n\n", $description, $module,
           $url);

    foreach my $block(@_)
    {
      process_doc_block($block);
    }
  }

  else
  {
    die("class/module fail");
  }
}

# Process the doc block corresponding to an individual function or type def
sub process_doc_block
{
  my $block = shift(@_);

  $block =~ s/\/\*\*\W+//s;
  my($type) = $block =~ m/(function|functype|type)/;
  die("block type fail") unless($type);
  $block =~ s/(function|functype|type) *//;
  my($synopsis) = $block =~ m/^(.+?)(\@param|\@member|\*\/)/s;
  $synopsis =~ s/\*//g;
  $synopsis =~ s/\s+/ /sg;
  $synopsis =~ s/\s+$//;

  if($type eq "function")
  {
    my($prototype) = $block =~ m/\*\/\s*(\w[^;]+);/;
    $prototype =~ s/\s+/ /sg;
    print(".. c:function:: $prototype\n\n  $synopsis\n\n");
  }
  elsif($type eq "type")
  {
    my($typetype, $typename) = $block =~ m/(struct|enum) (Agn\S+)/;
    print(".. c:type:: $typename\n\n  $synopsis\n\n");
    my @members = $block =~ m/\@member (.+)/g;
    foreach my $member(@members)
    {
      my($mtype, $mname, $mdesc) = $member =~ m/\[(.+)\] (\S+) (.+)/;
      print("  * **$mtype $mname**: $mdesc\n");
    }
    print("\n\n");
  }
  elsif($type eq "functype")
  {
    my($signature) = $block =~ m/\*\/\s*(\w[^;]+);/;
    $signature =~ s/\s+/ /sg;
    print(".. c:type:: $signature\n\n  $synopsis\n\n");
  }
  else
  {
    die("block type fail");
  }
}