1File::Comments(3) User Contributed Perl Documentation File::Comments(3)
2
3
4
6 File::Comments - Recognizes file formats and extracts format-specific
7 comments
8
10 use File::Comments;
11
12 my $snoop = File::Comments->new();
13
14 # *----------------
15 # | program.c:
16 # | /* comment */
17 # | main () {}
18 # *----------------
19 my $comments = $snoop->comments("program.c");
20 # => [" comment "]
21
22 # *----------------
23 # | script.pl:
24 # | # comment
25 # | print "howdy!\n"; # another comment
26 # *----------------
27 my $comments = $snoop->comments("script.pl");
28 # => [" comment", " another comment"]
29
30 # or strip comments from a file:
31 my $stripped = $snoop->stripped("script.pl");
32 # => "print "howdy!\n";"
33
34 # or just guess a file's type:
35 my $type = $snoop->guess_type("program.c");
36 # => "c"
37
39 File::Comments guesses the type of a given file, determines the format
40 used for comments, extracts all comments, and returns them as a
41 reference to an array of chunks. Alternatively, it strips all comments
42 from a file.
43
44 Currently supported are Perl scripts, C/C++ programs, Java, makefiles,
45 JavaScript, Python and PHP.
46
47 The plugin architecture used by File::Comments makes it easy to add new
48 formats. To support a new format, a new plugin module has to be
49 installed. No modifications to the File::Comments codebase are
50 necessary, new plugins will be picked up automatically.
51
52 File::Comments can also be used to simply guess a file's type. It it
53 somewhat more flexible than File::MMagic and File::Type. File types in
54 File::Comments are typically based on file name suffixes (*.c, *.pl,
55 etc.). If no suffix is available, or a given suffix is ambiguous (e.g.
56 if several plugins have registered a handler for the same suffix), then
57 the file's content is used to narrow down the possibilities and arrive
58 at a decision.
59
60 WARNING: THIS MODULE IS UNDER DEVELOPMENT, QUALITY IS ALPHA. IF YOU
61 FIND BUGS, OR WANT TO CONTRIBUTE PLUGINS, PLEASE SEND THEM MY WAY.
62
63 FILE TYPES
64 Currently, the following plugins are included in the File::Comments
65 distribution:
66
67 ###############################################
68 # plugin type #
69 ###############################################
70 File::Comments::Plugin::C c (o)
71 File::Comments::Plugin::Makefile makefile (X)
72 File::Comments::Plugin::Perl perl (X)
73 File::Comments::Plugin::JavaScript js (o)
74 File::Comments::Plugin::Java java (o)
75 File::Comments::Plugin::HTML html (X)
76 File::Comments::Plugin::Python python (o)
77 File::Comments::Plugin::PHP php (o)
78
79 (X) Fully implemented
80 (o) Implemented with regular expressions, only works for
81 easy cases until real parsers are employed.
82
83 The constants listed in the type column are the strings returned by the
84 "guess_type()" method.
85
87 $snoop = File::Comments->new()
88 Create a new comment extractor engine. This will automatically
89 initialize all plugins.
90
91 To avoid cold calls ("Cold Calls"), set "cold_calls" to a false
92 value (defaults to 1):
93
94 $snoop = File::Comments->new( cold_calls => 0 );
95
96 By default, if no plugin can be found for a given file,
97 "File::Comments" will throw a fatal error and "die()". If this is
98 undesirable and a default plugin should be used instead, it can be
99 specified in the constructor using the "default_plugin" parameter:
100
101 $snoop = File::Comments->new(
102 default_plugin => "File::Comments::Plugin::Makefile"
103 );
104
105 $comments = $snoop->comments("program.c");
106 Extract all comments from a file. After determining the file type
107 by either suffix or content ("Cold Calls"), comments are extracted
108 as chunks and returned as a reference to an array.
109
110 To get a single string containing all comments, just join the
111 chunks:
112
113 my $comments_string = join '', @$comments;
114
115 $stripped_text = $snoop->stripped("program.c");
116 Strip all comments from a file. After determining the file type by
117 either suffix or content ("Cold Calls"), all comments are removed
118 and the stripped text is returned in a scalar.
119
120 $type = $snoop->guess_type("script.pl")
121 Guess the type of a file, based on either suffix, or in absense of
122 a suffix via "Cold Calls". Return the result as a string: "c",
123 "makefile", "perl", etc. ("FILE TYPES").
124
125 $snoop->suffix_registered("c")
126 Returns true if one of the plugins has registered the given suffix.
127
128 Writing new plugins
129 Writing a new plugin to add functionality to the File::Comments
130 framework is as simple as defining a new module, derived from the
131 baseclass of all plugins, "File::Comments::Plugin". Three additional
132 methods are needed: "init()", "type()", and "comments()".
133
134 "init()" gets called when the mothership finds the plugin and
135 initializes it. This is the time to register extensions that the plugin
136 wants to handle.
137
138 The second mandatory method for a plugin is "type()", which returns a
139 string, indicating the type of the file examined. Usually this can be
140 done without further ado, since a basic plugin will called only on
141 files which it registered for by suffix. Exceptions to this are
142 explained later.
143
144 The third method is "comments()", which returns a reference to an array
145 of comment lines. The content of the source file to be examined will be
146 available in
147
148 $self->{target}->{content}
149
150 by the time "comments()" gets called.
151
152 And that's it. Here's a functional basic plugin, registering a new
153 suffix ".odd" with the mothership and expecting files with comment
154 lines that start with "ODDCOMMENT":
155
156 ###########################################
157 package File::Comments::Plugin::Oddball;
158 ###########################################
159
160 use strict;
161 use warnings;
162 use File::Comments::Plugin;
163
164 our $VERSION = "0.01";
165 our @ISA = qw(File::Comments::Plugin);
166
167 ###########################################
168 sub init {
169 ###########################################
170 my($self) = @_;
171
172 $self->register_suffix(".odd");
173 }
174
175 ###########################################
176 sub type {
177 ###########################################
178 my($self) = @_;
179
180 return "odd";
181 }
182
183 ###########################################
184 sub comments {
185 ###########################################
186 my($self) = @_;
187
188 # Some code to extract all comments from
189 # $self->{target}->{content}:
190 my @comments = ($self->{target}->{content} =~ /^ODDCOMMENT:(.*)/);
191 return \@comments;
192 }
193
194 1;
195
196 Cold Calls
197 If a file doesn't have an extension or an extensions that's served by
198 multiple plugins, File::Comments will go shop around and ask all
199 plugins if they want to handle the file. The mothership calls each
200 plugin's "applicable()" method, passing it an object of type
201 "File::Comments::Target", which contains the following fields:
202
203 When the plugin gets such a cold call (indicated by the third parameter
204 to "applicable()", it can either accept or deny the request. To arrive
205 at a decision, it can peek into the target object. The Perl plugin
206 illustrates this:
207
208 ###########################################
209 sub applicable {
210 ###########################################
211 my($self, $target, $cold_call) = @_;
212
213 return 1 unless $cold_call;
214
215 return 1 if $target->{content} =~ /^#!.*perl\b/;
216
217 return 0;
218 }
219
220 If a plugin does not define a "applicable()" method, a default method
221 is inherited from the base class "File::Comments::Plugin", which looks
222 like this:
223
224 ###########################################
225 sub applicable {
226 ###########################################
227 my($self, $target, $cold_call) = @_;
228
229 return 0 if $cold_call;
230 return 1;
231 }
232
233 This will deny all cold calls and only accept requests for files with
234 suffixes or base names the plugin has already signed up for.
235
236 Plugin Inheritance
237 Plugins can reuse existing plugins by inheritance. For example, if you
238 wanted to write a catch-all plugin that takes over all cold calls and
239 handles comments like the "Makefile" plugin, you can simply use
240
241 ###########################################
242 package File::Comments::Plugin::Catchall;
243 ###########################################
244
245 use strict;
246 use warnings;
247 use File::Comments::Plugin;
248 use File::Comments::Plugin::Makefile;
249
250 our $VERSION = "0.01";
251 our @ISA = qw(File::Comments::Plugin::Makefile);
252
253 ###########################################
254 sub applicable {
255 ###########################################
256 my($self) = @_;
257
258 return 1;
259 }
260
261 "File::Comments::Plugin::Catchall" just implements "applicable()" and
262 inherits everything else from "File::Comments::Plugin::Makefile".
263
265 Copyright 2005 by Mike Schilli, all rights reserved. This program is
266 free software, you can redistribute it and/or modify it under the same
267 terms as Perl itself.
268
270 2005, Mike Schilli <cpan@perlmeister.com>
271
272
273
274perl v5.30.1 2020-01-30 File::Comments(3)