File Coverage

blib/lib/Text/Textile/Plaintext.pm
Criterion Covered Total %
statement 21 44 47.7
branch 0 14 0.0
condition 0 6 0.0
subroutine 7 11 63.6
pod n/a
total 28 75 37.3


line stmt bran cond sub pod time code
1             ###############################################################################
2             #
3             # This file copyright (c) 2009 by Randy J. Ray, all rights reserved
4             #
5             # Copying and distribution are permitted under the terms of the Artistic
6             # License 2.0 (http://www.opensource.org/licenses/artistic-license-2.0.php) or
7             # the GNU LGPL (http://www.opensource.org/licenses/lgpl-2.1.php).
8             #
9             ###############################################################################
10             #
11             # Description: Render plain-text output from Textile input by taking the
12             # HTML content and converting it to text the way LWP's
13             # lwp-request script does.
14             #
15             # Functions: new
16             # textile
17             #
18             # Libraries: Text::Textile
19             # HTML::TreeBuilder
20             # HTML::FormatText
21             #
22             # Global Consts: $VERSION
23             #
24             ###############################################################################
25              
26             package Text::Textile::Plaintext;
27              
28 1     1   991 use 5.008;
  1         4  
  1         45  
29 1     1   7 use strict;
  1         3  
  1         40  
30 1     1   29 use warnings;
  1         2  
  1         39  
31 1     1   13 use vars qw($VERSION @EXPORT @EXPORT_OK);
  1         2  
  1         75  
32 1     1   946 use subs qw(new textile treebuilder formatter);
  1         20  
  1         5  
33 1     1   63 use base qw(Exporter Text::Textile);
  1         2  
  1         1418  
34              
35 1     1   82001 use Scalar::Util qw(blessed reftype);
  1         2  
  1         564  
36             require HTML::TreeBuilder;
37             require HTML::FormatText;
38              
39             $VERSION = '0.101';
40             $VERSION = eval $VERSION; ## no critic
41             @EXPORT = ();
42             @EXPORT_OK = qw(textile);
43              
44             ###############################################################################
45             #
46             # Sub Name: new
47             #
48             # Description: Create a new object of this class by creating a super-class
49             # instance and then adding objects for the parser and text-
50             # formatter.
51             #
52             # Arguments: NAME IN/OUT TYPE DESCRIPTION
53             # $class in scalar Name of the class to bless into
54             # %args in hash If passed, arguments for the
55             # constructer, either for the
56             # super-class or the two that
57             # are specific here (the parser
58             # and text-formatter referents)
59             #
60             # Returns: Success: new object
61             # Failure: whatever Text::Textile::new() returned
62             #
63             ###############################################################################
64             sub new
65             {
66 0     0     my ($class, %args) = @_;
67              
68 0   0       my $htmltree = delete $args{treebuilder} || HTML::TreeBuilder->new();
69 0           my $fmttext = delete $args{formatter};
70              
71 0 0         unless ($fmttext)
72             {
73 0 0         my $lmargin = (exists $args{leftmargin}) ? delete $args{leftmargin} : 0;
74 0 0         my $rmargin =
75             (exists $args{rightmargin}) ? delete $args{rightmargin} : 79;
76 0           $fmttext = HTML::FormatText->new(
77             leftmargin => $lmargin,
78             rightmargin => $rmargin
79             );
80             }
81              
82 0           my $self = $class->SUPER::new(%args);
83 0 0         return $self unless ref($self);
84              
85 0           bless $self, $class;
86 0           $self->treebuilder($htmltree);
87 0           $self->formatter($fmttext);
88              
89 0           $self;
90             }
91              
92             ###############################################################################
93             #
94             # Sub Name: textile
95             #
96             # Description: Overload of the parent's textile() method. Calls the
97             # superclass form, then returns the content formatted to
98             # plain-text via an instance of HTML::TreeBuilder working
99             # with an instance of HTML::FormatText.
100             #
101             # Arguments: NAME IN/OUT TYPE DESCRIPTION
102             # $self in ref If present, an object of this
103             # class. If not present, a
104             # throw-away one is created.
105             # $content in scalar Content to be converted to
106             # plain text.
107             #
108             # Returns: Success: lines of plain text
109             # Failure: whatever the underlying error(s) are/were
110             #
111             ###############################################################################
112             sub textile
113             {
114 0     0     my ($self, $content) = @_;
115              
116             # Check whether this was called procedurally or as a method, by looking to
117             # see if the first value is an object.
118 0 0 0       unless (blessed($self) && $self->isa('Text::Textile::Plaintext'))
119             {
120 0           $content = $self;
121 0           $self = __PACKAGE__->new();
122             }
123              
124             # Use the super-class to turn the Textile into HTML:
125 0           my $html_content = $self->SUPER::textile($content);
126              
127             # Use the accessors to get the HTML::TreeBuilder and HTML::FormatText
128             # objects, and use those to turn the HTML into text. This is also the
129             # return value:
130 0           $self->formatter->format($self->treebuilder->parse($html_content));
131             }
132              
133             ###############################################################################
134             #
135             # Sub Name: treebuilder
136             #
137             # Description: Get or set the instance of an HTML::TreeBuilder-compatible
138             # object to be used to parse/tokenize the HTML that
139             # Text::Textile produces.
140             #
141             # Arguments: NAME IN/OUT TYPE DESCRIPTION
142             # $self in ref Object of this class
143             # $obj in ref If present, new object to save
144             #
145             # Returns: current (new) attribute value
146             #
147             ###############################################################################
148             sub treebuilder
149             {
150 0     0     my ($self, $obj) = @_;
151              
152 0 0         (blessed $obj) ? $self->{__treebuilder} = $obj : $self->{__treebuilder};
153             }
154              
155             ###############################################################################
156             #
157             # Sub Name: formatter
158             #
159             # Description: Get or set the instance of an HTML::FormatText-compatible
160             # object to be used to convert the tokenized HTML to plain
161             # text.
162             #
163             # Arguments: NAME IN/OUT TYPE DESCRIPTION
164             # $self in ref Object of this class
165             # $obj in ref If present, new object to save
166             #
167             # Returns: current (new) attribute value
168             #
169             ###############################################################################
170             sub formatter
171             {
172 0     0     my ($self, $obj) = @_;
173              
174 0 0         (blessed $obj) ? $self->{__formatter} = $obj : $self->{__formatter};
175             }
176              
177             1;
178              
179             =head1 NAME
180              
181             Text::Textile::Plaintext - Convert Textile mark-up to plain text
182              
183             =head1 SYNOPSIS
184              
185             use Text::Textile::Plaintext qw(textile);
186              
187             my $textile = <
188             h1. Heading
189              
190             A _simple_ demonstration of Textile markup.
191              
192             * One
193             * Two
194             * Three
195              
196             "More information":http://www.textism.com/tools/textile is available.
197             EOT
198              
199             # Procedural interface:
200             my $text = textile($textile);
201             print $text;
202              
203             # Object-oriented interface
204             my $ttp = Text::Textile::Plaintext->new();
205             $text = $ttp->process($textile);
206              
207             =head1 DESCRIPTION
208              
209             The B class extends B by running the
210             HTML content that it produces through instances of a tree-builder and a
211             formatter. By default, B and B are used,
212             but classes that match their interfaces can be substituted.
213              
214             The functionality provided by this module is identical to that of
215             B. Note that even the synopsis, above, is lifted directly from
216             there. The only difference is in the format of the output produced.
217              
218             =head1 USAGE
219              
220             As with B, this module's functionality may be used either
221             procedurally or via an object interface. You can import the textile() function
222             and call it without having to first instantiate an object instance. See below
223             for documentation on this function and its calling convention.
224              
225             =head1 METHODS
226              
227             The following methods are available within this class:
228              
229             =over 4
230              
231             =item new([%ARGS])
232              
233             Create a new object of this class. The arguments detailed below, if present,
234             are stripped and processed by B while any remaining
235             arguments are passed to the super-class (B) constructor.
236              
237             The arguments handled locally are:
238              
239             =over 8
240              
241             =item treebuilder
242              
243             Provide a pre-instantiated instance of B (or suitable
244             sub-class) to use in place of new() constructing one itself.
245              
246             =item formatter
247              
248             Provide a pre-instantiated instance of B (or suitable
249             sub-class) to use in place of new() constructing one itself.
250              
251             =item leftmargin
252              
253             =item rightmargin
254              
255             These are passed directly to the constructor of B, unless you
256             passed in a specific formatter instance via the C parameter, above.
257             The defaults for the margins are those set by B (3 for the
258             left margin, 72 for the right).
259              
260             =back
261              
262             Both of the objects (tree-builder and formatter) are kept until after the
263             parent constructor is called and the object re-blessed into the calling
264             class. At that point, the values are assigned to the object using the accessor
265             methods defined below. This allows a sub-class to overload the accessors and
266             handle these parameters.
267              
268             =item textile($textile_content)
269              
270             Convert the Textile mark-up in C<$textile_content> to plain text, and return
271             the converted content. This method is identical in nature and calling form
272             to the same-named method in the parent class. The difference is the production
273             of plain text rather than HTML.
274              
275             This method may be imported and called as a function. In such a case, a
276             temporary B object is created and used to invoke
277             the needed parent class functionality.
278              
279             =item treebuilder([$new])
280              
281             Get or set the C attribute.
282              
283             If a value is given, it is assigned as the new value of the attribute. This
284             must be a reference to an object that is either an instance of
285             B, or an instance of an object that matches its
286             interface. You can use this to assign a tree-builder that has debugging
287             capacity built into it, for example.
288              
289             The return value is the current attribute value (after update).
290              
291             =item formatter([$new])
292              
293             Get or set the C attribute.
294              
295             If a value is given, it is assigned as the new value of the attribute. This
296             must be a reference to an object that is either an instance of
297             B, or an instance of an object that matches its
298             interface. You can use this to assign a formatter that has debugging capacity
299             built into it, for example.
300              
301             The return value is the current attribute value (after update).
302              
303             =back
304              
305             Note that the method process() is not defined here, as it is inherited from
306             B.
307              
308             =head1 DIAGNOSTICS
309              
310             This module makes no effort to trap error messages or exceptions. Any output to
311             STDERR or STDOUT, or calls to C or C by B,
312             B or B will go through unchallenged unless
313             the user sets up their own exception-handling.
314              
315             =head1 CAVEATS
316              
317             In truth, Textile could be converted to text without first being turned into
318             HTML. But B does a good job of handling all the various
319             stylistic syntax that can affect things like paragraph justification, etc.,
320             and the other modules do their jobs quite well, too.
321              
322             The B package has some quirks in the way things are laid-out,
323             such as bulleted lists.
324              
325             =head1 BUGS
326              
327             Please report any bugs or feature requests to C
328             rt.cpan.org>, or through the web interface at
329             L. I
330             will be notified, and then you'll automatically be notified of progress on your
331             bug as I make changes.
332              
333             =head1 SUPPORT
334              
335             =over 4
336              
337             =item * RT: CPAN's request tracker
338              
339             L
340              
341             =item * AnnoCPAN: Annotated CPAN documentation
342              
343             L
344              
345             =item * CPAN Ratings
346              
347             L
348              
349             =item * Search CPAN
350              
351             L
352              
353             =item * Source code on GitHub
354              
355             L
356              
357             =back
358              
359             =head1 COPYRIGHT & LICENSE
360              
361             This file and the code within are copyright (c) 2009 by Randy J. Ray.
362              
363             Copying and distribution are permitted under the terms of the Artistic
364             License 2.0 (L) or
365             the GNU LGPL 2.1 (L).
366              
367             =head1 SEE ALSO
368              
369             L
370              
371             =head1 AUTHOR
372              
373             Randy J. Ray C<< >>
374              
375             =cut