| 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 |