File Coverage

blib/lib/Pod/PerlPoint.pm
Criterion Covered Total %
statement 96 104 92.3
branch 23 30 76.6
condition 13 23 56.5
subroutine 36 42 85.7
pod 1 34 2.9
total 169 233 72.5


line stmt bran cond sub pod time code
1              
2              
3             # = HISTORY SECTION =====================================================================
4              
5             # ---------------------------------------------------------------------------------------
6             # version | date | author | changes
7             # ---------------------------------------------------------------------------------------
8             # 0.05 |28.12.2004| JSTENZEL | new configure() allows to switch to dotted text paragraphs
9             # | | | (as introduced by PerlPoint::Parser 0.40);
10             # 0.04 |29.05.2004| JSTENZEL | now supports "=for perlpoint" and "=begin perlpoint";
11             # | | JSTENZEL | bugfix: X is equivalent to \X{mode=index_only},
12             # | | | not \X;
13             # 0.03 |03.01.2003| JSTENZEL | headlines are preceded by explicit empty lines now;
14             # | | JSTENZEL | bugfix: \L's address option is "url", not "a";
15             # | | JSTENZEL | variable __pod2pp__empty__ is now (un)set within
16             # | | | the generated PerlPoint, users do no longer have to
17             # | | | take care of it themselves;
18             # 0.02 |04.12.2002| JSTENZEL | new implementation (derived from Pod::Simple::Text).
19             # 0.01 |01.09.2002| JSTENZEL | First version on base of Pod::Parser.
20             # ---------------------------------------------------------------------------------------
21              
22             # = POD SECTION =========================================================================
23              
24             =head1 NAME
25              
26             B - a POD to PerlPoint converter class
27              
28             =head1 VERSION
29              
30             This manual describes version B<0.05>.
31              
32             =head1 SYNOPSIS
33              
34             # load the module
35             use Pod::PerlPoint;
36              
37             # build an object
38             $d=new Pod::PerlPoint;
39              
40             # process the POD source
41             $d->parse_file($podFile);
42              
43              
44             =head1 DESCRIPTION
45              
46             C is a translator class to transform POD documents into PerlPoint
47             sources. It is based on C and inherits all its capabilities, so please
48             see the docs of C for advanced features.
49              
50             Once you have transformed a POD document into PerlPoint, it may be furtherly processed
51             using the PerlPoint utilities.
52              
53             If you prefer, you do not need to perform an explicit transformation. Beginning with
54             release 0.38, C can process POD sources directly. Please see
55             C for details, or the documentation that comes with PerlPoint.
56              
57             =head1 METHODS
58              
59             This module directly provides a constructor only. As C is a subclass
60             of , all the methods of this parent class are available as well.
61              
62             The constructor takes the exactly same parameters as C,
63             please see there for details.
64              
65             =cut
66              
67              
68              
69              
70             # check perl version
71             require 5;
72              
73             # = PACKAGE SECTION ======================================================================
74              
75             # declare package
76             package Pod::PerlPoint;
77              
78             # declare package version
79             $VERSION=0.05;
80              
81             # declare attributes
82 1     1   20072 use fields qw(_safeStartString);
  1         3142  
  1         7  
83              
84             # inheritance
85             @ISA=(qw(Pod::Simple::Methody));
86              
87              
88             # = PRAGMA SECTION =======================================================================
89              
90             # set pragmata
91 1     1   178 use strict;
  1         2  
  1         41  
92              
93              
94             # = LIBRARY SECTION ======================================================================
95              
96             # load modules
97 1     1   6 use Carp;
  1         7  
  1         81  
98 1     1   6662 use Pod::Simple;
  1         67859  
  1         126  
99 1     1   1376 use Pod::Simple::Methody;
  1         494  
  1         30  
100              
101 1     1   1320 use Data::Dumper;
  1         12182  
  1         289  
102              
103              
104             # = CODE SECTION =========================================================================
105              
106              
107             # just copied from Pod::Simple::Text ...
108 1 50   1   3152 BEGIN {*DEBUG=defined(&Pod::Simple::DEBUG) ? \&Pod::Simple::DEBUG : sub() {0}}
109              
110             # constructor
111             sub new
112             {
113             # get parameters (classname or object)
114 2     2 1 23 my $me=shift;
115              
116             # call base class constructor to build the new object
117 2         21 my $new=$me->SUPER::new(@_);
118              
119             # register embedded perlpoint
120 2         83 $new->accept_target('perlpoint');
121              
122             # configure output target
123 2   50     126 $new->{output_fh}||=*STDOUT{IO};
124              
125             # configure object
126 2         5 $new->{paragraph}='';
127 2         5 $new->{_pod2ppEmptyVarDefined}=0;
128 2         5 $new->{_safeStartString}='${__pod2pp__empty__}';
129              
130             # provide the new object
131 2         5 $new;
132             }
133              
134             # configuration
135             sub configure
136             {
137             # get and check parameters
138 1     1 0 11993 my ($me, %pars)=@_;
139 1 50       7 confess "[BUG] Missing object parameter.\n" unless $me;
140 1 50 33     23 confess "[BUG] Object parameter is no ", __PACKAGE__, " object.\n" unless ref $me and $me->isa(__PACKAGE__);
141              
142             # prepare dotted texts, if necessary
143 1 50 33     13 $me->{_safeStartString}='.', $me->{_pod2ppEmptyVarDefined}=1
144             if exists $pars{parser40} and $pars{parser40};
145             }
146              
147              
148             # Declare several POD element handlers to produce PerlPoint equivalents.
149              
150             # plain text
151             sub handle_text
152             {
153             # emit immediately in case we are handling embedded PerlPoint
154 60 100   60 0 1535 print({$_[0]->{output_fh}} $_[1], "\n\n"), return if $_[0]{perlpoint};
  4         17  
155              
156             # escape special characters (which are not only special at the *beginning*
157             # of a paragraph), if necessary
158 56 100       282 $_[1]=~s/([\\>~])/\\$1/g unless $_[0]{verbatimFlag};
159              
160             # check paragraph beginning, guard special characters, if necessary
161             # (such characters which have a special PerlPoint meaning but are pure text in POD)
162 56 100       161 $_[0]{paragraph}=$_[0]{_safeStartString} unless length($_[0]{paragraph});
163              
164             # add a definition of the special variable used, unless done before
165 56 100       171 $_[0]{_pod2ppEmptyVarDefined}=1, $_[0]{paragraph}="\n\n\$__pod2pp__empty__=\n\n$_[0]{paragraph}" unless $_[0]{_pod2ppEmptyVarDefined};
166              
167             # update text collection
168 56         586 $_[0]{paragraph}.=$_[1];
169              
170             # if we are at the beginning of a numbered list, flag that text was seen
171 56 100 100     469 $_[0]{nlist}=2 if length($_[1]) and exists $_[0]{nlist} and $_[0]{nlist}==1;
      100        
172             }
173              
174              
175             # paragraph - reset internal buffer at the beginning, flush it when completed
176 10     10 0 5627 sub start_Para {$_[0]{paragraph}='';}
177 10     10 0 100 sub end_Para {$_[0]->emit_par(0);}
178              
179             # headlines
180 2     2 0 3462 sub start_head1 {$_[0]->_start_head(1)}
181 2     2 0 38 sub end_head1 {$_[0]->emit_par(-4);}
182              
183 2     2 0 947 sub start_head2 {$_[0]->_start_head(2)}
184 2     2 0 29 sub end_head2 {$_[0]->emit_par(-3);}
185              
186 0     0 0 0 sub start_head3 {$_[0]->_start_head(3)}
187 0     0 0 0 sub end_head3 {$_[0]->emit_par(-2);}
188              
189 0     0 0 0 sub start_head4 {$_[0]->_start_head(4)}
190 0     0 0 0 sub end_head4 {$_[0]->emit_par(-1);}
191              
192             # internal helper method
193             sub _start_head
194             {
195             # store current headline level
196 4     4   16 $_[0]{headlineLevel}=$_[1];
197              
198             # start headline, precede it by empty lines to avoid inclusion confusion
199 4         25 $_[0]{paragraph}=join('', "\n\n", '=' x $_[1]);
200             }
201              
202              
203 4     4 0 1392 sub start_over_number {push(@{$_[0]{listType}}, '');}
  4         54  
204 4     4 0 374 sub end_over_number {pop(@{$_[0]{listType}});}
  4         16  
205              
206             # list elements: bullet list elements ...
207             sub start_item_bullet
208             {
209             # begin bullet point
210 4     4 0 4433 $_[0]{paragraph}='* ';
211             }
212              
213 4     4 0 149 sub end_item_bullet {$_[0]->emit_par(0);}
214              
215             # ... numbered list elements ...
216             sub start_item_number
217             {
218             # flag that we are within a numbered list (might possibly need to be stacked
219             # for nested list levels)
220 6     6 0 1833 $_[0]{nlist}=1;
221              
222             # begin the list point (in case of a continued list, mark this case)
223 6 100 66     45 $_[0]{paragraph}=($_[0]{listType}[-1] and $_[0]{listType}[-1] eq '#') ? '## ' : '# ';
224              
225             # add a definition of the special variable used, unless done before
226 6 50       17 $_[0]{_pod2ppEmptyVarDefined}=1, $_[0]{paragraph}="\n\n\$__pod2pp__empty__=\n\n$_[0]{paragraph}" unless $_[0]{_pod2ppEmptyVarDefined};
227              
228             # store list type
229 6         21 $_[0]{listType}[-1]='#';
230             }
231              
232             sub end_item_number
233             {
234             # in POD, numbered points might begin with a verbatim block directly, which
235             # would produce syntactically incorrect PerlPoint without care
236 6 100   6 0 90 $_[0]{paragraph}.=$_[0]{_safeStartString} if $_[0]{nlist}==1;
237              
238             # now flush as usual
239 6         19 $_[0]->emit_par(0);
240              
241             # reset flag
242 6         17 $_[0]{nlist}=0;
243             }
244              
245             # ... and text elements - make them subchapters (makes them anchors implicitly,
246             # which matches POD's behaviour)
247             sub start_item_text
248             {
249 0     0 0 0 $_[0]{paragraph}='=' x ($_[0]{headlineLevel}+1);
250             }
251              
252 0     0 0 0 sub end_item_text {$_[0]->emit_par(-2);}
253              
254             # tag support - possibly we need to add S<>, but I am not sure
255 2     2 0 32 sub start_B {$_[0]{paragraph}.='\B<';}
256 2     2 0 36 sub start_C {$_[0]{paragraph}.='\C<';}
257 2     2 0 34 sub start_F {$_[0]{paragraph}.='\C<';}
258 6     6 0 95 sub start_I {$_[0]{paragraph}.='\I<';}
259 2     2 0 38 sub start_X {$_[0]{paragraph}.='\X{mode=index_only}<';}
260              
261             sub start_L
262             {
263             # get attributes
264 4     4 0 130 my ($me, $attribs)=@_;
265              
266             # do we support the link type?
267 4 100 33     41 if ($attribs->{type} eq 'url')
    50 33        
268             {
269             # get target and guard special characters
270 2         6 (my $target=$attribs->{to})=~s/([=\"])/\\$1/g;
271              
272             # prepare the link
273 2         30 $_[0]{paragraph}.=qq(\\L{url="$target"}<);
274              
275             # mark that the link type is supported
276 2         24 push(@{$me->{lstack}}, 1);
  2         10  
277             }
278             elsif ($attribs->{type} eq 'pod' and not defined $attribs->{to} and $attribs->{section})
279             {
280             # get target and guard special characters
281 2         78 (my $target=$attribs->{section})=~s/([=\"])/\\$1/g;
282              
283             # prepare the link
284 2         28 $_[0]{paragraph}.=qq(\\REF{type=linked occasion=1 name="$target"}<);
285              
286             # mark that the link type is supported
287 2         24 push(@{$me->{lstack}}, 1);
  2         9  
288             }
289             else
290             {
291             # currently unsupported link - mark this
292 0         0 push(@{$me->{lstack}}, 0);
  0         0  
293             }
294             }
295              
296 4 50   4 0 41 sub end_L {$_[0]{paragraph}.='>' if pop(@{$_[0]{lstack}});}
  4         18  
297              
298              
299             # all tags are completed by a ">"
300 14     14 0 246 sub endTag {$_[0]{paragraph}.='>';}
301              
302             *end_B=\&endTag;
303             *end_C=\&endTag;
304             *end_F=\&endTag;
305             *end_I=\&endTag;
306             *end_X=\&endTag;
307              
308              
309             sub start_for
310             {
311             # flag that we are in a target section
312 4     4 0 948 $_[0]{perlpoint}=1;
313             }
314              
315             sub end_for
316             {
317             # flag that the target section is complete
318 4     4 0 392 $_[0]{perlpoint}=0;
319             }
320              
321              
322             # present what we collected (paragraph flush, used for most paragraph types)
323             sub emit_par
324             {
325             # get object
326 24     24 0 34 my $me=$_[0];
327              
328             # character translation copied from Pod::Simple::Text ...
329 24         49 $me->{paragraph}=~tr{\xAD}{}d if Pod::Simple::ASCII;
330              
331             # add a newline, perform further translation
332 24         47 my $out=$me->{paragraph}.="\n";
333 24         33 $out=~tr{\xA0}{ } if Pod::Simple::ASCII;
334              
335             # flush
336 24         102 print {$me->{output_fh}} $out, "\n";
  24         110  
337              
338             # reset internal buffer
339 24         8626 $me->{paragraph}='';
340             }
341              
342              
343             # verbatim paragraphs: we only need to transform them into "here documents"
344             sub start_Verbatim
345             {
346             # start "here document" (EOVPPB=end of verbatim PerlPoint block)
347 6     6 0 2849 $_[0]{paragraph}="<<___EOVPPB__\n\n";
348              
349             # flag that we are within a verbatim paragraph
350 6         22 $_[0]{verbatimFlag}=1;
351             }
352              
353             sub end_Verbatim
354             {
355             # get object
356 6     6 0 64 my $me=shift;
357              
358             # flag that the verbatim paragraph is complete
359 6         13 $me->{verbatimFlag}=0;
360              
361             # character translation copied from Pod::Simple::Text ...
362 6         9 if(Pod::Simple::ASCII)
363             {
364 6         13 $me->{paragraph}=~tr{\xA0}{ };
365 6         13 $me->{paragraph}=~tr{\xAD}{}d;
366             }
367              
368             # flush
369 6         758 print {$me->{output_fh}} '', $me->{paragraph}, "\n\n___EOVPPB__\n\n";
  6         31  
370              
371             # reset internal buffer
372 6         81 $me->{paragraph}='';
373             }
374              
375              
376             # flag successful loading
377             1;
378              
379              
380              
381              
382             # = POD TRAILER SECTION =================================================================
383              
384             =pod
385              
386             =head1 NOTES
387              
388              
389             =head2 Nested lists
390              
391             List nesting is I transformed by this version. This means that the list points
392             are translated, but without taking care of possibly nested levels.
393              
394              
395             =head2 Text list entries
396              
397             POD knows text lists, which are made hyperlink anchors implicitly. To reflect this
398             best, C transforms them into I.
399              
400              
401             =head2 Hyperlink support
402              
403             The C tag has several special meanings in POD, see L. Especially you
404             can link into other POD documents, even by section. Contrary to this, other POD sources
405             are unknown when a translation into PerlPoint is processed.
406              
407             So currently C only supports two types of hypelinks:
408              
409             =over 4
410              
411             =item Hyperlinks to external addresses
412              
413             Example:
414              
415             L
416              
417             Such a link is transformed using PerlPoints C<\L> tag.
418              
419             \L{url="http://use.perl.org"}
420              
421             =item Links to other sections of the same document
422              
423             Example:
424              
425             L
426              
427             Such a link us transformed using PerlPoints C<\REF> tag. In case the POD author
428             used an invalid link, the generated links is made optional.
429              
430             \REF{type=linked occasion=1 name="Section"}<"Section">
431              
432              
433              
434             =head2 PerlPoint parser version and variable $__pod2pp__empty__
435              
436             Unless C is called with C set to a true value, a PerlPoint variable
437             C<$__pod2pp__empty__> is used to start text paragraphs with, to avoid
438             conflicts caused by startup characters that are special to PerlPoint, but just text in POD.
439              
440             It is assumed that this variable is not used elsewhere. The generated PerlPoint unsets
441             it to make sure it is really empty.
442              
443             PerlPoint parsers 0.40 and above support I to safe generated texts.
444             Please call C with C set to a true value before you process your sources
445             by C etc.
446              
447             Please upgrade to C 0.40 or better, if possible.
448              
449              
450             =head2 POD index Tag
451              
452             The POD index tag C is supported and translated into its PerlPoint equivalent, C<\X>.
453              
454              
455             =head2 Embedded PerlPoint
456              
457             PerlPoint embedded into the POD source is automatically processed when using the
458             C<=for perlpoint> or C<=begin perlpoint>/C<=end perlpoint> syntax.
459              
460             A I text.
461              
462             =for perlpoint
463             A \I text!
464              
465             This is B again.
466              
467             =begin perlpoint
468              
469             Now for a \B example:
470              
471             $r=\I<10+20>;
472              
473             And a table:
474              
475             @|
476             column 1 | column 2
477             cell 1 | cell 2
478             cell 3 | cell 4
479              
480             =end perlpoint
481              
482              
483              
484             =head1 Credits
485              
486             This module is strongly based on Pod::Simple::Text. Thanks to its author
487             Sean M. Burke.
488              
489             =head1 SEE ALSO
490              
491             =over 4
492              
493             =item B
494              
495             The module that made it easy to write C on base of it.
496              
497             =item B
498              
499             A bundle of packages to deal with PerlPoint documents.
500              
501             =item B
502              
503             A POD to PerlPoint translator, distributed and installed with this module.
504              
505             =item B
506              
507             A PerlPoint to POD translator that comes with C.
508              
509              
510             =back
511              
512              
513             =head1 SUPPORT
514              
515             A PerlPoint mailing list is set up to discuss usage, ideas,
516             bugs, suggestions and translator development. To subscribe,
517             please send an empty message to perlpoint-subscribe@perl.org.
518              
519             If you prefer, you can contact me via perl@jochen-stenzel.de
520             as well.
521              
522              
523             =head1 AUTHOR
524              
525             Copyright (c) Jochen Stenzel (perl@jochen-stenzel.de), 2002.
526             All rights reserved.
527              
528             This module is free software, you can redistribute it and/or modify it
529             under the terms of the Artistic License distributed with Perl version
530             5.003 or (at your option) any later version. Please refer to the
531             Artistic License that came with your Perl distribution for more
532             details.
533              
534             The Artistic License should have been included in your distribution of
535             Perl. It resides in the file named "Artistic" at the top-level of the
536             Perl source tree (where Perl was downloaded/unpacked - ask your
537             system administrator if you dont know where this is). Alternatively,
538             the current version of the Artistic License distributed with Perl can
539             be viewed on-line on the World-Wide Web (WWW) from the following URL:
540             http://www.perl.com/perl/misc/Artistic.html
541              
542              
543             =head1 DISCLAIMER
544              
545             This software is distributed in the hope that it will be useful, but
546             is provided "AS IS" WITHOUT WARRANTY OF ANY KIND, either expressed or
547             implied, INCLUDING, without limitation, the implied warranties of
548             MERCHANTABILITY and FITNESS FOR A PARTICULAR PURPOSE.
549              
550             The ENTIRE RISK as to the quality and performance of the software
551             IS WITH YOU (the holder of the software). Should the software prove
552             defective, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
553             CORRECTION.
554              
555             IN NO EVENT WILL ANY COPYRIGHT HOLDER OR ANY OTHER PARTY WHO MAY CREATE,
556             MODIFY, OR DISTRIBUTE THE SOFTWARE BE LIABLE OR RESPONSIBLE TO YOU OR TO
557             ANY OTHER ENTITY FOR ANY KIND OF DAMAGES (no matter how awful - not even
558             if they arise from known or unknown flaws in the software).
559              
560             Please refer to the Artistic License that came with your Perl
561             distribution for more details.
562