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# SPDX-License-Identifier: GPL-1.0-or-later OR Artistic-1.0-Perl 10 11############################################################################## 12# Modules and declarations 13############################################################################## 14 15package Pod::Text; 16 17use 5.006; 18use strict; 19use warnings; 20 21use vars qw(@ISA @EXPORT %ESCAPES $VERSION); 22 23use Carp qw(carp croak); 24use Encode qw(encode); 25use Exporter (); 26use Pod::Simple (); 27 28@ISA = qw(Pod::Simple Exporter); 29 30# We have to export pod2text for backward compatibility. 31@EXPORT = qw(pod2text); 32 33$VERSION = '4.11'; 34 35# Ensure that $Pod::Simple::nbsp and $Pod::Simple::shy are available. Code 36# taken from Pod::Simple 3.32, but was only added in 3.30. 37my ($NBSP, $SHY); 38if ($Pod::Simple::VERSION ge 3.30) { 39 $NBSP = $Pod::Simple::nbsp; 40 $SHY = $Pod::Simple::shy; 41} else { 42 if ($] ge 5.007_003) { 43 $NBSP = chr utf8::unicode_to_native(0xA0); 44 $SHY = chr utf8::unicode_to_native(0xAD); 45 } elsif (Pod::Simple::ASCII) { 46 $NBSP = "\xA0"; 47 $SHY = "\xAD"; 48 } else { 49 $NBSP = "\x41"; 50 $SHY = "\xCA"; 51 } 52} 53 54############################################################################## 55# Initialization 56############################################################################## 57 58# This function handles code blocks. It's registered as a callback to 59# Pod::Simple and therefore doesn't work as a regular method call, but all it 60# does is call output_code with the line. 61sub handle_code { 62 my ($line, $number, $parser) = @_; 63 $parser->output_code ($line . "\n"); 64} 65 66# Initialize the object and set various Pod::Simple options that we need. 67# Here, we also process any additional options passed to the constructor or 68# set up defaults if none were given. Note that all internal object keys are 69# in all-caps, reserving all lower-case object keys for Pod::Simple and user 70# arguments. 71sub new { 72 my $class = shift; 73 my $self = $class->SUPER::new; 74 75 # Tell Pod::Simple to handle S<> by automatically inserting . 76 $self->nbsp_for_S (1); 77 78 # Tell Pod::Simple to keep whitespace whenever possible. 79 if ($self->can ('preserve_whitespace')) { 80 $self->preserve_whitespace (1); 81 } else { 82 $self->fullstop_space_harden (1); 83 } 84 85 # The =for and =begin targets that we accept. 86 $self->accept_targets (qw/text TEXT/); 87 88 # Ensure that contiguous blocks of code are merged together. Otherwise, 89 # some of the guesswork heuristics don't work right. 90 $self->merge_text (1); 91 92 # Pod::Simple doesn't do anything useful with our arguments, but we want 93 # to put them in our object as hash keys and values. This could cause 94 # problems if we ever clash with Pod::Simple's own internal class 95 # variables. 96 my %opts = @_; 97 my @opts = map { ("opt_$_", $opts{$_}) } keys %opts; 98 %$self = (%$self, @opts); 99 100 # Send errors to stderr if requested. 101 if ($$self{opt_stderr} and not $$self{opt_errors}) { 102 $$self{opt_errors} = 'stderr'; 103 } 104 delete $$self{opt_stderr}; 105 106 # Validate the errors parameter and act on it. 107 if (not defined $$self{opt_errors}) { 108 $$self{opt_errors} = 'pod'; 109 } 110 if ($$self{opt_errors} eq 'stderr' || $$self{opt_errors} eq 'die') { 111 $self->no_errata_section (1); 112 $self->complain_stderr (1); 113 if ($$self{opt_errors} eq 'die') { 114 $$self{complain_die} = 1; 115 } 116 } elsif ($$self{opt_errors} eq 'pod') { 117 $self->no_errata_section (0); 118 $self->complain_stderr (0); 119 } elsif ($$self{opt_errors} eq 'none') { 120 $self->no_errata_section (1); 121 $self->no_whining (1); 122 } else { 123 croak (qq(Invalid errors setting: "$$self{errors}")); 124 } 125 delete $$self{errors}; 126 127 # Initialize various things from our parameters. 128 $$self{opt_alt} = 0 unless defined $$self{opt_alt}; 129 $$self{opt_indent} = 4 unless defined $$self{opt_indent}; 130 $$self{opt_margin} = 0 unless defined $$self{opt_margin}; 131 $$self{opt_loose} = 0 unless defined $$self{opt_loose}; 132 $$self{opt_sentence} = 0 unless defined $$self{opt_sentence}; 133 $$self{opt_width} = 76 unless defined $$self{opt_width}; 134 135 # Figure out what quotes we'll be using for C<> text. 136 $$self{opt_quotes} ||= '"'; 137 if ($$self{opt_quotes} eq 'none') { 138 $$self{LQUOTE} = $$self{RQUOTE} = ''; 139 } elsif (length ($$self{opt_quotes}) == 1) { 140 $$self{LQUOTE} = $$self{RQUOTE} = $$self{opt_quotes}; 141 } elsif (length ($$self{opt_quotes}) % 2 == 0) { 142 my $length = length ($$self{opt_quotes}) / 2; 143 $$self{LQUOTE} = substr ($$self{opt_quotes}, 0, $length); 144 $$self{RQUOTE} = substr ($$self{opt_quotes}, $length); 145 } else { 146 croak qq(Invalid quote specification "$$self{opt_quotes}"); 147 } 148 149 # If requested, do something with the non-POD text. 150 $self->code_handler (\&handle_code) if $$self{opt_code}; 151 152 # Return the created object. 153 return $self; 154} 155 156############################################################################## 157# Core parsing 158############################################################################## 159 160# This is the glue that connects the code below with Pod::Simple itself. The 161# goal is to convert the event stream coming from the POD parser into method 162# calls to handlers once the complete content of a tag has been seen. Each 163# paragraph or POD command will have textual content associated with it, and 164# as soon as all of a paragraph or POD command has been seen, that content 165# will be passed in to the corresponding method for handling that type of 166# object. The exceptions are handlers for lists, which have opening tag 167# handlers and closing tag handlers that will be called right away. 168# 169# The internal hash key PENDING is used to store the contents of a tag until 170# all of it has been seen. It holds a stack of open tags, each one 171# represented by a tuple of the attributes hash for the tag and the contents 172# of the tag. 173 174# Add a block of text to the contents of the current node, formatting it 175# according to the current formatting instructions as we do. 176sub _handle_text { 177 my ($self, $text) = @_; 178 my $tag = $$self{PENDING}[-1]; 179 $$tag[1] .= $text; 180} 181 182# Given an element name, get the corresponding method name. 183sub method_for_element { 184 my ($self, $element) = @_; 185 $element =~ tr/-/_/; 186 $element =~ tr/A-Z/a-z/; 187 $element =~ tr/_a-z0-9//cd; 188 return $element; 189} 190 191# Handle the start of a new element. If cmd_element is defined, assume that 192# we need to collect the entire tree for this element before passing it to the 193# element method, and create a new tree into which we'll collect blocks of 194# text and nested elements. Otherwise, if start_element is defined, call it. 195sub _handle_element_start { 196 my ($self, $element, $attrs) = @_; 197 my $method = $self->method_for_element ($element); 198 199 # If we have a command handler, we need to accumulate the contents of the 200 # tag before calling it. 201 if ($self->can ("cmd_$method")) { 202 push (@{ $$self{PENDING} }, [ $attrs, '' ]); 203 } elsif ($self->can ("start_$method")) { 204 my $method = 'start_' . $method; 205 $self->$method ($attrs, ''); 206 } 207} 208 209# Handle the end of an element. If we had a cmd_ method for this element, 210# this is where we pass along the text that we've accumulated. Otherwise, if 211# we have an end_ method for the element, call that. 212sub _handle_element_end { 213 my ($self, $element) = @_; 214 my $method = $self->method_for_element ($element); 215 216 # If we have a command handler, pull off the pending text and pass it to 217 # the handler along with the saved attribute hash. 218 if ($self->can ("cmd_$method")) { 219 my $tag = pop @{ $$self{PENDING} }; 220 my $method = 'cmd_' . $method; 221 my $text = $self->$method (@$tag); 222 if (defined $text) { 223 if (@{ $$self{PENDING} } > 1) { 224 $$self{PENDING}[-1][1] .= $text; 225 } else { 226 $self->output ($text); 227 } 228 } 229 } elsif ($self->can ("end_$method")) { 230 my $method = 'end_' . $method; 231 $self->$method (); 232 } 233} 234 235############################################################################## 236# Output formatting 237############################################################################## 238 239# Wrap a line, indenting by the current left margin. We can't use Text::Wrap 240# because it plays games with tabs. We can't use formline, even though we'd 241# really like to, because it screws up non-printing characters. So we have to 242# do the wrapping ourselves. 243sub wrap { 244 my $self = shift; 245 local $_ = shift; 246 my $output = ''; 247 my $spaces = ' ' x $$self{MARGIN}; 248 my $width = $$self{opt_width} - $$self{MARGIN}; 249 while (length > $width) { 250 if (s/^([^\n]{0,$width})\s+// || s/^([^\n]{$width})//) { 251 $output .= $spaces . $1 . "\n"; 252 } else { 253 last; 254 } 255 } 256 $output .= $spaces . $_; 257 $output =~ s/\s+$/\n\n/; 258 return $output; 259} 260 261# Reformat a paragraph of text for the current margin. Takes the text to 262# reformat and returns the formatted text. 263sub reformat { 264 my $self = shift; 265 local $_ = shift; 266 267 # If we're trying to preserve two spaces after sentences, do some munging 268 # to support that. Otherwise, smash all repeated whitespace. 269 if ($$self{opt_sentence}) { 270 s/ +$//mg; 271 s/\.\n/. \n/g; 272 s/\n/ /g; 273 s/ +/ /g; 274 } else { 275 s/\s+/ /g; 276 } 277 return $self->wrap ($_); 278} 279 280# Output text to the output device. Replace non-breaking spaces with spaces 281# and soft hyphens with nothing, and then try to fix the output encoding if 282# necessary to match the input encoding unless UTF-8 output is forced. This 283# preserves the traditional pass-through behavior of Pod::Text. 284sub output { 285 my ($self, @text) = @_; 286 my $text = join ('', @text); 287 if ($NBSP) { 288 $text =~ s/$NBSP/ /g; 289 } 290 if ($SHY) { 291 $text =~ s/$SHY//g; 292 } 293 unless ($$self{opt_utf8}) { 294 my $encoding = $$self{encoding} || ''; 295 if ($encoding && $encoding ne $$self{ENCODING}) { 296 $$self{ENCODING} = $encoding; 297 eval { binmode ($$self{output_fh}, ":encoding($encoding)") }; 298 } 299 } 300 if ($$self{ENCODE}) { 301 print { $$self{output_fh} } encode ('UTF-8', $text); 302 } else { 303 print { $$self{output_fh} } $text; 304 } 305} 306 307# Output a block of code (something that isn't part of the POD text). Called 308# by preprocess_paragraph only if we were given the code option. Exists here 309# only so that it can be overridden by subclasses. 310sub output_code { $_[0]->output ($_[1]) } 311 312############################################################################## 313# Document initialization 314############################################################################## 315 316# Set up various things that have to be initialized on a per-document basis. 317sub start_document { 318 my ($self, $attrs) = @_; 319 if ($$attrs{contentless} && !$$self{ALWAYS_EMIT_SOMETHING}) { 320 $$self{CONTENTLESS} = 1; 321 } else { 322 delete $$self{CONTENTLESS}; 323 } 324 my $margin = $$self{opt_indent} + $$self{opt_margin}; 325 326 # Initialize a few per-document variables. 327 $$self{INDENTS} = []; # Stack of indentations. 328 $$self{MARGIN} = $margin; # Default left margin. 329 $$self{PENDING} = [[]]; # Pending output. 330 331 # We have to redo encoding handling for each document. 332 $$self{ENCODING} = ''; 333 334 # When UTF-8 output is set, check whether our output file handle already 335 # has a PerlIO encoding layer set. If it does not, we'll need to encode 336 # our output before printing it (handled in the output() sub). Wrap the 337 # check in an eval to handle versions of Perl without PerlIO. 338 $$self{ENCODE} = 0; 339 if ($$self{opt_utf8}) { 340 $$self{ENCODE} = 1; 341 eval { 342 my @options = (output => 1, details => 1); 343 my $flag = (PerlIO::get_layers ($$self{output_fh}, @options))[-1]; 344 if ($flag & PerlIO::F_UTF8 ()) { 345 $$self{ENCODE} = 0; 346 $$self{ENCODING} = 'UTF-8'; 347 } 348 }; 349 } 350 351 return ''; 352} 353 354# Handle the end of the document. The only thing we do is handle dying on POD 355# errors, since Pod::Parser currently doesn't. 356sub end_document { 357 my ($self) = @_; 358 if ($$self{complain_die} && $self->errors_seen) { 359 croak ("POD document had syntax errors"); 360 } 361} 362 363############################################################################## 364# Text blocks 365############################################################################## 366 367# Intended for subclasses to override, this method returns text with any 368# non-printing formatting codes stripped out so that length() correctly 369# returns the length of the text. For basic Pod::Text, it does nothing. 370sub strip_format { 371 my ($self, $string) = @_; 372 return $string; 373} 374 375# This method is called whenever an =item command is complete (in other words, 376# we've seen its associated paragraph or know for certain that it doesn't have 377# one). It gets the paragraph associated with the item as an argument. If 378# that argument is empty, just output the item tag; if it contains a newline, 379# output the item tag followed by the newline. Otherwise, see if there's 380# enough room for us to output the item tag in the margin of the text or if we 381# have to put it on a separate line. 382sub item { 383 my ($self, $text) = @_; 384 my $tag = $$self{ITEM}; 385 unless (defined $tag) { 386 carp "Item called without tag"; 387 return; 388 } 389 undef $$self{ITEM}; 390 391 # Calculate the indentation and margin. $fits is set to true if the tag 392 # will fit into the margin of the paragraph given our indentation level. 393 my $indent = $$self{INDENTS}[-1]; 394 $indent = $$self{opt_indent} unless defined $indent; 395 my $margin = ' ' x $$self{opt_margin}; 396 my $tag_length = length ($self->strip_format ($tag)); 397 my $fits = ($$self{MARGIN} - $indent >= $tag_length + 1); 398 399 # If the tag doesn't fit, or if we have no associated text, print out the 400 # tag separately. Otherwise, put the tag in the margin of the paragraph. 401 if (!$text || $text =~ /^\s+$/ || !$fits) { 402 my $realindent = $$self{MARGIN}; 403 $$self{MARGIN} = $indent; 404 my $output = $self->reformat ($tag); 405 $output =~ s/^$margin /$margin:/ if ($$self{opt_alt} && $indent > 0); 406 $output =~ s/\n*$/\n/; 407 408 # If the text is just whitespace, we have an empty item paragraph; 409 # this can result from =over/=item/=back without any intermixed 410 # paragraphs. Insert some whitespace to keep the =item from merging 411 # into the next paragraph. 412 $output .= "\n" if $text && $text =~ /^\s*$/; 413 414 $self->output ($output); 415 $$self{MARGIN} = $realindent; 416 $self->output ($self->reformat ($text)) if ($text && $text =~ /\S/); 417 } else { 418 my $space = ' ' x $indent; 419 $space =~ s/^$margin /$margin:/ if $$self{opt_alt}; 420 $text = $self->reformat ($text); 421 $text =~ s/^$margin /$margin:/ if ($$self{opt_alt} && $indent > 0); 422 my $tagspace = ' ' x $tag_length; 423 $text =~ s/^($space)$tagspace/$1$tag/ or warn "Bizarre space in item"; 424 $self->output ($text); 425 } 426} 427 428# Handle a basic block of text. The only tricky thing here is that if there 429# is a pending item tag, we need to format this as an item paragraph. 430sub cmd_para { 431 my ($self, $attrs, $text) = @_; 432 $text =~ s/\s+$/\n/; 433 if (defined $$self{ITEM}) { 434 $self->item ($text . "\n"); 435 } else { 436 $self->output ($self->reformat ($text . "\n")); 437 } 438 return ''; 439} 440 441# Handle a verbatim paragraph. Just print it out, but indent it according to 442# our margin. 443sub cmd_verbatim { 444 my ($self, $attrs, $text) = @_; 445 $self->item if defined $$self{ITEM}; 446 return if $text =~ /^\s*$/; 447 $text =~ s/^(\n*)([ \t]*\S+)/$1 . (' ' x $$self{MARGIN}) . $2/gme; 448 $text =~ s/\s*$/\n\n/; 449 $self->output ($text); 450 return ''; 451} 452 453# Handle literal text (produced by =for and similar constructs). Just output 454# it with the minimum of changes. 455sub cmd_data { 456 my ($self, $attrs, $text) = @_; 457 $text =~ s/^\n+//; 458 $text =~ s/\n{0,2}$/\n/; 459 $self->output ($text); 460 return ''; 461} 462 463############################################################################## 464# Headings 465############################################################################## 466 467# The common code for handling all headers. Takes the header text, the 468# indentation, and the surrounding marker for the alt formatting method. 469sub heading { 470 my ($self, $text, $indent, $marker) = @_; 471 $self->item ("\n\n") if defined $$self{ITEM}; 472 $text =~ s/\s+$//; 473 if ($$self{opt_alt}) { 474 my $closemark = reverse (split (//, $marker)); 475 my $margin = ' ' x $$self{opt_margin}; 476 $self->output ("\n" . "$margin$marker $text $closemark" . "\n\n"); 477 } else { 478 $text .= "\n" if $$self{opt_loose}; 479 my $margin = ' ' x ($$self{opt_margin} + $indent); 480 $self->output ($margin . $text . "\n"); 481 } 482 return ''; 483} 484 485# First level heading. 486sub cmd_head1 { 487 my ($self, $attrs, $text) = @_; 488 $self->heading ($text, 0, '===='); 489} 490 491# Second level heading. 492sub cmd_head2 { 493 my ($self, $attrs, $text) = @_; 494 $self->heading ($text, $$self{opt_indent} / 2, '== '); 495} 496 497# Third level heading. 498sub cmd_head3 { 499 my ($self, $attrs, $text) = @_; 500 $self->heading ($text, $$self{opt_indent} * 2 / 3 + 0.5, '= '); 501} 502 503# Fourth level heading. 504sub cmd_head4 { 505 my ($self, $attrs, $text) = @_; 506 $self->heading ($text, $$self{opt_indent} * 3 / 4 + 0.5, '- '); 507} 508 509############################################################################## 510# List handling 511############################################################################## 512 513# Handle the beginning of an =over block. Takes the type of the block as the 514# first argument, and then the attr hash. This is called by the handlers for 515# the four different types of lists (bullet, number, text, and block). 516sub over_common_start { 517 my ($self, $attrs) = @_; 518 $self->item ("\n\n") if defined $$self{ITEM}; 519 520 # Find the indentation level. 521 my $indent = $$attrs{indent}; 522 unless (defined ($indent) && $indent =~ /^\s*[-+]?\d{1,4}\s*$/) { 523 $indent = $$self{opt_indent}; 524 } 525 526 # Add this to our stack of indents and increase our current margin. 527 push (@{ $$self{INDENTS} }, $$self{MARGIN}); 528 $$self{MARGIN} += ($indent + 0); 529 return ''; 530} 531 532# End an =over block. Takes no options other than the class pointer. Output 533# any pending items and then pop one level of indentation. 534sub over_common_end { 535 my ($self) = @_; 536 $self->item ("\n\n") if defined $$self{ITEM}; 537 $$self{MARGIN} = pop @{ $$self{INDENTS} }; 538 return ''; 539} 540 541# Dispatch the start and end calls as appropriate. 542sub start_over_bullet { $_[0]->over_common_start ($_[1]) } 543sub start_over_number { $_[0]->over_common_start ($_[1]) } 544sub start_over_text { $_[0]->over_common_start ($_[1]) } 545sub start_over_block { $_[0]->over_common_start ($_[1]) } 546sub end_over_bullet { $_[0]->over_common_end } 547sub end_over_number { $_[0]->over_common_end } 548sub end_over_text { $_[0]->over_common_end } 549sub end_over_block { $_[0]->over_common_end } 550 551# The common handler for all item commands. Takes the type of the item, the 552# attributes, and then the text of the item. 553sub item_common { 554 my ($self, $type, $attrs, $text) = @_; 555 $self->item if defined $$self{ITEM}; 556 557 # Clean up the text. We want to end up with two variables, one ($text) 558 # which contains any body text after taking out the item portion, and 559 # another ($item) which contains the actual item text. Note the use of 560 # the internal Pod::Simple attribute here; that's a potential land mine. 561 $text =~ s/\s+$//; 562 my ($item, $index); 563 if ($type eq 'bullet') { 564 $item = '*'; 565 } elsif ($type eq 'number') { 566 $item = $$attrs{'~orig_content'}; 567 } else { 568 $item = $text; 569 $item =~ s/\s*\n\s*/ /g; 570 $text = ''; 571 } 572 $$self{ITEM} = $item; 573 574 # If body text for this item was included, go ahead and output that now. 575 if ($text) { 576 $text =~ s/\s*$/\n/; 577 $self->item ($text); 578 } 579 return ''; 580} 581 582# Dispatch the item commands to the appropriate place. 583sub cmd_item_bullet { my $self = shift; $self->item_common ('bullet', @_) } 584sub cmd_item_number { my $self = shift; $self->item_common ('number', @_) } 585sub cmd_item_text { my $self = shift; $self->item_common ('text', @_) } 586sub cmd_item_block { my $self = shift; $self->item_common ('block', @_) } 587 588############################################################################## 589# Formatting codes 590############################################################################## 591 592# The simple ones. 593sub cmd_b { return $_[0]{alt} ? "``$_[2]''" : $_[2] } 594sub cmd_f { return $_[0]{alt} ? "\"$_[2]\"" : $_[2] } 595sub cmd_i { return '*' . $_[2] . '*' } 596sub cmd_x { return '' } 597 598# Apply a whole bunch of messy heuristics to not quote things that don't 599# benefit from being quoted. These originally come from Barrie Slaymaker and 600# largely duplicate code in Pod::Man. 601sub cmd_c { 602 my ($self, $attrs, $text) = @_; 603 604 # A regex that matches the portion of a variable reference that's the 605 # array or hash index, separated out just because we want to use it in 606 # several places in the following regex. 607 my $index = '(?: \[.*\] | \{.*\} )?'; 608 609 # Check for things that we don't want to quote, and if we find any of 610 # them, return the string with just a font change and no quoting. 611 $text =~ m{ 612 ^\s* 613 (?: 614 ( [\'\`\"] ) .* \1 # already quoted 615 | \` .* \' # `quoted' 616 | \$+ [\#^]? \S $index # special ($^Foo, $") 617 | [\$\@%&*]+ \#? [:\'\w]+ $index # plain var or func 618 | [\$\@%&*]* [:\'\w]+ (?: -> )? \(\s*[^\s,]\s*\) # 0/1-arg func call 619 | [+-]? ( \d[\d.]* | \.\d+ ) (?: [eE][+-]?\d+ )? # a number 620 | 0x [a-fA-F\d]+ # a hex constant 621 ) 622 \s*\z 623 }xo && return $text; 624 625 # If we didn't return, go ahead and quote the text. 626 return $$self{opt_alt} 627 ? "``$text''" 628 : "$$self{LQUOTE}$text$$self{RQUOTE}"; 629} 630 631# Links reduce to the text that we're given, wrapped in angle brackets if it's 632# a URL. 633sub cmd_l { 634 my ($self, $attrs, $text) = @_; 635 if ($$attrs{type} eq 'url') { 636 if (not defined($$attrs{to}) or $$attrs{to} eq $text) { 637 return "<$text>"; 638 } elsif ($$self{opt_nourls}) { 639 return $text; 640 } else { 641 return "$text <$$attrs{to}>"; 642 } 643 } else { 644 return $text; 645 } 646} 647 648############################################################################## 649# Backwards compatibility 650############################################################################## 651 652# The old Pod::Text module did everything in a pod2text() function. This 653# tries to provide the same interface for legacy applications. 654sub pod2text { 655 my @args; 656 657 # This is really ugly; I hate doing option parsing in the middle of a 658 # module. But the old Pod::Text module supported passing flags to its 659 # entry function, so handle -a and -<number>. 660 while ($_[0] =~ /^-/) { 661 my $flag = shift; 662 if ($flag eq '-a') { push (@args, alt => 1) } 663 elsif ($flag =~ /^-(\d+)$/) { push (@args, width => $1) } 664 else { 665 unshift (@_, $flag); 666 last; 667 } 668 } 669 670 # Now that we know what arguments we're using, create the parser. 671 my $parser = Pod::Text->new (@args); 672 673 # If two arguments were given, the second argument is going to be a file 674 # handle. That means we want to call parse_from_filehandle(), which means 675 # we need to turn the first argument into a file handle. Magic open will 676 # handle the <&STDIN case automagically. 677 if (defined $_[1]) { 678 my @fhs = @_; 679 local *IN; 680 unless (open (IN, $fhs[0])) { 681 croak ("Can't open $fhs[0] for reading: $!\n"); 682 return; 683 } 684 $fhs[0] = \*IN; 685 $parser->output_fh ($fhs[1]); 686 my $retval = $parser->parse_file ($fhs[0]); 687 my $fh = $parser->output_fh (); 688 close $fh; 689 return $retval; 690 } else { 691 $parser->output_fh (\*STDOUT); 692 return $parser->parse_file (@_); 693 } 694} 695 696# Reset the underlying Pod::Simple object between calls to parse_from_file so 697# that the same object can be reused to convert multiple pages. 698sub parse_from_file { 699 my $self = shift; 700 $self->reinit; 701 702 # Fake the old cutting option to Pod::Parser. This fiddles with internal 703 # Pod::Simple state and is quite ugly; we need a better approach. 704 if (ref ($_[0]) eq 'HASH') { 705 my $opts = shift @_; 706 if (defined ($$opts{-cutting}) && !$$opts{-cutting}) { 707 $$self{in_pod} = 1; 708 $$self{last_was_blank} = 1; 709 } 710 } 711 712 # Do the work. 713 my $retval = $self->Pod::Simple::parse_from_file (@_); 714 715 # Flush output, since Pod::Simple doesn't do this. Ideally we should also 716 # close the file descriptor if we had to open one, but we can't easily 717 # figure this out. 718 my $fh = $self->output_fh (); 719 my $oldfh = select $fh; 720 my $oldflush = $|; 721 $| = 1; 722 print $fh ''; 723 $| = $oldflush; 724 select $oldfh; 725 return $retval; 726} 727 728# Pod::Simple failed to provide this backward compatibility function, so 729# implement it ourselves. File handles are one of the inputs that 730# parse_from_file supports. 731sub parse_from_filehandle { 732 my $self = shift; 733 $self->parse_from_file (@_); 734} 735 736# Pod::Simple's parse_file doesn't set output_fh. Wrap the call and do so 737# ourself unless it was already set by the caller, since our documentation has 738# always said that this should work. 739sub parse_file { 740 my ($self, $in) = @_; 741 unless (defined $$self{output_fh}) { 742 $self->output_fh (\*STDOUT); 743 } 744 return $self->SUPER::parse_file ($in); 745} 746 747# Do the same for parse_lines, just to be polite. Pod::Simple's man page 748# implies that the caller is responsible for setting this, but I don't see any 749# reason not to set a default. 750sub parse_lines { 751 my ($self, @lines) = @_; 752 unless (defined $$self{output_fh}) { 753 $self->output_fh (\*STDOUT); 754 } 755 return $self->SUPER::parse_lines (@lines); 756} 757 758# Likewise for parse_string_document. 759sub parse_string_document { 760 my ($self, $doc) = @_; 761 unless (defined $$self{output_fh}) { 762 $self->output_fh (\*STDOUT); 763 } 764 return $self->SUPER::parse_string_document ($doc); 765} 766 767############################################################################## 768# Module return value and documentation 769############################################################################## 770 7711; 772__END__ 773 774=for stopwords 775alt stderr Allbery Sean Burke's Christiansen UTF-8 pre-Unicode utf8 nourls 776parsers 777 778=head1 NAME 779 780Pod::Text - Convert POD data to formatted text 781 782=head1 SYNOPSIS 783 784 use Pod::Text; 785 my $parser = Pod::Text->new (sentence => 1, width => 78); 786 787 # Read POD from STDIN and write to STDOUT. 788 $parser->parse_from_filehandle; 789 790 # Read POD from file.pod and write to file.txt. 791 $parser->parse_from_file ('file.pod', 'file.txt'); 792 793=head1 DESCRIPTION 794 795Pod::Text is a module that can convert documentation in the POD format 796(the preferred language for documenting Perl) into formatted text. It 797uses no special formatting controls or codes whatsoever, and its output is 798therefore suitable for nearly any device. 799 800As a derived class from Pod::Simple, Pod::Text supports the same methods and 801interfaces. See L<Pod::Simple> for all the details; briefly, one creates a 802new parser with C<< Pod::Text->new() >> and then normally calls parse_file(). 803 804new() can take options, in the form of key/value pairs, that control the 805behavior of the parser. The currently recognized options are: 806 807=over 4 808 809=item alt 810 811If set to a true value, selects an alternate output format that, among other 812things, uses a different heading style and marks C<=item> entries with a 813colon in the left margin. Defaults to false. 814 815=item code 816 817If set to a true value, the non-POD parts of the input file will be included 818in the output. Useful for viewing code documented with POD blocks with the 819POD rendered and the code left intact. 820 821=item errors 822 823How to report errors. C<die> says to throw an exception on any POD 824formatting error. C<stderr> says to report errors on standard error, but 825not to throw an exception. C<pod> says to include a POD ERRORS section 826in the resulting documentation summarizing the errors. C<none> ignores 827POD errors entirely, as much as possible. 828 829The default is C<pod>. 830 831=item indent 832 833The number of spaces to indent regular text, and the default indentation for 834C<=over> blocks. Defaults to 4. 835 836=item loose 837 838If set to a true value, a blank line is printed after a C<=head1> heading. 839If set to false (the default), no blank line is printed after C<=head1>, 840although one is still printed after C<=head2>. This is the default because 841it's the expected formatting for manual pages; if you're formatting 842arbitrary text documents, setting this to true may result in more pleasing 843output. 844 845=item margin 846 847The width of the left margin in spaces. Defaults to 0. This is the margin 848for all text, including headings, not the amount by which regular text is 849indented; for the latter, see the I<indent> option. To set the right 850margin, see the I<width> option. 851 852=item nourls 853 854Normally, LZ<><> formatting codes with a URL but anchor text are formatted 855to show both the anchor text and the URL. In other words: 856 857 L<foo|http://example.com/> 858 859is formatted as: 860 861 foo <http://example.com/> 862 863This option, if set to a true value, suppresses the URL when anchor text 864is given, so this example would be formatted as just C<foo>. This can 865produce less cluttered output in cases where the URLs are not particularly 866important. 867 868=item quotes 869 870Sets the quote marks used to surround CE<lt>> text. If the value is a 871single character, it is used as both the left and right quote. Otherwise, 872it is split in half, and the first half of the string is used as the left 873quote and the second is used as the right quote. 874 875This may also be set to the special value C<none>, in which case no quote 876marks are added around CE<lt>> text. 877 878=item sentence 879 880If set to a true value, Pod::Text will assume that each sentence ends in two 881spaces, and will try to preserve that spacing. If set to false, all 882consecutive whitespace in non-verbatim paragraphs is compressed into a 883single space. Defaults to false. 884 885=item stderr 886 887Send error messages about invalid POD to standard error instead of 888appending a POD ERRORS section to the generated output. This is 889equivalent to setting C<errors> to C<stderr> if C<errors> is not already 890set. It is supported for backward compatibility. 891 892=item utf8 893 894By default, Pod::Text uses the same output encoding as the input encoding 895of the POD source (provided that Perl was built with PerlIO; otherwise, it 896doesn't encode its output). If this option is given, the output encoding 897is forced to UTF-8. 898 899Be aware that, when using this option, the input encoding of your POD 900source should be properly declared unless it's US-ASCII. Pod::Simple will 901attempt to guess the encoding and may be successful if it's Latin-1 or 902UTF-8, but it will produce warnings. Use the C<=encoding> command to 903declare the encoding. See L<perlpod(1)> for more information. 904 905=item width 906 907The column at which to wrap text on the right-hand side. Defaults to 76. 908 909=back 910 911The standard Pod::Simple method parse_file() takes one argument naming the 912POD file to read from. By default, the output is sent to C<STDOUT>, but 913this can be changed with the output_fh() method. 914 915The standard Pod::Simple method parse_from_file() takes up to two 916arguments, the first being the input file to read POD from and the second 917being the file to write the formatted output to. 918 919You can also call parse_lines() to parse an array of lines or 920parse_string_document() to parse a document already in memory. As with 921parse_file(), parse_lines() and parse_string_document() default to sending 922their output to C<STDOUT> unless changed with the output_fh() method. 923 924To put the output from any parse method into a string instead of a file 925handle, call the output_string() method instead of output_fh(). 926 927See L<Pod::Simple> for more specific details on the methods available to 928all derived parsers. 929 930=head1 DIAGNOSTICS 931 932=over 4 933 934=item Bizarre space in item 935 936=item Item called without tag 937 938(W) Something has gone wrong in internal C<=item> processing. These 939messages indicate a bug in Pod::Text; you should never see them. 940 941=item Can't open %s for reading: %s 942 943(F) Pod::Text was invoked via the compatibility mode pod2text() interface 944and the input file it was given could not be opened. 945 946=item Invalid errors setting "%s" 947 948(F) The C<errors> parameter to the constructor was set to an unknown value. 949 950=item Invalid quote specification "%s" 951 952(F) The quote specification given (the C<quotes> option to the 953constructor) was invalid. A quote specification must be either one 954character long or an even number (greater than one) characters long. 955 956=item POD document had syntax errors 957 958(F) The POD document being formatted had syntax errors and the C<errors> 959option was set to C<die>. 960 961=back 962 963=head1 BUGS 964 965Encoding handling assumes that PerlIO is available and does not work 966properly if it isn't. The C<utf8> option is therefore not supported 967unless Perl is built with PerlIO support. 968 969=head1 CAVEATS 970 971If Pod::Text is given the C<utf8> option, the encoding of its output file 972handle will be forced to UTF-8 if possible, overriding any existing 973encoding. This will be done even if the file handle is not created by 974Pod::Text and was passed in from outside. This maintains consistency 975regardless of PERL_UNICODE and other settings. 976 977If the C<utf8> option is not given, the encoding of its output file handle 978will be forced to the detected encoding of the input POD, which preserves 979whatever the input text is. This ensures backward compatibility with 980earlier, pre-Unicode versions of this module, without large numbers of 981Perl warnings. 982 983This is not ideal, but it seems to be the best compromise. If it doesn't 984work for you, please let me know the details of how it broke. 985 986=head1 NOTES 987 988This is a replacement for an earlier Pod::Text module written by Tom 989Christiansen. It has a revamped interface, since it now uses Pod::Simple, 990but an interface roughly compatible with the old Pod::Text::pod2text() 991function is still available. Please change to the new calling convention, 992though. 993 994The original Pod::Text contained code to do formatting via termcap 995sequences, although it wasn't turned on by default and it was problematic to 996get it to work at all. This rewrite doesn't even try to do that, but a 997subclass of it does. Look for L<Pod::Text::Termcap>. 998 999=head1 AUTHOR 1000 1001Russ Allbery <rra@cpan.org>, based I<very> heavily on the original 1002Pod::Text by Tom Christiansen <tchrist@mox.perl.com> and its conversion to 1003Pod::Parser by Brad Appleton <bradapp@enteract.com>. Sean Burke's initial 1004conversion of Pod::Man to use Pod::Simple provided much-needed guidance on 1005how to use Pod::Simple. 1006 1007=head1 COPYRIGHT AND LICENSE 1008 1009Copyright 1999-2002, 2004, 2006, 2008-2009, 2012-2016, 2018 Russ Allbery 1010<rra@cpan.org> 1011 1012This program is free software; you may redistribute it and/or modify it 1013under the same terms as Perl itself. 1014 1015=head1 SEE ALSO 1016 1017L<Pod::Simple>, L<Pod::Text::Termcap>, L<perlpod(1)>, L<pod2text(1)> 1018 1019The current version of this module is always available from its web site at 1020L<https://www.eyrie.org/~eagle/software/podlators/>. It is also part of the 1021Perl core distribution as of 5.6.0. 1022 1023=cut 1024 1025# Local Variables: 1026# copyright-at-end-flag: t 1027# End: 1028