RT# 81961 Pod2Html can use installed libs, or Freeside source
[freeside.git] / FS / FS / Misc / Pod2Html.pm
1 package FS::Misc::Pod2Html;
2 use strict;
3 use warnings;
4 use Carp qw( croak );
5 use File::Copy;
6 use Pod::Simple::HTML;
7 use Pod::Simple::HTMLBatch;
8 use Pod::Simple::Search;
9
10 use base 'Exporter';
11 our @EXPORT_OK = qw(
12   fs_pod2html
13   fs_pod2html_from_src
14   fs_pod2html_from_dirs
15   $include_system_perl_modules
16   $quiet_mode
17 );
18
19 our $include_system_perl_modules = 1;
20 our $quiet_mode = 0;
21 our $DEBUG = 0;
22
23 =head1 NAME
24
25 FS::Misc::Pod2Html
26
27 =head1 DESCRIPTION
28
29 Generate HTML from POD Documentation
30
31 =head1 SYNOPSIS
32
33 Usage:
34
35   use FS::Misc::Pod2Html 'fs_pod2html';
36   fs_pod2html( '/output/directory' );
37
38 Also:
39
40   perl -MFS::Misc::Pod2Html -e "FS::Misc::Pod2Html::fs_pod2html('/tmp/pod2html');"
41
42 =cut
43
44 our $html_before_title = q{
45   <% include( '/elements/header.html', 'Developer Documentation' ) %>
46   <& /elements/menubar.html,
47     'Freeside Perl Modules' => $fsurl.'docs/library/FS.html',
48     'Complete Index' => $fsurl.'docs/library/index.html',
49   &>
50
51   <div style="width: 90%; margin: 1em auto; font-size: .9em; border: solid 1px #666; background-color: #eee; padding: 1em;">
52   <h1 style="margin: .5em; border-bottom: solid 1px #999;">
53 };
54
55 our $html_after_title = q{</h1>};
56
57 our $html_footer = q{</div><% include ('/elements/footer.html' ) %>};
58
59 =head2 fs_pod2html output_dir
60
61 Generates Freeside-themed HTML docuemtnation from installed perl modules
62
63 =cut
64
65 sub fs_pod2html {
66   fs_pod2html_from_dirs(
67     shift,
68     '/usr/local/share/perl/5.24.1',
69     '/usr/local/bin',
70     $include_system_perl_modules ? (
71       '/usr/share/perl5',
72       '/usr/share/perl/5.24',
73       '/usr/share/perl/5.24.1',
74     ) : (),
75   );
76 }
77
78 =head2 fs_pod2html_from_src output_dir
79
80 Generate Freeside-themed HTML documentation from a Freeside source tree
81
82 Will fail, unless run with CWD at the root of the Freesidse source tree
83
84 =cut
85
86 sub fs_pod2html_from_src {
87   my $html_dir = shift;
88
89   fs_pod2html_from_dirs(
90     $html_dir,
91     'FS/bin',
92     'bin',
93     'FS',
94     'fs_selfservice/FS-SelfService',
95     # '/usr/local/share/perl/5.24.1',
96     # '/usr/local/bin',
97     $include_system_perl_modules ? (
98       '/usr/share/perl5',
99       '/usr/share/perl/5.24',
100       '/usr/share/perl/5.24.1',
101     ) : (),
102   );
103
104   # FS-SelfService is loosely packaged:
105   #   perl modules are not stored in lib/FS, scripts not stored in /bin, so
106   # batch_convert() places these .html in the wrong locations
107   #
108   # Copy to correct locations, and correct relative links
109   copy( "$html_dir/SelfService.html", "$html_dir/FS/SelfService.html" );
110   mkdir( "$html_dir/FS/SelfService" );
111   copy( "$html_dir/SelfService/XMLRPC.html", "$html_dir/FS/SelfService/XMLRPC.html" );
112     for my $sed_cmd (
113     'sed -i "s/href=\"\.\//href=\"\.\.\//g" "'.$html_dir.'/FS/SelfService.html"',
114     'sed -i "s/href=\"\\..\//href=\"\.\.\/\.\.\//g" "'.$html_dir.'/FS/SelfService/XMLRPC.html"',
115   ) {
116     `$sed_cmd`
117   }
118 }
119
120 =head2 fs_pod2html output_dir @source_scan_dirs
121
122 Generate Freeside-themed HTML documentation, scanning the provided directories
123
124 =cut
125
126 sub fs_pod2html_from_dirs {
127   my $html_dir = shift
128     or croak 'Please specify an output directory';
129
130   croak "Directory $html_dir: No write access"
131     unless -w $html_dir;
132
133   my @search_dirs = @_;
134
135   for my $dir ( @search_dirs ) {
136     unless ( -d $dir ) {
137       croak "Cannot continue - source directory ($dir) not found! ";
138     }
139   }
140
141   my $parser = Pod::Simple::HTMLBatch->new;
142
143   $parser->verbose(0)
144     if $quiet_mode;
145
146   $parser->verbose(2)
147     if $DEBUG;
148
149   $parser->search_class('Inline::Pod::Simple::Search');
150   $parser->html_render_class('Inline::Pod::Simple::HTML');
151   $parser->contents_page_start(
152     "$html_before_title Freeside Documentation Index $html_after_title"
153   );
154   $parser->contents_page_end( $html_footer );
155
156   $parser->batch_convert( \@search_dirs, $html_dir );
157 }
158
159 1;
160
161 =head1 NAME
162
163 Inline::Pod::Simple::Search
164
165 =head2 DESCRIPTION
166
167 Subclass of Pod::Simple::Search
168
169 Enable searching for POD in all files instead of just .pl and .pm
170
171 =cut
172
173 package Inline::Pod::Simple::Search;
174 use base 'Pod::Simple::Search';
175
176 sub new {
177   my $class = shift;
178   my $self = Pod::Simple::Search->new( @_ );
179   $self->laborious(1);
180   $self->verbose(2)
181     if $DEBUG;
182   $self;
183 }
184
185 1;
186
187 =head1 NAME
188
189 Inline::Pod::Simple::HTML
190
191 =head2 DESCRIPTION
192
193 Subclass of Pod::Simple::HTML
194
195 Customize parsed HTML output
196
197 =cut
198
199 # Subclass Pod::Simple::HTML to control HTML output
200 package Inline::Pod::Simple::HTML;
201 use base 'Pod::Simple::HTML';
202
203 sub html_header_before_title { $html_before_title }
204 sub html_header_after_title { $html_after_title }
205 sub html_footer { $html_footer }
206
207 1;