File Coverage

blib/lib/Pod/Text.pm
Criterion Covered Total %
statement 310 342 90.6
branch 108 144 75.0
condition 37 49 75.5
subroutine 57 58 98.2
pod 6 46 13.0
total 518 639 81.0


line stmt bran cond sub pod time code
1             # Convert POD data to formatted text.
2             #
3             # This module converts POD to formatted text. It replaces the old Pod::Text
4             # module that came with versions of Perl prior to 5.6.0 and attempts to match
5             # its output except for some specific circumstances where other decisions
6             # seemed to produce better output. It uses Pod::Parser and is designed to be
7             # very easy to subclass.
8             #
9             # Perl core hackers, please note that this module is also separately
10             # maintained outside of the Perl core as part of the podlators. Please send
11             # me any patches at the address above in addition to sending them to the
12             # standard Perl mailing lists.
13             #
14             # Copyright 1999, 2000, 2001, 2002, 2004, 2006, 2008, 2009, 2012, 2013, 2014,
15             # 2015, 2016 Russ Allbery
16             #
17             # This program is free software; you may redistribute it and/or modify it
18             # under the same terms as Perl itself.
19              
20             ##############################################################################
21             # Modules and declarations
22             ##############################################################################
23              
24             package Pod::Text;
25              
26 12     12   194981 use 5.006;
  12         50  
27 12     12   67 use strict;
  12         19  
  12         394  
28 12     12   64 use warnings;
  12         28  
  12         561  
29              
30 12     12   67 use vars qw(@ISA @EXPORT %ESCAPES $VERSION);
  12         19  
  12         1171  
31              
32 12     12   70 use Carp qw(carp croak);
  12         28  
  12         1166  
33 12     12   7334 use Encode qw(encode);
  12         119133  
  12         1180  
34 12     12   106 use Exporter ();
  12         24  
  12         1196  
35 12     12   11025 use Pod::Simple ();
  12         308041  
  12         68746  
36              
37             @ISA = qw(Pod::Simple Exporter);
38              
39             # We have to export pod2text for backward compatibility.
40             @EXPORT = qw(pod2text);
41              
42             $VERSION = '4.09';
43              
44             # Ensure that $Pod::Simple::nbsp and $Pod::Simple::shy are available. Code
45             # taken from Pod::Simple 3.32, but was only added in 3.30.
46             my ($NBSP, $SHY);
47             if ($Pod::Simple::VERSION ge 3.30) {
48             $NBSP = $Pod::Simple::nbsp;
49             $SHY = $Pod::Simple::shy;
50             } else {
51             if ($] ge 5.007_003) {
52             $NBSP = chr utf8::unicode_to_native(0xA0);
53             $SHY = chr utf8::unicode_to_native(0xAD);
54             } elsif (Pod::Simple::ASCII) {
55             $NBSP = "\xA0";
56             $SHY = "\xAD";
57             } else {
58             $NBSP = "\x41";
59             $SHY = "\xCA";
60             }
61             }
62              
63             ##############################################################################
64             # Initialization
65             ##############################################################################
66              
67             # This function handles code blocks. It's registered as a callback to
68             # Pod::Simple and therefore doesn't work as a regular method call, but all it
69             # does is call output_code with the line.
70             sub handle_code {
71 8     8 0 137 my ($line, $number, $parser) = @_;
72 8         17 $parser->output_code ($line . "\n");
73             }
74              
75             # Initialize the object and set various Pod::Simple options that we need.
76             # Here, we also process any additional options passed to the constructor or
77             # set up defaults if none were given. Note that all internal object keys are
78             # in all-caps, reserving all lower-case object keys for Pod::Simple and user
79             # arguments.
80             sub new {
81 29     29 1 81965 my $class = shift;
82 29         243 my $self = $class->SUPER::new;
83              
84             # Tell Pod::Simple to handle S<> by automatically inserting  .
85 29         1015 $self->nbsp_for_S (1);
86              
87             # Tell Pod::Simple to keep whitespace whenever possible.
88 29 50       608 if ($self->can ('preserve_whitespace')) {
89 29         127 $self->preserve_whitespace (1);
90             } else {
91 0         0 $self->fullstop_space_harden (1);
92             }
93              
94             # The =for and =begin targets that we accept.
95 29         299 $self->accept_targets (qw/text TEXT/);
96              
97             # Ensure that contiguous blocks of code are merged together. Otherwise,
98             # some of the guesswork heuristics don't work right.
99 29         853 $self->merge_text (1);
100              
101             # Pod::Simple doesn't do anything useful with our arguments, but we want
102             # to put them in our object as hash keys and values. This could cause
103             # problems if we ever clash with Pod::Simple's own internal class
104             # variables.
105 29         222 my %opts = @_;
106 29         90 my @opts = map { ("opt_$_", $opts{$_}) } keys %opts;
  16         119  
107 29         242 %$self = (%$self, @opts);
108              
109             # Send errors to stderr if requested.
110 29 100 66     256 if ($$self{opt_stderr} and not $$self{opt_errors}) {
111 1         6 $$self{opt_errors} = 'stderr';
112             }
113 29         56 delete $$self{opt_stderr};
114              
115             # Validate the errors parameter and act on it.
116 29 100       121 if (not defined $$self{opt_errors}) {
117 24         78 $$self{opt_errors} = 'pod';
118             }
119 29 100 100     334 if ($$self{opt_errors} eq 'stderr' || $$self{opt_errors} eq 'die') {
    100          
    50          
120 3         19 $self->no_errata_section (1);
121 3         33 $self->complain_stderr (1);
122 3 100       29 if ($$self{opt_errors} eq 'die') {
123 1         4 $$self{complain_die} = 1;
124             }
125             } elsif ($$self{opt_errors} eq 'pod') {
126 25         150 $self->no_errata_section (0);
127 25         267 $self->complain_stderr (0);
128             } elsif ($$self{opt_errors} eq 'none') {
129 1         14 $self->no_whining (1);
130             } else {
131 0         0 croak (qq(Invalid errors setting: "$$self{errors}"));
132             }
133 29         164 delete $$self{errors};
134              
135             # Initialize various things from our parameters.
136 29 100       158 $$self{opt_alt} = 0 unless defined $$self{opt_alt};
137 29 50       109 $$self{opt_indent} = 4 unless defined $$self{opt_indent};
138 29 100       137 $$self{opt_margin} = 0 unless defined $$self{opt_margin};
139 29 50       99 $$self{opt_loose} = 0 unless defined $$self{opt_loose};
140 29 100       104 $$self{opt_sentence} = 0 unless defined $$self{opt_sentence};
141 29 50       107 $$self{opt_width} = 76 unless defined $$self{opt_width};
142              
143             # Figure out what quotes we'll be using for C<> text.
144 29   100     231 $$self{opt_quotes} ||= '"';
145 29 50       237 if ($$self{opt_quotes} eq 'none') {
    100          
    50          
146 0         0 $$self{LQUOTE} = $$self{RQUOTE} = '';
147             } elsif (length ($$self{opt_quotes}) == 1) {
148 28         173 $$self{LQUOTE} = $$self{RQUOTE} = $$self{opt_quotes};
149             } elsif (length ($$self{opt_quotes}) % 2 == 0) {
150 1         4 my $length = length ($$self{opt_quotes}) / 2;
151 1         5 $$self{LQUOTE} = substr ($$self{opt_quotes}, 0, $length);
152 1         4 $$self{RQUOTE} = substr ($$self{opt_quotes}, $length);
153             } else {
154 0         0 croak qq(Invalid quote specification "$$self{opt_quotes}");
155             }
156              
157             # If requested, do something with the non-POD text.
158 29 100       117 $self->code_handler (\&handle_code) if $$self{opt_code};
159              
160             # Return the created object.
161 29         137 return $self;
162             }
163              
164             ##############################################################################
165             # Core parsing
166             ##############################################################################
167              
168             # This is the glue that connects the code below with Pod::Simple itself. The
169             # goal is to convert the event stream coming from the POD parser into method
170             # calls to handlers once the complete content of a tag has been seen. Each
171             # paragraph or POD command will have textual content associated with it, and
172             # as soon as all of a paragraph or POD command has been seen, that content
173             # will be passed in to the corresponding method for handling that type of
174             # object. The exceptions are handlers for lists, which have opening tag
175             # handlers and closing tag handlers that will be called right away.
176             #
177             # The internal hash key PENDING is used to store the contents of a tag until
178             # all of it has been seen. It holds a stack of open tags, each one
179             # represented by a tuple of the attributes hash for the tag and the contents
180             # of the tag.
181              
182             # Add a block of text to the contents of the current node, formatting it
183             # according to the current formatting instructions as we do.
184             sub _handle_text {
185 1075     1075   8165 my ($self, $text) = @_;
186 1075         1632 my $tag = $$self{PENDING}[-1];
187 1075         3088 $$tag[1] .= $text;
188             }
189              
190             # Given an element name, get the corresponding method name.
191             sub method_for_element {
192 2204     2204 0 2707 my ($self, $element) = @_;
193 2204         2952 $element =~ tr/-/_/;
194 2204         2528 $element =~ tr/A-Z/a-z/;
195 2204         2614 $element =~ tr/_a-z0-9//cd;
196 2204         4369 return $element;
197             }
198              
199             # Handle the start of a new element. If cmd_element is defined, assume that
200             # we need to collect the entire tree for this element before passing it to the
201             # element method, and create a new tree into which we'll collect blocks of
202             # text and nested elements. Otherwise, if start_element is defined, call it.
203             sub _handle_element_start {
204 1102     1102   245432 my ($self, $element, $attrs) = @_;
205 1102         2132 my $method = $self->method_for_element ($element);
206              
207             # If we have a command handler, we need to accumulate the contents of the
208             # tag before calling it.
209 1102 100       6089 if ($self->can ("cmd_$method")) {
    100          
210 994         1104 push (@{ $$self{PENDING} }, [ $attrs, '' ]);
  994         3675  
211             } elsif ($self->can ("start_$method")) {
212 106         196 my $method = 'start_' . $method;
213 106         368 $self->$method ($attrs, '');
214             }
215             }
216              
217             # Handle the end of an element. If we had a cmd_ method for this element,
218             # this is where we pass along the text that we've accumulated. Otherwise, if
219             # we have an end_ method for the element, call that.
220             sub _handle_element_end {
221 1102     1102   12044 my ($self, $element) = @_;
222 1102         1876 my $method = $self->method_for_element ($element);
223              
224             # If we have a command handler, pull off the pending text and pass it to
225             # the handler along with the saved attribute hash.
226 1102 100       4678 if ($self->can ("cmd_$method")) {
    100          
227 994         962 my $tag = pop @{ $$self{PENDING} };
  994         1690  
228 994         1641 my $method = 'cmd_' . $method;
229 994         2682 my $text = $self->$method (@$tag);
230 994 50       3469 if (defined $text) {
231 994 100       1060 if (@{ $$self{PENDING} } > 1) {
  994         2385  
232 344         1312 $$self{PENDING}[-1][1] .= $text;
233             } else {
234 650         1282 $self->output ($text);
235             }
236             }
237             } elsif ($self->can ("end_$method")) {
238 106         189 my $method = 'end_' . $method;
239 106         355 $self->$method ();
240             }
241             }
242              
243             ##############################################################################
244             # Output formatting
245             ##############################################################################
246              
247             # Wrap a line, indenting by the current left margin. We can't use Text::Wrap
248             # because it plays games with tabs. We can't use formline, even though we'd
249             # really like to, because it screws up non-printing characters. So we have to
250             # do the wrapping ourselves.
251             sub wrap {
252 162     162 0 214 my $self = shift;
253 162         250 local $_ = shift;
254 162         199 my $output = '';
255 162         322 my $spaces = ' ' x $$self{MARGIN};
256 162         277 my $width = $$self{opt_width} - $$self{MARGIN};
257 162         491 while (length > $width) {
258 40 50 33     666 if (s/^([^\n]{0,$width})\s+// || s/^([^\n]{$width})//) {
259 40         236 $output .= $spaces . $1 . "\n";
260             } else {
261 0         0 last;
262             }
263             }
264 162         359 $output .= $spaces . $_;
265 162         978 $output =~ s/\s+$/\n\n/;
266 162         658 return $output;
267             }
268              
269             # Reformat a paragraph of text for the current margin. Takes the text to
270             # reformat and returns the formatted text.
271             sub reformat {
272 465     465 0 662 my $self = shift;
273 465         836 local $_ = shift;
274              
275             # If we're trying to preserve two spaces after sentences, do some munging
276             # to support that. Otherwise, smash all repeated whitespace.
277 465 100       886 if ($$self{opt_sentence}) {
278 1         5 s/ +$//mg;
279 1         4 s/\.\n/. \n/g;
280 1         4 s/\n/ /g;
281 1         3 s/ +/ /g;
282             } else {
283 464         3732 s/\s+/ /g;
284             }
285 465         1616 return $self->wrap ($_);
286             }
287              
288             # Output text to the output device. Replace non-breaking spaces with spaces
289             # and soft hyphens with nothing, and then try to fix the output encoding if
290             # necessary to match the input encoding unless UTF-8 output is forced. This
291             # preserves the traditional pass-through behavior of Pod::Text.
292             sub output {
293 1243     1243 0 2749 my ($self, @text) = @_;
294 1243         2324 my $text = join ('', @text);
295 1243 50       2703 if ($NBSP) {
296 1243         3049 $text =~ s/$NBSP/ /g;
297             }
298 1243 50       2238 if ($SHY) {
299 1243         1939 $text =~ s/$SHY//g;
300             }
301 1243 100       2773 unless ($$self{opt_utf8}) {
302 1223   100     4645 my $encoding = $$self{encoding} || '';
303 1223 100 100     3128 if ($encoding && $encoding ne $$self{ENCODING}) {
304 5         12 $$self{ENCODING} = $encoding;
305 5     1   10 eval { binmode ($$self{output_fh}, ":encoding($encoding)") };
  5         110  
  1         10  
  1         2  
  1         9  
306             }
307             }
308 1243 50       3444 if ($$self{ENCODE}) {
309 0         0 print { $$self{output_fh} } encode ('UTF-8', $text);
  0         0  
310             } else {
311 1243         1214 print { $$self{output_fh} } $text;
  1243         4826  
312             }
313             }
314              
315             # Output a block of code (something that isn't part of the POD text). Called
316             # by preprocess_paragraph only if we were given the code option. Exists here
317             # only so that it can be overridden by subclasses.
318 8     8 0 11 sub output_code { $_[0]->output ($_[1]) }
319              
320             ##############################################################################
321             # Document initialization
322             ##############################################################################
323              
324             # Set up various things that have to be initialized on a per-document basis.
325             sub start_document {
326 40     40 0 70 my ($self, $attrs) = @_;
327 40 100 66     194 if ($$attrs{contentless} && !$$self{ALWAYS_EMIT_SOMETHING}) {
328 1         3 $$self{CONTENTLESS} = 1;
329             } else {
330 39         70 delete $$self{CONTENTLESS};
331             }
332 40         82 my $margin = $$self{opt_indent} + $$self{opt_margin};
333              
334             # Initialize a few per-document variables.
335 40         85 $$self{INDENTS} = []; # Stack of indentations.
336 40         104 $$self{MARGIN} = $margin; # Default left margin.
337 40         147 $$self{PENDING} = [[]]; # Pending output.
338              
339             # We have to redo encoding handling for each document.
340 40         112 $$self{ENCODING} = '';
341              
342             # When UTF-8 output is set, check whether our output file handle already
343             # has a PerlIO encoding layer set. If it does not, we'll need to encode
344             # our output before printing it (handled in the output() sub). Wrap the
345             # check in an eval to handle versions of Perl without PerlIO.
346 40         63 $$self{ENCODE} = 0;
347 40 100       134 if ($$self{opt_utf8}) {
348 2         5 $$self{ENCODE} = 1;
349 2         3 eval {
350 2         7 my @options = (output => 1, details => 1);
351 2         18 my $flag = (PerlIO::get_layers ($$self{output_fh}, @options))[-1];
352 2 50       28 if ($flag & PerlIO::F_UTF8 ()) {
353 2         3 $$self{ENCODE} = 0;
354 2         6 $$self{ENCODING} = 'UTF-8';
355             }
356             };
357             }
358              
359 40         125 return '';
360             }
361              
362             # Handle the end of the document. The only thing we do is handle dying on POD
363             # errors, since Pod::Parser currently doesn't.
364             sub end_document {
365 40     40 0 81 my ($self) = @_;
366 40 100 66     224 if ($$self{complain_die} && $self->errors_seen) {
367 1         348 croak ("POD document had syntax errors");
368             }
369             }
370              
371             ##############################################################################
372             # Text blocks
373             ##############################################################################
374              
375             # Intended for subclasses to override, this method returns text with any
376             # non-printing formatting codes stripped out so that length() correctly
377             # returns the length of the text. For basic Pod::Text, it does nothing.
378             sub strip_format {
379 49     49 0 76 my ($self, $string) = @_;
380 49         106 return $string;
381             }
382              
383             # This method is called whenever an =item command is complete (in other words,
384             # we've seen its associated paragraph or know for certain that it doesn't have
385             # one). It gets the paragraph associated with the item as an argument. If
386             # that argument is empty, just output the item tag; if it contains a newline,
387             # output the item tag followed by the newline. Otherwise, see if there's
388             # enough room for us to output the item tag in the margin of the text or if we
389             # have to put it on a separate line.
390             sub item {
391 136     136 1 249 my ($self, $text) = @_;
392 136         211 my $tag = $$self{ITEM};
393 136 50       365 unless (defined $tag) {
394 0         0 carp "Item called without tag";
395 0         0 return;
396             }
397 136         223 undef $$self{ITEM};
398              
399             # Calculate the indentation and margin. $fits is set to true if the tag
400             # will fit into the margin of the paragraph given our indentation level.
401 136         202 my $indent = $$self{INDENTS}[-1];
402 136 50       309 $indent = $$self{opt_indent} unless defined $indent;
403 136         319 my $margin = ' ' x $$self{opt_margin};
404 136         431 my $tag_length = length ($self->strip_format ($tag));
405 136         1287 my $fits = ($$self{MARGIN} - $indent >= $tag_length + 1);
406              
407             # If the tag doesn't fit, or if we have no associated text, print out the
408             # tag separately. Otherwise, put the tag in the margin of the paragraph.
409 136 100 100     1393 if (!$text || $text =~ /^\s+$/ || !$fits) {
      100        
410 39         69 my $realindent = $$self{MARGIN};
411 39         77 $$self{MARGIN} = $indent;
412 39         109 my $output = $self->reformat ($tag);
413 39 100 66     164 $output =~ s/^$margin /$margin:/ if ($$self{opt_alt} && $indent > 0);
414 39         270 $output =~ s/\n*$/\n/;
415              
416             # If the text is just whitespace, we have an empty item paragraph;
417             # this can result from =over/=item/=back without any intermixed
418             # paragraphs. Insert some whitespace to keep the =item from merging
419             # into the next paragraph.
420 39 100 100     227 $output .= "\n" if $text && $text =~ /^\s*$/;
421              
422 39         90 $self->output ($output);
423 39         268 $$self{MARGIN} = $realindent;
424 39 100 100     262 $self->output ($self->reformat ($text)) if ($text && $text =~ /\S/);
425             } else {
426 97         186 my $space = ' ' x $indent;
427 97 100       274 $space =~ s/^$margin /$margin:/ if $$self{opt_alt};
428 97         249 $text = $self->reformat ($text);
429 97 100 66     388 $text =~ s/^$margin /$margin:/ if ($$self{opt_alt} && $indent > 0);
430 97         157 my $tagspace = ' ' x $tag_length;
431 97 50       1680 $text =~ s/^($space)$tagspace/$1$tag/ or warn "Bizarre space in item";
432 97         313 $self->output ($text);
433             }
434             }
435              
436             # Handle a basic block of text. The only tricky thing here is that if there
437             # is a pending item tag, we need to format this as an item paragraph.
438             sub cmd_para {
439 394     394 0 617 my ($self, $attrs, $text) = @_;
440 394         2001 $text =~ s/\s+$/\n/;
441 394 100       1016 if (defined $$self{ITEM}) {
442 87         387 $self->item ($text . "\n");
443             } else {
444 307         1066 $self->output ($self->reformat ($text . "\n"));
445             }
446 394         3658 return '';
447             }
448              
449             # Handle a verbatim paragraph. Just print it out, but indent it according to
450             # our margin.
451             sub cmd_verbatim {
452 22     22 0 73 my ($self, $attrs, $text) = @_;
453 22 50       64 $self->item if defined $$self{ITEM};
454 22 50       84 return if $text =~ /^\s*$/;
455 22         94 $text =~ s/^(\n*)([ \t]*\S+)/$1 . (' ' x $$self{MARGIN}) . $2/gme;
  111         465  
456 22         641 $text =~ s/\s*$/\n\n/;
457 22         52 $self->output ($text);
458 22         181 return '';
459             }
460              
461             # Handle literal text (produced by =for and similar constructs). Just output
462             # it with the minimum of changes.
463             sub cmd_data {
464 2     2 0 5 my ($self, $attrs, $text) = @_;
465 2         5 $text =~ s/^\n+//;
466 2         11 $text =~ s/\n{0,2}$/\n/;
467 2         5 $self->output ($text);
468 2         4 return '';
469             }
470              
471             ##############################################################################
472             # Headings
473             ##############################################################################
474              
475             # The common code for handling all headers. Takes the header text, the
476             # indentation, and the surrounding marker for the alt formatting method.
477             sub heading {
478 79     79 0 179 my ($self, $text, $indent, $marker) = @_;
479 79 50       297 $self->item ("\n\n") if defined $$self{ITEM};
480 79         389 $text =~ s/\s+$//;
481 79 100       459 if ($$self{opt_alt}) {
482 1         5 my $closemark = reverse (split (//, $marker));
483 1         3 my $margin = ' ' x $$self{opt_margin};
484 1         6 $self->output ("\n" . "$margin$marker $text $closemark" . "\n\n");
485             } else {
486 78 50       221 $text .= "\n" if $$self{opt_loose};
487 78         235 my $margin = ' ' x ($$self{opt_margin} + $indent);
488 78         319 $self->output ($margin . $text . "\n");
489             }
490 79         618 return '';
491             }
492              
493             # First level heading.
494             sub cmd_head1 {
495 72     72 0 644 my ($self, $attrs, $text) = @_;
496 72         268 $self->heading ($text, 0, '====');
497             }
498              
499             # Second level heading.
500             sub cmd_head2 {
501 8     8 0 61 my ($self, $attrs, $text) = @_;
502 8         35 $self->heading ($text, $$self{opt_indent} / 2, '== ');
503             }
504              
505             # Third level heading.
506             sub cmd_head3 {
507 8     8 0 14 my ($self, $attrs, $text) = @_;
508 8         37 $self->heading ($text, $$self{opt_indent} * 2 / 3 + 0.5, '= ');
509             }
510              
511             # Fourth level heading.
512             sub cmd_head4 {
513 8     8 0 31 my ($self, $attrs, $text) = @_;
514 8         48 $self->heading ($text, $$self{opt_indent} * 3 / 4 + 0.5, '- ');
515             }
516              
517             ##############################################################################
518             # List handling
519             ##############################################################################
520              
521             # Handle the beginning of an =over block. Takes the type of the block as the
522             # first argument, and then the attr hash. This is called by the handlers for
523             # the four different types of lists (bullet, number, text, and block).
524             sub over_common_start {
525 66     66 0 149 my ($self, $attrs) = @_;
526 66 50       259 $self->item ("\n\n") if defined $$self{ITEM};
527              
528             # Find the indentation level.
529 66         150 my $indent = $$attrs{indent};
530 66 50 33     699 unless (defined ($indent) && $indent =~ /^\s*[-+]?\d{1,4}\s*$/) {
531 0         0 $indent = $$self{opt_indent};
532             }
533              
534             # Add this to our stack of indents and increase our current margin.
535 66         96 push (@{ $$self{INDENTS} }, $$self{MARGIN});
  66         223  
536 66         180 $$self{MARGIN} += ($indent + 0);
537 66         264 return '';
538             }
539              
540             # End an =over block. Takes no options other than the class pointer. Output
541             # any pending items and then pop one level of indentation.
542             sub over_common_end {
543 66     66 0 117 my ($self) = @_;
544 66 100       226 $self->item ("\n\n") if defined $$self{ITEM};
545 66         76 $$self{MARGIN} = pop @{ $$self{INDENTS} };
  66         173  
546 66         351 return '';
547             }
548              
549             # Dispatch the start and end calls as appropriate.
550 8     8 0 29 sub start_over_bullet { $_[0]->over_common_start ($_[1]) }
551 8     8 0 28 sub start_over_number { $_[0]->over_common_start ($_[1]) }
552 38     38 0 195 sub start_over_text { $_[0]->over_common_start ($_[1]) }
553 12     12 0 42 sub start_over_block { $_[0]->over_common_start ($_[1]) }
554 8     8 0 24 sub end_over_bullet { $_[0]->over_common_end }
555 8     8 0 25 sub end_over_number { $_[0]->over_common_end }
556 38     38 0 172 sub end_over_text { $_[0]->over_common_end }
557 12     12 0 30 sub end_over_block { $_[0]->over_common_end }
558              
559             # The common handler for all item commands. Takes the type of the item, the
560             # attributes, and then the text of the item.
561             sub item_common {
562 136     136 0 232 my ($self, $type, $attrs, $text) = @_;
563 136 100       470 $self->item if defined $$self{ITEM};
564              
565             # Clean up the text. We want to end up with two variables, one ($text)
566             # which contains any body text after taking out the item portion, and
567             # another ($item) which contains the actual item text. Note the use of
568             # the internal Pod::Simple attribute here; that's a potential land mine.
569 136         447 $text =~ s/\s+$//;
570 136         161 my ($item, $index);
571 136 100       491 if ($type eq 'bullet') {
    100          
572 16         36 $item = '*';
573             } elsif ($type eq 'number') {
574 16         37 $item = $$attrs{'~orig_content'};
575             } else {
576 104         150 $item = $text;
577 104         178 $item =~ s/\s*\n\s*/ /g;
578 104         257 $text = '';
579             }
580 136         272 $$self{ITEM} = $item;
581              
582             # If body text for this item was included, go ahead and output that now.
583 136 100       314 if ($text) {
584 32         296 $text =~ s/\s*$/\n/;
585 32         92 $self->item ($text);
586             }
587 136         753 return '';
588             }
589              
590             # Dispatch the item commands to the appropriate place.
591 16     16 0 22 sub cmd_item_bullet { my $self = shift; $self->item_common ('bullet', @_) }
  16         42  
592 16     16 0 30 sub cmd_item_number { my $self = shift; $self->item_common ('number', @_) }
  16         44  
593 104     104 0 201 sub cmd_item_text { my $self = shift; $self->item_common ('text', @_) }
  104         350  
594 0     0 0 0 sub cmd_item_block { my $self = shift; $self->item_common ('block', @_) }
  0         0  
595              
596             ##############################################################################
597             # Formatting codes
598             ##############################################################################
599              
600             # The simple ones.
601 10 50   10 0 47 sub cmd_b { return $_[0]{alt} ? "``$_[2]''" : $_[2] }
602 6 50   6 0 37 sub cmd_f { return $_[0]{alt} ? "\"$_[2]\"" : $_[2] }
603 11     11 0 58 sub cmd_i { return '*' . $_[2] . '*' }
604 4     4 0 16 sub cmd_x { return '' }
605              
606             # Apply a whole bunch of messy heuristics to not quote things that don't
607             # benefit from being quoted. These originally come from Barrie Slaymaker and
608             # largely duplicate code in Pod::Man.
609             sub cmd_c {
610 113     113 0 187 my ($self, $attrs, $text) = @_;
611              
612             # A regex that matches the portion of a variable reference that's the
613             # array or hash index, separated out just because we want to use it in
614             # several places in the following regex.
615 113         189 my $index = '(?: \[.*\] | \{.*\} )?';
616              
617             # Check for things that we don't want to quote, and if we find any of
618             # them, return the string with just a font change and no quoting.
619 113 100       3016 $text =~ m{
620             ^\s*
621             (?:
622             ( [\'\`\"] ) .* \1 # already quoted
623             | \` .* \' # `quoted'
624             | \$+ [\#^]? \S $index # special ($^Foo, $")
625             | [\$\@%&*]+ \#? [:\'\w]+ $index # plain var or func
626             | [\$\@%&*]* [:\'\w]+ (?: -> )? \(\s*[^\s,]\s*\) # 0/1-arg func call
627             | [+-]? ( \d[\d.]* | \.\d+ ) (?: [eE][+-]?\d+ )? # a number
628             | 0x [a-fA-F\d]+ # a hex constant
629             )
630             \s*\z
631             }xo && return $text;
632              
633             # If we didn't return, go ahead and quote the text.
634             return $$self{opt_alt}
635 105 50       630 ? "``$text''"
636             : "$$self{LQUOTE}$text$$self{RQUOTE}";
637             }
638              
639             # Links reduce to the text that we're given, wrapped in angle brackets if it's
640             # a URL.
641             sub cmd_l {
642 110     110 0 164 my ($self, $attrs, $text) = @_;
643 110 100       274 if ($$attrs{type} eq 'url') {
644 6 100 66     45 if (not defined($$attrs{to}) or $$attrs{to} eq $text) {
    100          
645 3         68 return "<$text>";
646             } elsif ($$self{opt_nourls}) {
647 1         28 return $text;
648             } else {
649 2         30 return "$text <$$attrs{to}>";
650             }
651             } else {
652 104         228 return $text;
653             }
654             }
655              
656             ##############################################################################
657             # Backwards compatibility
658             ##############################################################################
659              
660             # The old Pod::Text module did everything in a pod2text() function. This
661             # tries to provide the same interface for legacy applications.
662             sub pod2text {
663 1     1 0 788 my @args;
664              
665             # This is really ugly; I hate doing option parsing in the middle of a
666             # module. But the old Pod::Text module supported passing flags to its
667             # entry function, so handle -a and -.
668 1         6 while ($_[0] =~ /^-/) {
669 0         0 my $flag = shift;
670 0 0       0 if ($flag eq '-a') { push (@args, alt => 1) }
  0 0       0  
671 0         0 elsif ($flag =~ /^-(\d+)$/) { push (@args, width => $1) }
672             else {
673 0         0 unshift (@_, $flag);
674 0         0 last;
675             }
676             }
677              
678             # Now that we know what arguments we're using, create the parser.
679 1         6 my $parser = Pod::Text->new (@args);
680              
681             # If two arguments were given, the second argument is going to be a file
682             # handle. That means we want to call parse_from_filehandle(), which means
683             # we need to turn the first argument into a file handle. Magic open will
684             # handle the <&STDIN case automagically.
685 1 50       3 if (defined $_[1]) {
686 0         0 my @fhs = @_;
687 0         0 local *IN;
688 0 0       0 unless (open (IN, $fhs[0])) {
689 0         0 croak ("Can't open $fhs[0] for reading: $!\n");
690 0         0 return;
691             }
692 0         0 $fhs[0] = \*IN;
693 0         0 $parser->output_fh ($fhs[1]);
694 0         0 my $retval = $parser->parse_file ($fhs[0]);
695 0         0 my $fh = $parser->output_fh ();
696 0         0 close $fh;
697 0         0 return $retval;
698             } else {
699 1         4 $parser->output_fh (\*STDOUT);
700 1         6 return $parser->parse_file (@_);
701             }
702             }
703              
704             # Reset the underlying Pod::Simple object between calls to parse_from_file so
705             # that the same object can be reused to convert multiple pages.
706             sub parse_from_file {
707 34     34 1 33315 my $self = shift;
708 34         195 $self->reinit;
709              
710             # Fake the old cutting option to Pod::Parser. This fiddings with internal
711             # Pod::Simple state and is quite ugly; we need a better approach.
712 34 100       854 if (ref ($_[0]) eq 'HASH') {
713 1         2 my $opts = shift @_;
714 1 50 33     9 if (defined ($$opts{-cutting}) && !$$opts{-cutting}) {
715 1         3 $$self{in_pod} = 1;
716 1         2 $$self{last_was_blank} = 1;
717             }
718             }
719              
720             # Do the work.
721 34         256 my $retval = $self->Pod::Simple::parse_from_file (@_);
722              
723             # Flush output, since Pod::Simple doesn't do this. Ideally we should also
724             # close the file descriptor if we had to open one, but we can't easily
725             # figure this out.
726 33         1136 my $fh = $self->output_fh ();
727 33         351 my $oldfh = select $fh;
728 33         92 my $oldflush = $|;
729 33         1346 $| = 1;
730 33         82 print $fh '';
731 33         74 $| = $oldflush;
732 33         185 select $oldfh;
733 33         109 return $retval;
734             }
735              
736             # Pod::Simple failed to provide this backward compatibility function, so
737             # implement it ourselves. File handles are one of the inputs that
738             # parse_from_file supports.
739             sub parse_from_filehandle {
740 1     1 0 20 my $self = shift;
741 1         5 $self->parse_from_file (@_);
742             }
743              
744             # Pod::Simple's parse_file doesn't set output_fh. Wrap the call and do so
745             # ourself unless it was already set by the caller, since our documentation has
746             # always said that this should work.
747             sub parse_file {
748 39     39 1 3956 my ($self, $in) = @_;
749 39 50       143 unless (defined $$self{output_fh}) {
750 0         0 $self->output_fh (\*STDOUT);
751             }
752 39         173 return $self->SUPER::parse_file ($in);
753             }
754              
755             # Do the same for parse_lines, just to be polite. Pod::Simple's man page
756             # implies that the caller is responsible for setting this, but I don't see any
757             # reason not to set a default.
758             sub parse_lines {
759 126     126 1 29708 my ($self, @lines) = @_;
760 126 50       466 unless (defined $$self{output_fh}) {
761 0         0 $self->output_fh (\*STDOUT);
762             }
763 126         627 return $self->SUPER::parse_lines (@lines);
764             }
765              
766             # Likewise for parse_string_document.
767             sub parse_string_document {
768 2     2 1 4724 my ($self, $doc) = @_;
769 2 50       9 unless (defined $$self{output_fh}) {
770 0         0 $self->output_fh (\*STDOUT);
771             }
772 2         15 return $self->SUPER::parse_string_document ($doc);
773             }
774              
775             ##############################################################################
776             # Module return value and documentation
777             ##############################################################################
778              
779             1;
780             __END__