1 Javadoc-style Perl Documentation Generator
2 ==========================================
3 :author: Aaron Ball
4 :email: nullspoon@iohq.net
5
6
7 == {doctitle}
8
9 I'm not a huge fan of Java, but I really do appreciate their standards for code
10 comments. I use them in my PHP, C+\+, and Perl code. There is obviously some
11 changing that needs to happen becuase those languages don't all comment the
12 same, but for the most part it works really well.
13
14 Today I needed to write up a document on how one of my larger scripts/programs
15 worked. I wanted to include the script architecture, but didn't have a good way
16 to do it. Then I remembered something one of my favorite open source projects
17 does. MediaWiki is doing continuous integration and so they use (as I know
18 other OSS projects do) http://jenkins-ci.org/[Jenkins] to do post-commit
19 validation. Specifically relating to this post, they use the Jenkins scripts
20 to verify that the comments for each function are in the right format and
21 contain the right data types, etc. In application to my project at hand, in my
22 Perl scripts this would look something like...
23
24 ----
25 #
26 # This subroutine does something cool
27 #
28 # @param $_[0] string This is a test parameter
29 # @param $_[1] array This is an array reference of mic checks
30 #
31 # @return bool Success or failure of this function's awesomeness
32 #
33 ----
34
35 The commit validation scripts Jenkins uses would check if the subroutine
36 definition did in fact require two parameters and that the function returned
37 boolean. Granted, since Perl isn't strongly typed, this has to be a bit looser
38 than it would for other languages (C+\+, C#, etc), but you get the idea. This
39 documentation style is still awesome (at least, I think it is)
40
41 What I needed today though was a script that parsed my other scripts, read in
42 all the subroutines (Perl, remember?), parsed out the comments for each one,
43 and returned HTML using inline styles so I could copy it into a Word (well,
44 LibreOffice Writer) doc without losing formatting. That said, here's the quick
45 and dirty.
46
47 **Note**: Ironically, I just realized that this script isn't commented.
48
49 ----
50 #!/usr/bin/env perl
51 use warnings;
52 use strict;
53
54 #
55 # This program is free software: you can redistribute it and/or modify
56 # it under the terms of the GNU General Public License as published by
57 # the Free Software Foundation, either version 3 of the License, or
58 # (at your option) any later version.
59 #
60 # This program is distributed in the hope that it will be useful,
61 # but WITHOUT ANY WARRANTY; without even the implied warranty of
62 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63 # GNU General Public License for more details.
64 #
65 # You should have received a copy of the GNU General Public License
66 # along with this program. If not, see <http://www.gnu.org/licenses/>.
67 #
68
69 if( scalar( @ARGV ) < 1 ) {
70 print "\nPlease specify a file to parse.\n\n";
71 exit( 0 );
72 }
73
74 main( @ARGV );
75
76 sub main {
77 my $path = $_[0];
78 # Open our file and do some science!
79 open FILE, $path or die $!;
80 my @lines = <FILE>;
81 close( FILE );
82 my @subs;
83 my $body = '';
84 for( my $i = 0; $i < scalar( @lines ); $i++ ) {
85 my $line = $lines[$i];
86 # Remove leading spaces
87 $line =~ s/^[\t\s]+//;
88 # Remove multiple inner space
89 $line =~ s/[\t\s]+/ /;
90 if( $line =~ /^sub ([\d\w_-]+)[\s{]+$/ ) {
91 my $h2 = "<h2 style=\"margin:0px; padding:0px; display:inline; font-size:1.2em; color:#444;\">";
92 $body .= '<br />' . $h2 . $1 . "()</h2>\n";
93 # We've found one!
94 my $comments = '';
95 # Now we go backwards, nabbing the comments as we go
96 for( my $n = $i - 1; $n > 0; $n-- ) {
97 if( $lines[$n] =~ /#[\w\d\s\t]*/ ) {
98 # Becase we're now reading backwards,
99 # we need to prepend
100 $comments = lineToHtml( $lines[$n] ) . $comments;
101 } else {
102 # Exit and continue
103 $n = 0;
104 }
105 }
106 my $pStyle = "<p style=\"display:block; background-color:#eee; margin:0px;";
107 $pStyle .= "padding:5px; border:1px dashed #aaa; width:90%; font-size:9pt;\">";
108 $comments = $pStyle . $comments . "</p>\n";
109 $body .= $comments;
110 }
111 }
112 $body .= "\n\n";
113 print bodyToHtml( $body );
114 exit( 0 );
115 }
116
117 sub bodyToHtml {
118 my $body = $_[0];
119 my $bodyHeader = '<!DOCTYPE html />';
120 $bodyHeader .= '<html><head>';
121 $bodyHeader .= '</head><body style="font-family:sans-serif;">';
122
123 my $bodyFooter = '</body></html>';
124 return $bodyHeader . $body . $bodyFooter;
125 }
126
127 sub lineToHtml {
128 my $line = $_[0];
129
130 my $formatted = $line;
131 $formatted =~ s/^[#\s\t]+//;
132 $formatted =~ s/\n+//;
133 if( $formatted =~ /^\@param/ ) {
134 $formatted =~ s/\@param/<strong>\@param<\/strong>/;
135 $formatted = '<br /><span style="display:block; color:#499;">' . $formatted . '</span>';
136 } elsif( $formatted =~ /^\@return/ ) {
137 $formatted =~ s/\@return/<strong>\@return<\/strong>/;
138 $formatted = '<br /><span style="display:block; color:#494; margin-top:10px;">' . $formatted . '</span>';
139 }
140 $formatted =~ s/ (int|hash|array|string|boolean|bool) / <span style="color:#949; font-style:italic;">$1<\/span> /i;
141 $formatted .= "\n";
142 return $formatted;
143 }
144 ----
145
146
147
148 // vim: set syntax=asciidoc:
|