line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Emacs::Run::ExtractDocs; |
2
|
1
|
|
|
1
|
|
24819
|
use base qw( Class::Base ); |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
929
|
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
=head1 NAME |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
Emacs::Run::ExtractDocs - extract elisp docstrings to html form |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 SYNOPSIS |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
use Emacs::Run::ExtractDocs; |
11
|
|
|
|
|
|
|
my $reed = Emacs::Run::ExtractDocs->new({ |
12
|
|
|
|
|
|
|
html_output_location => "/tmp/html", |
13
|
|
|
|
|
|
|
}); |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# needed only if extract-docstrings.el isn't in load-path |
16
|
|
|
|
|
|
|
$reed->set_main_library("/tmp/new/elisp/extract-doctrings.el"); |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
$reed->elisp_docstrings_to_html("my-elisp-with-a-lot-of-docstrings.el"); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 DESCRIPTION |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Emacs::Run::ExtractDocs is a module that provides ways of working |
23
|
|
|
|
|
|
|
with the "docstrings" from emacs lisp packages and transforming |
24
|
|
|
|
|
|
|
them to other formats (at present, just html). |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
The central feature is the elisp_docstrings_to_html method, |
27
|
|
|
|
|
|
|
which can create a web page displaying the docstrings of any |
28
|
|
|
|
|
|
|
given elisp package. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
Note that this is a very unusual "perl" package, in that it |
31
|
|
|
|
|
|
|
depends on having emacs installed (most likely, GNU/Emacs). |
32
|
|
|
|
|
|
|
Also, the extract-docstrings.el file that is shipped with this |
33
|
|
|
|
|
|
|
perl package must be installed somewhere in the emacs load-path. |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head2 METHODS |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=over |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=cut |
40
|
|
|
|
|
|
|
|
41
|
1
|
|
|
1
|
|
1387
|
use 5.8.0; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
42
|
|
42
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
28
|
|
43
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
75
|
|
44
|
1
|
|
|
1
|
|
6
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
81
|
|
45
|
1
|
|
|
1
|
|
1232
|
use Data::Dumper; |
|
1
|
|
|
|
|
11688
|
|
|
1
|
|
|
|
|
84
|
|
46
|
1
|
|
|
1
|
|
904
|
use Hash::Util qw( lock_keys unlock_keys ); |
|
1
|
|
|
|
|
2687
|
|
|
1
|
|
|
|
|
7
|
|
47
|
1
|
|
|
1
|
|
108
|
use File::Basename qw( fileparse basename dirname ); |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
77
|
|
48
|
1
|
|
|
1
|
|
1657
|
use Env qw( $HOME ); |
|
1
|
|
|
|
|
3494
|
|
|
1
|
|
|
|
|
9
|
|
49
|
|
|
|
|
|
|
|
50
|
1
|
|
|
1
|
|
1281
|
use Emacs::Run; |
|
1
|
|
|
|
|
37687
|
|
|
1
|
|
|
|
|
771
|
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
our $VERSION = '0.03'; |
53
|
|
|
|
|
|
|
my $DEBUG = 0; # TODO change to 0 before shipping |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
# needed for accessor generation |
56
|
|
|
|
|
|
|
our $AUTOLOAD; |
57
|
|
|
|
|
|
|
my %ATTRIBUTES = (); |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=item new |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
Creates a new Emacs::Run::ExtractDocs object. |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
Takes a hashref as an argument, with named fields identical |
64
|
|
|
|
|
|
|
to the names of the object attributes. These attributes are: |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=over |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=item html_output_location |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
Directory to put generated html. |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=item main_library |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
Defaults to the elisp library name "extract-doctrings", |
75
|
|
|
|
|
|
|
so the system can find "extract-doctrings.el" once it's |
76
|
|
|
|
|
|
|
installed in the emacs load_path. |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
This can be set to a different library name, or more likely |
79
|
|
|
|
|
|
|
to a full path to the extract-docstrings.el in an unusual |
80
|
|
|
|
|
|
|
location. (This is very useful for testing, so that the |
81
|
|
|
|
|
|
|
code can run before it's installed.) |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=item emacs_runner |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
An Emacs::Run object, used internally to call utility |
86
|
|
|
|
|
|
|
routines to probe the emacs installation, and run pieces |
87
|
|
|
|
|
|
|
of emacs lisp code. This will normally be created automatically, |
88
|
|
|
|
|
|
|
but if some unusual options are needed, one can be created |
89
|
|
|
|
|
|
|
externally and passed in as an attribute. |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=back |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
Takes an optional hashref as an argument, with named fields |
94
|
|
|
|
|
|
|
identical to the names of the object attributes. |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=cut |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# Note: "new" is inherited from Class::Base and |
99
|
|
|
|
|
|
|
# calls the following "init" routine automatically. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=item init |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
Method that initializes object attributes and then locks them |
104
|
|
|
|
|
|
|
down to prevent accidental creation of new ones. |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Any class that inherits from this one should have an B of |
107
|
|
|
|
|
|
|
it's own that calls this B. Otherwise, it's an internally |
108
|
|
|
|
|
|
|
used routine that is not of much interest to client coders. |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=cut |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
sub init { |
113
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
114
|
0
|
|
|
|
|
|
my $args = shift; |
115
|
0
|
|
|
|
|
|
unlock_keys( %{ $self } ); |
|
0
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
|
117
|
0
|
0
|
|
|
|
|
if ($DEBUG) { |
118
|
0
|
|
|
|
|
|
$self->debugging(1); |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
0
|
|
|
|
|
|
my @attributes = qw( |
122
|
|
|
|
|
|
|
html_output_location |
123
|
|
|
|
|
|
|
main_library |
124
|
|
|
|
|
|
|
emacs_runner |
125
|
|
|
|
|
|
|
); |
126
|
|
|
|
|
|
|
|
127
|
0
|
|
|
|
|
|
foreach my $field (@attributes) { |
128
|
0
|
|
|
|
|
|
$ATTRIBUTES{ $field } = 1; |
129
|
0
|
|
|
|
|
|
$self->{ $field } = $args->{ $field }; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
# default to the lib name (works once extract-docstrings.el |
133
|
|
|
|
|
|
|
# is installed) |
134
|
0
|
|
0
|
|
|
|
$self->{ main_library } ||= 'extract-docstrings'; |
135
|
0
|
|
|
|
|
|
my $main_library = $self->{ main_library }; |
136
|
|
|
|
|
|
|
|
137
|
0
|
0
|
|
|
|
|
unless ( $self->emacs_runner ) { |
138
|
0
|
|
|
|
|
|
my $er = Emacs::Run->new({ |
139
|
|
|
|
|
|
|
emacs_libs => [ $main_library ], |
140
|
|
|
|
|
|
|
}); |
141
|
0
|
|
|
|
|
|
$self->set_emacs_runner( $er ); |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
0
|
|
|
|
|
|
lock_keys( %{ $self } ); |
|
0
|
|
|
|
|
|
|
145
|
0
|
|
|
|
|
|
return $self; |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=back |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=head2 main methods |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=over |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=item elisp_docstrings_to_html |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
Given the name of an emacs lisp library (sans path or extension), |
157
|
|
|
|
|
|
|
or the file name of the library (with extension *.el), generates |
158
|
|
|
|
|
|
|
an html file in the standard location defined in the object: |
159
|
|
|
|
|
|
|
html_output_location |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
The output file naming convention is: _el.html |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=cut |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub elisp_docstrings_to_html { |
166
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
167
|
0
|
|
|
|
|
|
my $thingie = shift; # either file or library |
168
|
0
|
|
|
|
|
|
my $progname = ( caller(0) )[3]; |
169
|
0
|
|
|
|
|
|
my $er = $self->emacs_runner; |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# Add the given library to the ones loaded by the Emacs::Run object |
172
|
0
|
|
|
|
|
|
$er->push_emacs_libs( $thingie ); |
173
|
|
|
|
|
|
|
|
174
|
0
|
|
|
|
|
|
my $loader_elisp = $er->generate_elisp_to_load_library( $thingie ); |
175
|
0
|
|
|
|
|
|
$loader_elisp = $er->quote_elisp( $loader_elisp ); |
176
|
|
|
|
|
|
|
|
177
|
0
|
|
|
|
|
|
my ($elisp_file, $elisp_lib); |
178
|
0
|
0
|
|
|
|
|
if ( $thingie =~ m/\.el$/ ) { |
179
|
0
|
|
|
|
|
|
$elisp_file = $thingie; |
180
|
0
|
|
|
|
|
|
($elisp_lib, undef, undef) = fileparse( $elisp_file, qr{ \.el$ }x ); |
181
|
|
|
|
|
|
|
} else { |
182
|
0
|
|
|
|
|
|
$elisp_lib = $thingie; |
183
|
0
|
|
|
|
|
|
$elisp_file = $self->emacs_runner->elisp_file_from_library_name_if_in_loadpath( $elisp_lib ); |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
0
|
|
|
|
|
|
my $output_loc = $self->html_output_location; |
187
|
0
|
|
|
|
|
|
my $output_file = "$output_loc/$elisp_lib" . '_el.html'; |
188
|
|
|
|
|
|
|
|
189
|
0
|
0
|
|
|
|
|
unlink $output_file if -e $output_file; # redundant with elisp feature |
190
|
|
|
|
|
|
|
|
191
|
0
|
|
|
|
|
|
my $extractor_elisp = qq{ |
192
|
|
|
|
|
|
|
(extract-doctrings-generate-html-for-elisp-file |
193
|
|
|
|
|
|
|
"$elisp_file" |
194
|
|
|
|
|
|
|
"$output_file" |
195
|
|
|
|
|
|
|
"Documentation for $elisp_lib.el (extracted docstrings)") |
196
|
|
|
|
|
|
|
}; |
197
|
|
|
|
|
|
|
|
198
|
0
|
|
|
|
|
|
$self->emacs_runner->eval_elisp( $extractor_elisp ); # Note: eval_elisp does a quote_elisp internally. |
199
|
|
|
|
|
|
|
|
200
|
0
|
|
|
|
|
|
my $output_created_flag = -e $output_file; |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
# check that there's a closing |