File Coverage

blib/lib/Pod/PseudoPod/PerlTricks.pm
Criterion Covered Total %
statement 92 419 21.9
branch 24 352 6.8
condition 2 47 4.2
subroutine 21 53 39.6
pod 5 35 14.2
total 144 906 15.8


line stmt bran cond sub pod time code
1 3     3   1446 use v5.20;
  3         7  
  3         92  
2 3     3   11 use feature qw(signatures);
  3         3  
  3         202  
3 3     3   11 no warnings qw(experimental::signatures);
  3         6  
  3         109  
4              
5              
6             package Pod::PseudoPod::PerlTricks;
7 3     3   9 use strict;
  3         3  
  3         78  
8 3     3   794 use parent 'Pod::PseudoPod';
  3         455  
  3         11  
9              
10 3     3   74222 use warnings;
  3         6  
  3         77  
11 3     3   9 no warnings;
  3         4  
  3         91  
12              
13 3     3   1667 use subs qw();
  3         56  
  3         122  
14 3     3   12 use vars qw($VERSION);
  3         4  
  3         88  
15              
16 3     3   11 use Carp;
  3         4  
  3         166  
17 3     3   31137 use Data::Dumper;
  3         16228  
  3         7318  
18              
19             $VERSION = '0.011';
20              
21 2 50   2 0 3 sub DEBUG () { 0 }
  2         1  
  2         21  
22              
23             =encoding utf8
24              
25             =head1 NAME
26              
27             Pod::PseudoPod::PerlTricks - Turn Pod into the HTML PerlTricks needs
28              
29             =head1 SYNOPSIS
30              
31             use Pod::PseudoPod::PerlTricks;
32              
33             =head1 DESCRIPTION
34              
35             ***THIS IS ALPHA SOFTWARE. MAJOR PARTS WILL CHANGE***
36              
37             I wrote just enough of this module to get my job done, and I skipped
38             every part of the specification I didn't need while still making it
39             flexible enough to handle stuff later.
40              
41              
42             PerlTricks.com Style Guide v0.01
43             ========================== =====
44             By David Farrell
45              
46             Introduction
47             ------------
48             This document is intended to guide PerlTricks authors in producing articles that are consistent with the aims of the website. None of this is set in stone - great writing should always prevail.
49              
50             Goal
51             ----
52             We aspire to reasoned, insightful, professional writing with a lighthearted bent.
53              
54             Topics of interest
55             ------------------
56             - Anything Perl related: news, events, tutorials, community
57             - Non-Perl programming subjects: version control, hosting, sysadmin
58             - Open Source
59              
60             Looking for an idea for an article? Our bread and butter is: "here is something cool you can do with Perl". Start there.
61              
62             Politics / Tone
63             ---------------
64             - We are pro: Perl, Open Source and free software
65             - No rants or "hit pieces"
66             - Reasoned criticism is fine
67              
68             Language
69             --------
70             - American English
71             - 300-1,000 words per article
72             - Simple English (use http://www.hemingwayapp.com/ to help)
73             - Only capitalize the first letter of a word in headings (no title case)
74             - Articles can begin with an italicised introductory paragraph
75             - Technical terms / references when first used should be quoted in speech marks (")
76             - Use the first-person
77             - We are "PerlTricks.com"
78             - You can use "we" to refer to PerlTricks.com, the staff, our point of view etc.
79             - When referring to modules for the first time, provide a link to metacpan
80              
81             Markup
82             ------
83             - HTML
84             -

for sub-headers

85             -

for paragraphs

86             - for links
87             - for inline code
88             -
for Perl code block
89             -
for plain code block
90             -
for blockquote
91             - , can be used for emphasis
92             -
    , are supported
    93             - Inline images ... can be done, let me know if you need them and I'll upload in the backend
    94              
    95             Questions or comments ? Email me: perltricks.com@gmail.com
    96              
    97              
    98              
    99             =cut
    100              
    101             =over 4
    102              
    103             =cut
    104              
    105 0 0   0   0 sub _ponder_begin ( $self, $para, $curr_open, $paras ){
      0 0       0  
      0         0  
      0         0  
      0         0  
      0         0  
      0         0  
    106             # XXX this is such a messed up way to do this, but this is
    107             # not designed to be extended
    108 0 0       0 unless ($para->[2] =~ /^\s*(?:output)/) {
    109 0         0 return $self->SUPER::_ponder_begin($para,$curr_open,$paras);
    110             }
    111              
    112 0         0 my $content = join ' ', splice @$para, 2;
    113 0         0 $content =~ s/^\s+//s;
    114 0         0 $content =~ s/\s+$//s;
    115              
    116 0         0 my ($target, $title) = $content =~ m/^(\S+)\s*(.*)$/;
    117 0         0 $para->[1]{'target'} = $target; # without any ':'
    118              
    119 0 0       0 return 1 unless $self->{'accept_targets'}{$target};
    120              
    121 0         0 $para->[0] = '=for'; # Just what we happen to call these, internally
    122 0   0     0 $para->[1]{'~really'} ||= '=begin';
    123 0         0 $para->[1]{'~resolve'} = 1;
    124              
    125 0         0 push @$curr_open, $para;
    126 0   0     0 $self->{'content_seen'} ||= 1;
    127              
    128 0         0 $self->_handle_element_start( $target, $para->[1] );
    129              
    130 0         0 return 1;
    131             }
    132              
    133 0 0   0 0 0 sub begin_for ( $self, $attributes={} ) {
      0 0       0  
      0 0       0  
      0         0  
      0         0  
    134 0         0 my $target = $attributes->{target};
    135 0         0 my $method = 'start_' . $target;
    136              
    137 0 0       0 if( $self->can( $method ) ) {
    138 0         0 $self->$method();
    139             }
    140             else {
    141 0 0       0 DEBUG > 1 and print "No method $method";
    142             }
    143             }
    144              
    145 0 0   0 0 0 sub end_for ( $self, $attributes={} ) {
      0 0       0  
      0 0       0  
      0         0  
      0         0  
    146 0         0 my $target = $attributes->{target};
    147 0         0 my $method = 'end_' . $target;
    148              
    149 0 0       0 if( $self->can( $method ) ) {
    150 0         0 $self->$method();
    151             }
    152             else {
    153 0 0       0 DEBUG > 1 and print "No method $method";
    154             }
    155             }
    156              
    157 1 50   1 0 2 sub add_to_pad ( $self, $stuff ) {
      1 50       1  
      1         1  
      1         1  
      1         1  
    158 1         2 my $pad = $self->get_pad;
    159 0         0 $self->{$pad} .= $stuff;
    160             }
    161              
    162 0 0   0 0 0 sub clear_pad ( $self ) {
      0 0       0  
      0         0  
      0         0  
    163 0         0 my $pad = $self->get_pad;
    164 0         0 $self->{$pad} = '';
    165             }
    166              
    167 0 0   0 0 0 sub set_title ( $self, $title ) { $self->{title} = $title }
      0 0       0  
      0         0  
      0         0  
      0         0  
      0         0  
    168              
    169 0 0   0 0 0 sub title ( $self ) { $self->{title} }
      0 0       0  
      0         0  
      0         0  
      0         0  
    170              
    171             =item document_header
    172              
    173             The empty string. We don't worry about that here. The blogging
    174             platform adds that.
    175              
    176             =cut
    177              
    178 1 50   1 1 5 sub document_header ( $self ) { '' }
      1 50       2  
      1         1  
      1         1  
      1         2  
    179              
    180             =item document_footer
    181              
    182             The empty string. We don't worry about that here. The blogging
    183             platform adds that.
    184              
    185             =cut
    186              
    187 0 0   0 1 0 sub document_footer ( $self ) { '' }
      0 0       0  
      0         0  
      0         0  
      0         0  
    188              
    189             =back
    190              
    191             =head2 The Pod::Simple mechanics
    192              
    193             Everything else is the same stuff from C.
    194              
    195             =over 4
    196              
    197             =cut
    198              
    199 2 50   2 1 1003 sub new ( $class ) {
      2 50       5  
      2         4  
      2         2  
    200 2         15 my $self = $class->SUPER::new();
    201 2         97 $self->accept_codes( qw( K ) );
    202 2         38 $self->accept_targets( qw(code terminal output figure) );
    203 2         54 $self->accept_directive_as_verbatim( qw(code terminal output) );
    204 2         69 $self;
    205             }
    206              
    207 0 0   0 0 0 sub emit ( $self, $attributes={} ) {
      0 0       0  
      0 0       0  
      0         0  
      0         0  
    208              
    209 0 0       0 if (defined $self->{'output_fh'})
    210             {
    211 0         0 print {$self->{'output_fh'}} $self->get_from_current_pad;
      0         0  
    212             }
    213             else
    214             {
    215 0         0 print $self->get_from_current_pad;
    216             }
    217 0         0 $self->clear_pad;
    218 0         0 return;
    219             }
    220              
    221 1 50   1 0 2 sub get_pad ( $self, $attributes={} ) {
      1 50       4  
      1 50       1  
      1         1  
      1         1  
    222 1         2 $self->not_implemented;
    223             }
    224              
    225 0 0   0 0 0 sub get_from_current_pad ( $self ) {
      0 0       0  
      0         0  
      0         0  
    226 0         0 my $pad = $self->get_pad;
    227 0         0 $self->{$pad};
    228             }
    229              
    230 0 0   0 0 0 sub add_to_current_pad ( $self, $text ) {
      0 0       0  
      0         0  
      0         0  
      0         0  
    231 0         0 my $pad = $self->get_pad;
    232 0         0 $self->{$pad} .= $text;
    233             }
    234              
    235 1 50   1 0 11 sub start_Document ( $self, $attributes={} ) {
      1 50       2  
      1 50       1  
      1         2  
      1         1  
    236 1         2 $self->{in_section} = [];
    237 1         3 $self->add_to_pad( $self->document_header );
    238 0         0 $self->emit;
    239             }
    240              
    241 0 0   0 0 0 sub end_Document ( $self, $attributes={} ) {
      0 0       0  
      0 0       0  
      0         0  
      0         0  
    242 0         0 $self->add_to_pad( $self->document_footer );
    243 0         0 $self->emit;
    244             }
    245              
    246 0 0   0 0 0 sub start_head0 ( $self, $attributes={} ) { $self->_header_start( 0 ); }
      0 0       0  
      0 0       0  
      0         0  
      0         0  
      0         0  
    247 0 0   0 0 0 sub end_head0 ( $self, $attributes={} ) { $self->_header_end( 0 ); }
      0 0       0  
      0 0       0  
      0         0  
      0         0  
      0         0  
    248              
    249 0 0   0 0 0 sub end_head1 ( $self, $attributes={} ) { $self->_header_end( 1 ); }
      0 0       0  
      0 0       0  
      0         0  
      0         0  
      0         0  
    250 0 0   0 0 0 sub start_head1 ( $self, $attributes={} ) { $self->_header_start( 1 ); }
      0 0       0  
      0 0       0  
      0         0  
      0         0  
      0         0  
    251              
    252 0 0   0 0 0 sub end_head2 ( $self, $attributes={} ) { $self->_header_end( 2 ); }
      0 0       0  
      0 0       0  
      0         0  
      0         0  
      0         0  
    253 0 0   0 0 0 sub start_head2 ( $self, $attributes={} ) { $self->_header_start( 2 ); }
      0 0       0  
      0 0       0  
      0         0  
      0         0  
      0         0  
    254              
    255 0 0   0 0 0 sub start_head3 ( $self, $attributes={} ) { $self->_header_start( 3 ); }
      0 0       0  
      0 0       0  
      0         0  
      0         0  
      0         0  
    256 0 0   0 0 0 sub end_head3 ( $self, $attributes={} ) { $self->_header_end( 3 ); }
      0 0       0  
      0 0       0  
      0         0  
      0         0  
      0         0  
    257              
    258             =item * start_output
    259              
    260             =item * end_output
    261              
    262             These methods simple set flags and defer everything else to the
    263             verbatim handler.
    264              
    265             =cut
    266              
    267 0 0   0 1 0 sub start_output ( $self, $attributes={} ) {
      0 0       0  
      0 0       0  
      0         0  
      0         0  
    268 0         0 $self->{'in_output'} = 1;
    269             }
    270              
    271 0 0   0 1 0 sub end_output ( $self, $attributes={} ) {
      0 0       0  
      0 0       0  
      0         0  
      0         0  
    272 0         0 $self->{'in_output'} = 0;
    273             }
    274              
    275 0 0   0   0 sub _get_initial_item_type ( $self, $attributes={} ) {
      0 0       0  
      0 0       0  
      0         0  
      0         0  
    276 0         0 my $type = $self->SUPER::_get_initial_item_type;
    277              
    278 0         0 $type;
    279             }
    280              
    281              
    282 1 50   1 0 2 sub not_implemented ( $self, $attributes={} ) { croak "Not implemented! " . (caller(1))[3] }
      1 50       2  
      1 50       2  
      1         1  
      1         1  
      1         210  
    283              
    284 0 0   0 0 0 sub in_item_list ( $self, $attributes={} ) { scalar @{ $self->{list_levels} } }
      0 0       0  
      0 0       0  
      0         0  
      0         0  
      0         0  
      0         0  
    285 0 0   0 0 0 sub add_list_level_item ( $self, $attributes={} ) {
      0 0       0  
      0 0       0  
      0         0  
      0         0  
    286 0         0 ${ $self->{list_levels} }[-1]{item_count}++;
      0         0  
    287             }
    288 0 0   0 0 0 sub is_first_list_level_item ( $self, $attributes={} ) {
      0 0       0  
      0 0       0  
      0         0  
      0         0  
    289 0         0 ${ $self->{list_levels} }[-1]{item_count} == 0;
      0         0  
    290             }
    291              
    292 0 0   0 0 0 sub start_list_level ( $self, $attributes={} ) {
      0 0       0  
      0 0       0  
      0         0  
      0         0  
    293 0         0 push @{ $self->{list_levels} }, { item_count => 0 };
      0         0  
    294             }
    295              
    296 0 0   0 0 0 sub end_list_level ( $self, $attributes={} ) {
      0 0       0  
      0 0       0  
      0         0  
      0         0  
    297 0         0 pop @{ $self->{list_levels} };
      0         0  
    298             }
    299              
    300 0 0   0 0 0 sub dont_escape ( $self ) {
      0 0       0  
      0         0  
      0         0  
    301 0 0       0 $self->{in_verbatim} || $self->{in_C}
    302             }
    303              
    304 0 0   0 0 0 sub escape_text ( $self, $text_ref ) {
      0 0       0  
      0         0  
      0         0  
      0         0  
    305 0         0 $$text_ref =~ s/&/&/g;
    306 0         0 $$text_ref =~ s/
    307              
    308 0         0 return 1;
    309             }
    310              
    311              
    312             BEGIN {
    313 3     3   763 require Pod::Simple::BlackBox;
    314              
    315             package Pod::Simple::BlackBox;
    316              
    317 0 0   0     sub _ponder_Verbatim ( $self, $para ) {
      0 0          
      0            
      0            
      0            
    318 0           DEBUG and print STDERR " giving verbatim treatment...\n";
    319              
    320 0           $para->[1]{'xml:space'} = 'preserve';
    321 0           foreach my $line ( @$para[ 2 .. $#$para ] ) {
    322 0           $line =~ s/\A(\t| )//gm;
    323 0           $line =~ s/\A(\t+)/" " x ( 4 * length($1) )/e;
      0            
    324 0 0         warn
    325             sprintf(
    326             "%s: tab in code listing! [%s]",
    327             $self->chapter,
    328             $line
    329             ) if $line =~ /\t/;
    330             }
    331              
    332             # Now the VerbatimFormatted hoodoo...
    333 0 0 0       if( $self->{'accept_codes'} and
        0          
    334             $self->{'accept_codes'}{'VerbatimFormatted'}
    335             ) {
    336 0   0       while(@$para > 3 and $para->[-1] !~ m/\S/) { pop @$para }
      0            
    337             # Kill any number of terminal newlines
    338 0           $self->_verbatim_format($para);
    339             } elsif ($self->{'codes_in_verbatim'}) {
    340 0           push @$para,
    341 0           @{$self->_make_treelet(
    342             join("\n", splice(@$para, 2)),
    343             $para->[1]{'start_line'}, $para->[1]{'xml:space'}
    344             )};
    345 0           $para->[-1] =~ s/\n+$//s; # Kill any number of terminal newlines
    346             } else {
    347 0 0         push @$para, join "\n", splice(@$para, 2) if @$para > 3;
    348 0           $para->[-1] =~ s/\n+$//s; # Kill any number of terminal newlines
    349             }
    350 0           return;
    351             }
    352              
    353             }
    354              
    355 3     3   3431 BEGIN {
    356              
    357             # override _treat_Es so I can localize e2char
    358             sub _treat_Es {
    359 0     0   0 my $self = shift;
    360              
    361 0         0 require Pod::Escapes;
    362 0         0 local *Pod::Escapes::e2char = *e2char_tagged_text;
    363              
    364 0         0 $self->SUPER::_treat_Es( @_ );
    365             }
    366              
    367             sub e2char_tagged_text {
    368             package Pod::Escapes;
    369              
    370 0     0 0 0 my $in = shift;
    371              
    372 0 0 0     0 return unless defined $in and length $in;
    373              
    374 0 0       0 if( $in =~ m/^(0[0-7]*)$/ ) { $in = oct $in; }
      0 0       0  
    375 0         0 elsif( $in =~ m/^0?x([0-9a-fA-F]+)$/ ) { $in = hex $1; }
    376              
    377 0 0       0 if( $NOT_ASCII ) {
    378 0 0       0 unless( $in =~ m/^\d+$/ )
    379             {
    380 0         0 $in = $Name2character{$in};
    381 0 0       0 return unless defined $in;
    382 0         0 $in = ord $in;
    383             }
    384              
    385 0   0     0 return $Code2USASCII{$in}
    386             || $Latin1Code_to_fallback{$in}
    387             || $FAR_CHAR;
    388             }
    389              
    390 0 0 0     0 if( defined $Name2character_number{$in} and $Name2character_number{$in} < 127 ) {
        0          
    391 0         0 return "&$in;";
    392             }
    393             elsif( defined $Name2character_number{$in} ) {
    394             # this needs to be fixed width because I want to look for
    395             # it in a negative lookbehind
    396 0         0 return sprintf '&#x%04x;', $Name2character_number{$in};
    397             }
    398             else
    399             {
    400 0         0 return '???';
    401             }
    402              
    403             }
    404             }
    405              
    406             =back
    407              
    408             =head1 TO DO
    409              
    410              
    411             =head1 SEE ALSO
    412              
    413             L, L
    414              
    415             =head1 SOURCE AVAILABILITY
    416              
    417             This source is in Github:
    418              
    419             http://github.com/briandfoy/pod-pseudopod-perltricks
    420              
    421             If, for some reason, I disappear from the world, one of the other
    422             members of the project can shepherd this module appropriately.
    423              
    424             =head1 AUTHOR
    425              
    426             brian d foy, C<< >>
    427              
    428             =head1 COPYRIGHT AND LICENSE
    429              
    430             Copyright © 2014-2015, brian d foy . All rights reserved.
    431              
    432             You may redistribute this under the same terms as Perl itself.
    433              
    434             =cut
    435              
    436 2 50   2   267 sub _ponder_paragraph_buffer ( $self ) {
      2 50       3  
      2         2  
      2         1  
    437              
    438             # Para-token types as found in the buffer.
    439             # ~Verbatim, ~Para, ~end, =head1..4, =for, =begin, =end,
    440             # =over, =back, =item
    441             # and the null =pod (to be complained about if over one line)
    442             #
    443             # "~data" paragraphs are something we generate at this level, depending on
    444             # a currently open =over region
    445              
    446             # Events fired: Begin and end for:
    447             # directivename (like head1 .. head4), item, extend,
    448             # for (from =begin...=end, =for),
    449             # over-bullet, over-number, over-text, over-block,
    450             # item-bullet, item-number, item-text,
    451             # Document,
    452             # Data, Para, Verbatim
    453             # B, C, longdirname (TODO -- wha?), etc. for all directives
    454             #
    455              
    456 2         1 my $paras;
    457 2 100       2 return unless @{$paras = $self->{'paras'}};
      2         5  
    458 1   50     5 my $curr_open = ($self->{'curr_open'} ||= []);
    459              
    460 1 50       2 DEBUG > 10 and print "# Paragraph buffer: <<", Pod::Simple::BlackBox::pretty($paras), ">>\n";
    461              
    462             # We have something in our buffer. So apparently the document has started.
    463 1 50       2 unless($self->{'doc_has_started'}) {
    464 1         2 $self->{'doc_has_started'} = 1;
    465              
    466 1         1 my $starting_contentless;
    467 1   33     7 $starting_contentless =
    468             (
    469             !@$curr_open
    470             and @$paras and ! grep $_->[0] ne '~end', @$paras
    471             # i.e., if the paras is all ~ends
    472             )
    473             ;
    474 1 0       2 DEBUG and print "# Starting ",
        50          
    475             $starting_contentless ? 'contentless' : 'contentful',
    476             " document\n"
    477             ;
    478              
    479 1 50       7 $self->_handle_element_start('Document',
    480             {
    481             'start_line' => $paras->[0][1]{'start_line'},
    482             $starting_contentless ? ( 'contentless' => 1 ) : (),
    483             },
    484             );
    485             }
    486              
    487 0           my($para, $para_type);
    488 0           while(@$paras) {
    489 0 0 0       last if @$paras == 1 and
          0        
    490             ( $paras->[0][0] eq '=over' or $paras->[0][0] eq '~Verbatim'
    491             or $paras->[0][0] eq '=item' )
    492             ;
    493             # Those're the three kinds of paragraphs that require lookahead.
    494             # Actually, an "=item Foo" inside an region
    495             # and any =item inside an region (rare)
    496             # don't require any lookahead, but all others (bullets
    497             # and numbers) do.
    498              
    499             # TODO: winge about many kinds of directives in non-resolving =for regions?
    500             # TODO: many? like what? =head1 etc?
    501              
    502 0           $para = shift @$paras;
    503 0           $para_type = $para->[0];
    504              
    505 0 0         DEBUG > 1 and print "Pondering a $para_type paragraph, given the stack: (",
    506             $self->_dump_curr_open(), ")\n";
    507              
    508 0 0         if($para_type eq '=for') {
        0          
        0          
        0          
    509 0 0         next if $self->_ponder_for($para,$curr_open,$paras);
    510             } elsif($para_type eq '=begin') {
    511 0 0         next if $self->_ponder_begin($para,$curr_open,$paras);
    512             } elsif($para_type eq '=end') {
    513 0 0         next if $self->_ponder_end($para,$curr_open,$paras);
    514             } elsif($para_type eq '~end') { # The virtual end-document signal
    515 0 0         next if $self->_ponder_doc_end($para,$curr_open,$paras);
    516             }
    517              
    518              
    519             # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
    520             #~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
    521 0 0         if(grep $_->[1]{'~ignore'}, @$curr_open) {
    522 0 0         DEBUG > 1 and
    523             print "Skipping $para_type paragraph because in ignore mode.\n";
    524 0           next;
    525             }
    526             #~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
    527             # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
    528              
    529 0 0         if($para_type eq '=pod') {
        0          
        0          
        0          
        0          
        0          
    530 0           $self->_ponder_pod($para,$curr_open,$paras);
    531             } elsif($para_type eq '=over') {
    532 0 0         next if $self->_ponder_over($para,$curr_open,$paras);
    533             } elsif($para_type eq '=back') {
    534 0 0         next if $self->_ponder_back($para,$curr_open,$paras);
    535             } elsif($para_type eq '=row') {
    536 0 0         next if $self->_ponder_row_start($para,$curr_open,$paras);
    537              
    538             } elsif( $para_type eq '=headrow'){
    539 0           $self->start_headrow;
    540             } elsif( $para_type eq '=bodyrows') {
    541 0           $self->start_bodyrows;
    542             }
    543              
    544             else {
    545             # All non-magical codes!!!
    546              
    547             # Here we start using $para_type for our own twisted purposes, to
    548             # mean how it should get treated, not as what the element name
    549             # should be.
    550              
    551 0 0         DEBUG > 1 and print "Pondering non-magical $para_type\n";
    552              
    553             # In tables, the start of a headrow or bodyrow also terminates an
    554             # existing open row.
    555 0 0 0       if($para_type eq '=headrow' || $para_type eq '=bodyrows') {
    556 0           $self->_ponder_row_end($para,$curr_open,$paras);
    557             }
    558              
    559             # Enforce some =headN discipline
    560 0 0 0       if($para_type =~ m/^=head\d$/s
          0        
          0        
    561             and ! $self->{'accept_heads_anywhere'}
    562             and @$curr_open
    563             and $curr_open->[-1][0] eq '=over'
    564             ) {
    565 0 0         DEBUG > 2 and print "'=$para_type' inside an '=over'!\n";
    566 0           $self->whine(
    567             $para->[1]{'start_line'},
    568             "You forgot a '=back' before '$para_type'"
    569             );
    570 0           unshift @$paras, ['=back', {}, ''], $para; # close the =over
    571 0           next;
    572             }
    573              
    574              
    575 0 0 0       if($para_type eq '=item') {
        0          
        0          
        0          
        0          
        0          
        0          
    576 0 0         next if $self->_ponder_item($para,$curr_open,$paras);
    577 0           $para_type = 'Plain';
    578             # Now fall thru and process it.
    579              
    580             } elsif($para_type eq '=extend') {
    581             # Well, might as well implement it here.
    582 0           $self->_ponder_extend($para);
    583 0           next; # and skip
    584             } elsif($para_type eq '=encoding') {
    585             # Not actually acted on here, but we catch errors here.
    586 0           $self->_handle_encoding_second_level($para);
    587              
    588 0           next; # and skip
    589             } elsif($para_type eq '~Verbatim') {
    590 0           $para->[0] = 'Verbatim';
    591 0           $para_type = '?Verbatim';
    592             } elsif($para_type eq '~Para') {
    593 0           $para->[0] = 'Para';
    594 0           $para_type = '?Plain';
    595             } elsif($para_type eq 'Data') {
    596 0           $para->[0] = 'Data';
    597 0           $para_type = '?Data';
    598             } elsif( $para_type =~ s/^=//s
    599             and defined( $para_type = $self->{'accept_directives'}{$para_type} )
    600             ) {
    601 0 0         DEBUG > 1 and print " Pondering known directive ${$para}[0] as $para_type\n";
      0            
    602             } else {
    603             # An unknown directive!
    604 0           DEBUG > 1 and printf "Unhandled directive %s (Handled: %s)\n",
    605 0 0         $para->[0], join(' ', sort keys %{$self->{'accept_directives'}} )
    606             ;
    607 0           $self->whine(
    608             $para->[1]{'start_line'},
    609             "Unknown directive: $para->[0]"
    610             );
    611              
    612             # And maybe treat it as text instead of just letting it go?
    613 0           next;
    614             }
    615              
    616 0 0         DEBUG > 1 and print "para_type is $para_type\n";
    617 0 0         if($para_type =~ s/^\?//s) {
    618 0 0         if(! @$curr_open) { # usual case
    619 0 0         DEBUG and print "Treating $para_type paragraph as such because stack is empty.\n";
    620             } else {
    621 0           my @fors = grep $_->[0] eq '=for', @$curr_open;
    622 0 0         DEBUG > 1 and print "Containing fors: ",
    623             join(',', map $_->[1]{'target'}, @fors), "\n";
    624              
    625 0 0         if(! @fors) {
        0          
    626 0 0         DEBUG and print "Treating $para_type paragraph as such because stack has no =for's\n";
    627              
    628             #} elsif(grep $_->[1]{'~resolve'}, @fors) {
    629             #} elsif(not grep !$_->[1]{'~resolve'}, @fors) {
    630             } elsif( $fors[-1][1]{'~resolve'} ) {
    631             # Look to the immediately containing for
    632 0 0         DEBUG and print "~resolve is $fors[-1][1]{'~resolve'}\n";
    633              
    634 0 0         if($para_type eq 'Data') {
    635 0 0         DEBUG and print "Treating Data paragraph as Plain/Verbatim because the containing =for ($fors[-1][1]{'target'}) is a resolver\n";
    636 0           $para->[0] = 'Para';
    637 0           $para_type = 'Plain';
    638             } else {
    639 0 0         DEBUG and print "Treating $para_type paragraph as such because the containing =for ($fors[-1][1]{'target'}) is a resolver\n";
    640             }
    641             } else {
    642 0 0         DEBUG and print "Treating $para_type paragraph as Data because the containing =for ($fors[-1][1]{'target'}) is a non-resolver\n";
    643 0           $para->[0] = $para_type = 'Data';
    644             }
    645             }
    646             }
    647              
    648             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    649 0 0         if($para_type eq 'Plain') {
        0          
        0          
    650 0           $self->_ponder_Plain($para);
    651             } elsif($para_type eq 'Verbatim') {
    652 0           $self->_ponder_Verbatim($para);
    653             } elsif($para_type eq 'Data') {
    654 0           $self->_ponder_Data($para);
    655             } else {
    656 0           die "\$para type is $para_type -- how did that happen?";
    657             # Shouldn't happen.
    658             }
    659              
    660             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    661 0           $para->[0] =~ s/^[~=]//s;
    662              
    663 0 0         DEBUG and print "\n", Pod::Simple::BlackBox::pretty($para), "\n";
    664              
    665             # traverse the treelet (which might well be just one string scalar)
    666 0   0       $self->{'content_seen'} ||= 1;
    667 0           $self->_traverse_treelet_bit(@$para);
    668             }
    669             }
    670              
    671 0           return;
    672             }
    673              
    674             1;