Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

import Pod::Simple 2.06 from CPAN

git-cpan-module: Pod::Simple
git-cpan-version: 2.06
git-cpan-authorid: SBURKE
  • Loading branch information...
commit 011585b332e49a0a12bdd5d81e2441245b0bf970 1 parent d8e219f
authored schwern committed
21  ChangeLog
... ...
@@ -1,6 +1,25 @@
1  
-# ChangeLog for Pod::Simple dist     # Time-stamp: "2003-11-04 23:16:23 AST"
  1
+# ChangeLog for Pod::Simple dist     # Time-stamp: "2004-05-07 15:25:25 ADT"
2 2
 #---------------------------------------------------------------------------
3 3
 
  4
+2004-05-07   Sean M. Burke <sburke@cpan.org>
  5
+	* Release 2.06
  6
+
  7
+	Allison Randal brilliantly refactors a huge monolithic sub in
  8
+	Blackbox.pm.  Code is now actually sanely readable!
  9
+
  10
+	I add the new option-attributes fullstop_space_harden and
  11
+	codes_in_verbatim, and the two methods abandon_output_string and
  12
+        abandon_output_fh.  Not yet documented.
  13
+
  14
+	New test fullstop_spaces.t and new corpus document
  15
+	greek_iso_8859_7.pod.
  16
+	
  17
+	Another version should be forthcoming in a few days that has the
  18
+	new Pod::Simple::HTML stuff in it.
  19
+
  20
+	Note to self: document =extend and =encoding in perlpodspec ASAP!
  21
+
  22
+	
4 23
 2003-11-04  Sean M. Burke <sburke@cpan.org>
5 24
 	* Release 2.05 -- bugfix version
6 25
 
3  MANIFEST
@@ -54,6 +54,8 @@ t/corpus/french_implicit_latin1.txt
54 54
 t/corpus/french_implicit_latin1.xml
55 55
 t/corpus/french_latin1.txt
56 56
 t/corpus/french_latin1.xml
  57
+t/corpus/greek_iso_8859_7.pod
  58
+t/corpus/greek_iso_8859_7.xml
57 59
 t/corpus/haiku-iso2202jp.txt
58 60
 t/corpus/haiku-iso2202jp.xml
59 61
 t/corpus/haiku-iso2202jpx.txt
@@ -105,6 +107,7 @@ t/fcodes_ell.t
105 107
 t/fcodes_ess.t
106 108
 t/for.t
107 109
 t/fornot.t
  110
+t/fullstop_spaces.t
108 111
 t/head_ends_over.t
109 112
 t/heads.t
110 113
 t/html-para.t
4  META.yml
... ...
@@ -1,7 +1,7 @@
1 1
 # http://module-build.sourceforge.net/META-spec.html
2 2
 #XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#
3 3
 name:         Pod-Simple
4  
-version:      2.05
  4
+version:      2.06
5 5
 version_from: lib/Pod/Simple.pm
6 6
 installdirs:  site
7 7
 requires:
@@ -9,4 +9,4 @@ requires:
9 9
     Text::Wrap:                    98.112902
10 10
 
11 11
 distribution_type: module
12  
-generated_by: ExtUtils::MakeMaker version 6.19
  12
+generated_by: ExtUtils::MakeMaker version 6.17
20  lib/Pod/Simple.pm
@@ -18,7 +18,7 @@ use vars qw(
18 18
 );
19 19
 
20 20
 @ISA = ('Pod::Simple::BlackBox');
21  
-$VERSION = '2.05';
  21
+$VERSION = '2.06';
22 22
 
23 23
 @Known_formatting_codes = qw(I B C L E F S X Z); 
24 24
 %Known_formatting_codes = map(($_=>1), @Known_formatting_codes);
@@ -80,6 +80,8 @@ __PACKAGE__->_accessorize(
80 80
   'bare_output',       # For some subclasses: whether to prepend
81 81
                        #  header-code and postpend footer-code
82 82
 
  83
+  'fullstop_space_harden', # Whether to turn ".  " into ".[nbsp] ";
  84
+
83 85
   'nix_X_codes',       # whether to ignore X<...> codes
84 86
   'merge_text',        # whether to avoid breaking a single piece of
85 87
                        #  text up into several events
@@ -87,6 +89,8 @@ __PACKAGE__->_accessorize(
87 89
  'content_seen',      # whether we've seen any real Pod content
88 90
  'errors_seen',       # TODO: document.  whether we've seen any errors (fatal or not)
89 91
 
  92
+ 'codes_in_verbatim', # for PseudoPod extensions
  93
+
90 94
  'code_handler',      # coderef to call when a code (non-pod) line is seen
91 95
  'cut_handler',       # coderef to call when a =cut line is seen
92 96
  #Called like:
@@ -139,9 +143,17 @@ sub output_string {
139 143
   $$x = '' unless defined $$x;
140 144
   DEBUG > 4 and print "# Output string set to $x ($$x)\n";
141 145
   $this->{'output_fh'} = Pod::Simple::TiedOutFH->handle_on($_[0]);
142  
-  return $this->{'output_string'} = ${ $this->{'output_fh'} };
  146
+  return
  147
+    $this->{'output_string'} = $_[0];
  148
+    #${ ${ $this->{'output_fh'} } };
143 149
 }
144 150
 
  151
+sub abandon_output_string { $_[0]->abandon_output_fh; delete $_[0]{'output_string'} }
  152
+sub abandon_output_fh     { $_[0]->output_fh(undef) }
  153
+# These don't delete the string or close the FH -- they just delete our
  154
+#  references to it/them.
  155
+# TODO: document these
  156
+
145 157
 #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
146 158
 
147 159
 sub new {
@@ -1008,7 +1020,9 @@ sub _treat_Ls {  # Process our dear dear friends, the L<...> sequences
1008 1020
       ) {
1009 1021
         $treelet->[$i][1]{'type'} = 'url';
1010 1022
         $treelet->[$i][1]{'content-implicit'} = 'yes';
1011  
-        
  1023
+
  1024
+        # TODO: deal with rel: URLs here?
  1025
+
1012 1026
         if( 3 == @{ $treelet->[$i] } ) {
1013 1027
           # But if it IS just one text node (most common case)
1014 1028
           DEBUG > 1 and printf qq{Catching "%s as " as ho-hum L<URL> link.\n},
969  lib/Pod/Simple/BlackBox.pm
@@ -525,237 +525,17 @@ sub _ponder_paragraph_buffer {
525 525
     DEBUG > 1 and print "Pondering a $para_type paragraph, given the stack: (",
526 526
       $self->_dump_curr_open(), ")\n";
527 527
     
528  
-    if($para_type eq '=for') { #//////////////////////////////////////////////
529  
-      # Fake it out as a begin/end
530  
-      my $target;
  528
+    if($para_type eq '=for') {
  529
+      next if $self->_ponder_for($para,$curr_open,$paras);
531 530
 
532  
-      if(grep $_->[1]{'~ignore'}, @$curr_open) {
533  
-        DEBUG > 1 and print "Ignoring ignorable =for\n";
534  
-        next;
535  
-      }
536  
-
537  
-      for(my $i = 2; $i < @$para; ++$i) {
538  
-        if($para->[$i] =~ s/^\s*(\S+)\s*//s) {
539  
-          $target = $1;
540  
-          last;
541  
-        }
542  
-      }
543  
-      unless(defined $target) {
544  
-        $self->whine(
545  
-          $para->[1]{'start_line'},
546  
-          "=for without a target?"
547  
-        );
548  
-        next;
549  
-      }
550  
-      DEBUG > 1 and
551  
-       print "Faking out a =for $target as a =begin $target / =end $target\n";
552  
-      
553  
-      $para->[0] = 'Data';
554  
-      
555  
-      unshift @$paras,
556  
-        ['=begin',
557  
-          {'start_line' => $para->[1]{'start_line'}, '~really' => '=for'},
558  
-          $target,
559  
-        ],
560  
-        $para,
561  
-        ['=end',
562  
-          {'start_line' => $para->[1]{'start_line'}, '~really' => '=for'},
563  
-          $target,
564  
-        ],
565  
-      ;
566  
-      
567  
-      next;
568  
-      
569  
-    } elsif($para_type eq '=begin') { #///////////////////////////////////////
570  
-
571  
-      my $content = join ' ', splice @$para, 2;
572  
-      $content =~ s/^\s+//s;
573  
-      $content =~ s/\s+$//s;
574  
-      unless(length($content)) {
575  
-        $self->whine(
576  
-          $para->[1]{'start_line'},
577  
-          "=begin without a target?"
578  
-        );
579  
-        DEBUG and print "Ignoring targetless =begin\n";
580  
-        next;
581  
-      }
582  
-      
583  
-      unless($content =~ m/^\S+$/s) {  # i.e., unless it's one word
584  
-        $self->whine(
585  
-          $para->[1]{'start_line'},
586  
-          "'=begin' only takes one parameter, not several as in '=begin $content'"
587  
-        );
588  
-        DEBUG and print "Ignoring unintelligible =begin $content\n";
589  
-        next;
590  
-      }
591  
-
592  
-
593  
-      $para->[1]{'target'} = $content;  # without any ':'
594  
-
595  
-      $content =~ s/^:!/!:/s;
596  
-      my $neg;  # whether this is a negation-match
597  
-      $neg = 1        if $content =~ s/^!//s;
598  
-      my $to_resolve;  # whether to process formatting codes
599  
-      $to_resolve = 1 if $content =~ s/^://s;
600  
-      
601  
-      my $dont_ignore; # whether this target matches us
602  
-      
603  
-      foreach my $target_name (
604  
-        split(',', $content, -1),
605  
-        $neg ? () : '*'
606  
-      ) {
607  
-        DEBUG > 2 and
608  
-         print " Considering whether =begin $content matches $target_name\n";
609  
-        next unless $self->{'accept_targets'}{$target_name};
610  
-        
611  
-        DEBUG > 2 and
612  
-         print "  It DOES match the acceptable target $target_name!\n";
613  
-        $to_resolve = 1
614  
-          if $self->{'accept_targets'}{$target_name} eq 'force_resolve';
615  
-        $dont_ignore = 1;
616  
-        $para->[1]{'target_matching'} = $target_name;
617  
-        last; # stop looking at other target names
618  
-      }
619  
-
620  
-      if($neg) {
621  
-        if( $dont_ignore ) {
622  
-          $dont_ignore = '';
623  
-          delete $para->[1]{'target_matching'};
624  
-          DEBUG > 2 and print " But the leading ! means that this is a NON-match!\n";
625  
-        } else {
626  
-          $dont_ignore = 1;
627  
-          $para->[1]{'target_matching'} = '!';
628  
-          DEBUG > 2 and print " But the leading ! means that this IS a match!\n";
629  
-        }
630  
-      }
631  
-
632  
-      $para->[0] = '=for';  # Just what we happen to call these, internally
633  
-      $para->[1]{'~really'} ||= '=begin';
634  
-      $para->[1]{'~ignore'}   = (! $dont_ignore) || 0;
635  
-      $para->[1]{'~resolve'}  = $to_resolve || 0;
  531
+    } elsif($para_type eq '=begin') {
  532
+      next if $self->_ponder_begin($para,$curr_open,$paras);
636 533
 
637  
-      DEBUG > 1 and print " Making note to ", $dont_ignore ? 'not ' : '',
638  
-        "ignore contents of this region\n";
639  
-      DEBUG > 1 and $dont_ignore and print " Making note to treat contents as ",
640  
-        ($to_resolve ? 'verbatim/plain' : 'data'), " paragraphs\n";
641  
-      DEBUG > 1 and print " (Stack now: ", $self->_dump_curr_open(), ")\n";
642  
-
643  
-      push @$curr_open, $para;
644  
-      if(!$dont_ignore or scalar grep $_->[1]{'~ignore'}, @$curr_open) {
645  
-        DEBUG > 1 and print "Ignoring ignorable =begin\n";
646  
-      } else {
647  
-        $self->{'content_seen'} ||= 1;
648  
-        $self->_handle_element_start(($scratch='for'), $para->[1]);
649  
-      }
650  
-
651  
-      next;
652  
-      
653  
-    } elsif($para_type eq '=end') { #/////////////////////////////////////////
654  
-
655  
-      my $content = join ' ', splice @$para, 2;
656  
-      $content =~ s/^\s+//s;
657  
-      $content =~ s/\s+$//s;
658  
-      DEBUG and print "Ogling '=end $content' directive\n";
659  
-      
660  
-      unless(length($content)) {
661  
-        $self->whine(
662  
-          $para->[1]{'start_line'},
663  
-          "'=end' without a target?" . (
664  
-            ( @$curr_open and $curr_open->[-1][0] eq '=for' )
665  
-            ? ( " (Should be \"=end " . $curr_open->[-1][1]{'target'} . '")' )
666  
-            : ''
667  
-          )
668  
-        );
669  
-        DEBUG and print "Ignoring targetless =end\n";
670  
-        next;
671  
-      }
672  
-      
673  
-      unless($content =~ m/^\S+$/) {  # i.e., unless it's one word
674  
-        $self->whine(
675  
-          $para->[1]{'start_line'},
676  
-          "'=end $content' is invalid.  (Stack: "
677  
-          . $self->_dump_curr_open() . ')'
678  
-        );
679  
-        DEBUG and print "Ignoring mistargetted =end $content\n";
680  
-        next;
681  
-      }
682  
-      
683  
-      unless(@$curr_open and $curr_open->[-1][0] eq '=for') {
684  
-        $self->whine(
685  
-          $para->[1]{'start_line'},
686  
-          "=end $content without matching =begin.  (Stack: "
687  
-          . $self->_dump_curr_open() . ')'
688  
-        );
689  
-        DEBUG and print "Ignoring mistargetted =end $content\n";
690  
-        next;
691  
-      }
692  
-      
693  
-      unless($content eq $curr_open->[-1][1]{'target'}) {
694  
-        $self->whine(
695  
-          $para->[1]{'start_line'},
696  
-          "=end $content doesn't match =begin " 
697  
-          . $curr_open->[-1][1]{'target'}
698  
-          . ".  (Stack: "
699  
-          . $self->_dump_curr_open() . ')'
700  
-        );
701  
-        DEBUG and print "Ignoring mistargetted =end $content at line $para->[1]{'start_line'}\n";
702  
-        next;
703  
-      }
704  
-
705  
-      # Else it's okay to close...
706  
-      if(grep $_->[1]{'~ignore'}, @$curr_open) {
707  
-        DEBUG > 1 and print "Not firing any event for this =end $content because in an ignored region\n";
708  
-        # And that may be because of this to-be-closed =for region, or some
709  
-        #  other one, but it doesn't matter.
710  
-      } else {
711  
-        $curr_open->[-1][1]{'start_line'} = $para->[1]{'start_line'};
712  
-          # what's that for?
713  
-        
714  
-        $self->{'content_seen'} ||= 1;
715  
-        $self->_handle_element_end( $scratch = 'for' );
716  
-      }
717  
-      DEBUG > 1 and print "Popping $curr_open->[-1][0] $curr_open->[-1][1]{'target'} because of =end $content\n";
718  
-      pop @$curr_open;
719  
-
720  
-      next;
721  
-      
722  
-    } elsif($para_type eq '~end') { #/////////////////////////////////////////
723  
-      # The virtual end-document signal
724  
-      
725  
-      if(@$curr_open) { # Deal with things left open
726  
-        DEBUG and print "Stack is nonempty at end-document: (",
727  
-          $self->_dump_curr_open(), ")\n";
728  
-          
729  
-        DEBUG > 9 and print "Stack: ", pretty($curr_open), "\n";
730  
-        unshift @$paras, $self->_closers_for_all_curr_open;
731  
-        # Make sure there is exactly one ~end in the parastack, at the end:
732  
-        @$paras = grep $_->[0] ne '~end', @$paras;
733  
-        push @$paras, $para, $para;
734  
-         # We need two -- once for the next cycle where we
735  
-         #  generate errata, and then another to be at the end
736  
-         #  when that loop back around to process the errata.
737  
-        next;
738  
-        
739  
-      } else {
740  
-        DEBUG and print "Okay, stack is empty now.\n";
741  
-      }
742  
-      
743  
-      # Try generating errata section, if applicable
744  
-      unless($self->{'~tried_gen_errata'}) {
745  
-        $self->{'~tried_gen_errata'} = 1;
746  
-        my @extras = $self->_gen_errata();
747  
-        if(@extras) {
748  
-          unshift @$paras, @extras;
749  
-          DEBUG and print "Generated errata... relooping...\n";
750  
-          next;  # I.e., loop around again to process these fake-o paragraphs
751  
-        }
752  
-      }
753  
-      
754  
-      splice @$paras; # Well, that's that for this paragraph buffer.
755  
-      DEBUG and print "Throwing end-document event.\n";
  534
+    } elsif($para_type eq '=end') {
  535
+      next if $self->_ponder_end($para,$curr_open,$paras);
756 536
 
757  
-      $self->_handle_element_end( $scratch = 'Document' );
758  
-      next; # Hasta la byebye
  537
+    } elsif($para_type eq '~end') { # The virtual end-document signal
  538
+      next if $self->_ponder_doc_end($para,$curr_open,$paras);
759 539
     }
760 540
 
761 541
 
@@ -769,97 +549,17 @@ sub _ponder_paragraph_buffer {
769 549
     #~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
770 550
     # ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
771 551
 
772  
-    if($para_type eq '=pod') { #//////////////////////////////////////////////
773  
-      $self->whine(
774  
-        $para->[1]{'start_line'},
775  
-        "=pod directives shouldn't be over one line long!  Ignoring all "
776  
-         . (@$para - 2) . " lines of content"
777  
-      ) if @$para > 3;
778  
-      # Content is always ignored.
779  
-      
  552
+    if($para_type eq '=pod') {
  553
+      $self->_ponder_pod($para,$curr_open,$paras);
780 554
 
781  
-    } elsif($para_type eq '=over') { #////////////////////////////////////////
782  
-      next unless @$paras;
783  
-      my $list_type;
  555
+    } elsif($para_type eq '=over') {
  556
+      next if $self->_ponder_over($para,$curr_open,$paras);
784 557
 
785  
-      if($paras->[0][0] eq '=item') { # most common case
786  
-        $list_type = $self->_get_initial_item_type($paras->[0]);
  558
+    } elsif($para_type eq '=back') {
  559
+      next if $self->_ponder_back($para,$curr_open,$paras);
787 560
 
788  
-      } elsif($paras->[0][0] eq '=back') {
789  
-        # Ignore empty lists.  TODO: make this an option?
790  
-        shift @$paras;
791  
-        next;
792  
-        
793  
-      } elsif($paras->[0][0] eq '~end') {
794  
-        $self->whine(
795  
-          $para->[1]{'start_line'},
796  
-          "=over is the last thing in the document?!"
797  
-        );
798  
-        next; # But feh, ignore it.
799  
-      } else {
800  
-        $list_type = 'block';
801  
-      }
802  
-      $para->[1]{'~type'} = $list_type;
803  
-      push @$curr_open, $para;
804  
-       # yes, we reuse the paragraph as a stack item
805  
-      
806  
-      my $content = join ' ', splice @$para, 2;
807  
-      my $overness;
808  
-      if($content =~ m/^\s*$/s) {
809  
-        $para->[1]{'indent'} = 4;
810  
-      } elsif($content =~ m/^\s*((?:\d*\.)?\d+)\s*$/s) {
811  
-        no integer;
812  
-        $para->[1]{'indent'} = $1;
813  
-        if($1 == 0) {
814  
-          $self->whine(
815  
-            $para->[1]{'start_line'},
816  
-            "Can't have a 0 in =over $content"
817  
-          );
818  
-          $para->[1]{'indent'} = 4;
819  
-        }
820  
-      } else {
821  
-        $self->whine(
822  
-          $para->[1]{'start_line'},
823  
-          "=over should be: '=over' or '=over positive_number'"
824  
-        );
825  
-        $para->[1]{'indent'} = 4;
826  
-      }
827  
-      DEBUG > 1 and print "=over found of type $list_type\n";
828  
-      
829  
-      $self->{'content_seen'} ||= 1;
830  
-      $self->_handle_element_start(($scratch = 'over-' . $list_type), $para->[1]);
831  
-      
832  
-    } elsif($para_type eq '=back') { #////////////////////////////////////////
833  
-
834  
-      # TODO: fire off </item-number> or </item-bullet> or </item-text> ??
835  
-
836  
-      my $content = join ' ', splice @$para, 2;
837  
-      if($content =~ m/\S/) {
838  
-        $self->whine(
839  
-          $para->[1]{'start_line'},
840  
-          "=back doesn't take any parameters, but you said =back $content"
841  
-        );
842  
-      }
  561
+    } else {
843 562
 
844  
-      if(@$curr_open and $curr_open->[-1][0] eq '=over') {
845  
-        DEBUG > 1 and print "=back happily closes matching =over\n";
846  
-        # Expected case: we're closing the most recently opened thing
847  
-        #my $over = pop @$curr_open;
848  
-        $self->{'content_seen'} ||= 1;
849  
-        $self->_handle_element_end( $scratch =
850  
-          'over-' . ( (pop @$curr_open)->[1]{'~type'} )
851  
-        );
852  
-      } else {
853  
-        DEBUG > 1 and print "=back found without a matching =over.  Stack: (",
854  
-            join(', ', map $_->[0], @$curr_open), ").\n";
855  
-        $self->whine(
856  
-          $para->[1]{'start_line'},
857  
-          '=back without =over'
858  
-        );
859  
-        next; # and ignore it
860  
-      }
861  
-      
862  
-    } else { #////////////////////////////////////////////////////////////////
863 563
       # All non-magical codes!!!
864 564
       
865 565
       # Here we start using $para_type for our own twisted purposes, to
@@ -1123,54 +823,11 @@ sub _ponder_paragraph_buffer {
1123 823
 
1124 824
       #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1125 825
       if($para_type eq 'Plain') {
1126  
-        DEBUG and print " giving plain treatment...\n";
1127  
-        unless( @$para == 2 or ( @$para == 3 and $para->[2] eq '' )
1128  
-          or $para->[1]{'~cooked'}
1129  
-        ) {
1130  
-          push @$para,
1131  
-          @{$self->_make_treelet(
1132  
-            join("\n", splice(@$para, 2)),
1133  
-            $para->[1]{'start_line'}
1134  
-          )};
1135  
-        }
1136  
-        # Empty paragraphs don't need a treelet for any reason I can see.
1137  
-        # And precooked paragraphs already have a treelet.
1138  
-        
  826
+        $self->_ponder_Plain($para);
1139 827
       } elsif($para_type eq 'Verbatim') {
1140  
-        DEBUG and print " giving verbatim treatment...\n";
1141  
-      
1142  
-        $para->[1]{'xml:space'} = 'preserve';
1143  
-        for($i = 2; $i < @$para; $i++) {
1144  
-          foreach my $line ($para->[$i]) { # just for aliasing
1145  
-            while( $line =~
1146  
-              # Sort of adapted from Text::Tabs -- yes, it's hardwired in that
1147  
-              # tabs are at every EIGHTH column.  For portability, it has to be
1148  
-              # one setting everywhere, and 8th wins.
1149  
-              s/^([^\t]*)(\t+)/$1.(" " x ((length($2)<<3)-(length($1)&7)))/e
1150  
-            ) {}
1151  
-
1152  
-            # TODO: whinge about (or otherwise treat) unindented or overlong lines
1153  
-
1154  
-          }
1155  
-        }
1156  
-        
1157  
-        # Now the VerbatimFormatted hoodoo...
1158  
-        if( $self->{'accept_codes'} and
1159  
-            $self->{'accept_codes'}{'VerbatimFormatted'}
1160  
-        ) {
1161  
-          while(@$para > 3 and $para->[-1] !~ m/\S/) { pop @$para }
1162  
-           # Kill any number of terminal newlines
1163  
-          $self->_verbatim_format($para);
1164  
-        } else {
1165  
-          push @$para, join "\n", splice(@$para, 2) if @$para > 3;
1166  
-          $para->[-1] =~ s/\n+$//s; # Kill any number of terminal newlines
1167  
-        }
1168  
-        
  828
+        $self->_ponder_Verbatim($para);        
1169 829
       } elsif($para_type eq 'Data') {
1170  
-        DEBUG and print " giving data treatment...\n";
1171  
-        $para->[1]{'xml:space'} = 'preserve';
1172  
-        push @$para, join "\n", splice(@$para, 2) if @$para > 3;
1173  
-        
  830
+        $self->_ponder_Data($para);
1174 831
       } else {
1175 832
         die "\$para type is $para_type -- how did that happen?";
1176 833
         # Shouldn't happen.
@@ -1190,6 +847,583 @@ sub _ponder_paragraph_buffer {
1190 847
   return;
1191 848
 }
1192 849
 
  850
+###########################################################################
  851
+# The sub-ponderers...
  852
+
  853
+
  854
+
  855
+sub _ponder_for {
  856
+  my ($self,$para,$curr_open,$paras) = @_;
  857
+
  858
+  # Fake it out as a begin/end
  859
+  my $target;
  860
+
  861
+  if(grep $_->[1]{'~ignore'}, @$curr_open) {
  862
+    DEBUG > 1 and print "Ignoring ignorable =for\n";
  863
+    return 1;
  864
+  }
  865
+
  866
+  for(my $i = 2; $i < @$para; ++$i) {
  867
+    if($para->[$i] =~ s/^\s*(\S+)\s*//s) {
  868
+      $target = $1;
  869
+      last;
  870
+    }
  871
+  }
  872
+  unless(defined $target) {
  873
+    $self->whine(
  874
+      $para->[1]{'start_line'},
  875
+      "=for without a target?"
  876
+    );
  877
+    return 1;
  878
+  }
  879
+  DEBUG > 1 and
  880
+   print "Faking out a =for $target as a =begin $target / =end $target\n";
  881
+  
  882
+  $para->[0] = 'Data';
  883
+  
  884
+  unshift @$paras,
  885
+    ['=begin',
  886
+      {'start_line' => $para->[1]{'start_line'}, '~really' => '=for'},
  887
+      $target,
  888
+    ],
  889
+    $para,
  890
+    ['=end',
  891
+      {'start_line' => $para->[1]{'start_line'}, '~really' => '=for'},
  892
+      $target,
  893
+    ],
  894
+  ;
  895
+  
  896
+  return 1;
  897
+}
  898
+
  899
+sub _ponder_begin {
  900
+  my ($self,$para,$curr_open,$paras) = @_;
  901
+  my $content = join ' ', splice @$para, 2;
  902
+  $content =~ s/^\s+//s;
  903
+  $content =~ s/\s+$//s;
  904
+  unless(length($content)) {
  905
+    $self->whine(
  906
+      $para->[1]{'start_line'},
  907
+      "=begin without a target?"
  908
+    );
  909
+    DEBUG and print "Ignoring targetless =begin\n";
  910
+    return 1;
  911
+  }
  912
+  
  913
+  unless($content =~ m/^\S+$/s) {  # i.e., unless it's one word
  914
+    $self->whine(
  915
+      $para->[1]{'start_line'},
  916
+      "'=begin' only takes one parameter, not several as in '=begin $content'"
  917
+    );
  918
+    DEBUG and print "Ignoring unintelligible =begin $content\n";
  919
+    return 1;
  920
+  }
  921
+
  922
+
  923
+  $para->[1]{'target'} = $content;  # without any ':'
  924
+
  925
+  $content =~ s/^:!/!:/s;
  926
+  my $neg;  # whether this is a negation-match
  927
+  $neg = 1        if $content =~ s/^!//s;
  928
+  my $to_resolve;  # whether to process formatting codes
  929
+  $to_resolve = 1 if $content =~ s/^://s;
  930
+  
  931
+  my $dont_ignore; # whether this target matches us
  932
+  
  933
+  foreach my $target_name (
  934
+    split(',', $content, -1),
  935
+    $neg ? () : '*'
  936
+  ) {
  937
+    DEBUG > 2 and
  938
+     print " Considering whether =begin $content matches $target_name\n";
  939
+    next unless $self->{'accept_targets'}{$target_name};
  940
+    
  941
+    DEBUG > 2 and
  942
+     print "  It DOES match the acceptable target $target_name!\n";
  943
+    $to_resolve = 1
  944
+      if $self->{'accept_targets'}{$target_name} eq 'force_resolve';
  945
+    $dont_ignore = 1;
  946
+    $para->[1]{'target_matching'} = $target_name;
  947
+    last; # stop looking at other target names
  948
+  }
  949
+
  950
+  if($neg) {
  951
+    if( $dont_ignore ) {
  952
+      $dont_ignore = '';
  953
+      delete $para->[1]{'target_matching'};
  954
+      DEBUG > 2 and print " But the leading ! means that this is a NON-match!\n";
  955
+    } else {
  956
+      $dont_ignore = 1;
  957
+      $para->[1]{'target_matching'} = '!';
  958
+      DEBUG > 2 and print " But the leading ! means that this IS a match!\n";
  959
+    }
  960
+  }
  961
+
  962
+  $para->[0] = '=for';  # Just what we happen to call these, internally
  963
+  $para->[1]{'~really'} ||= '=begin';
  964
+  $para->[1]{'~ignore'}   = (! $dont_ignore) || 0;
  965
+  $para->[1]{'~resolve'}  = $to_resolve || 0;
  966
+
  967
+  DEBUG > 1 and print " Making note to ", $dont_ignore ? 'not ' : '',
  968
+    "ignore contents of this region\n";
  969
+  DEBUG > 1 and $dont_ignore and print " Making note to treat contents as ",
  970
+    ($to_resolve ? 'verbatim/plain' : 'data'), " paragraphs\n";
  971
+  DEBUG > 1 and print " (Stack now: ", $self->_dump_curr_open(), ")\n";
  972
+
  973
+  push @$curr_open, $para;
  974
+  if(!$dont_ignore or scalar grep $_->[1]{'~ignore'}, @$curr_open) {
  975
+    DEBUG > 1 and print "Ignoring ignorable =begin\n";
  976
+  } else {
  977
+    $self->{'content_seen'} ||= 1;
  978
+    $self->_handle_element_start((my $scratch='for'), $para->[1]);
  979
+  }
  980
+
  981
+  return 1;
  982
+}
  983
+
  984
+sub _ponder_end {
  985
+  my ($self,$para,$curr_open,$paras) = @_;
  986
+  my $content = join ' ', splice @$para, 2;
  987
+  $content =~ s/^\s+//s;
  988
+  $content =~ s/\s+$//s;
  989
+  DEBUG and print "Ogling '=end $content' directive\n";
  990
+  
  991
+  unless(length($content)) {
  992
+    $self->whine(
  993
+      $para->[1]{'start_line'},
  994
+      "'=end' without a target?" . (
  995
+        ( @$curr_open and $curr_open->[-1][0] eq '=for' )
  996
+        ? ( " (Should be \"=end " . $curr_open->[-1][1]{'target'} . '")' )
  997
+        : ''
  998
+      )
  999
+    );
  1000
+    DEBUG and print "Ignoring targetless =end\n";
  1001
+    return 1;
  1002
+  }
  1003
+  
  1004
+  unless($content =~ m/^\S+$/) {  # i.e., unless it's one word
  1005
+    $self->whine(
  1006
+      $para->[1]{'start_line'},
  1007
+      "'=end $content' is invalid.  (Stack: "
  1008
+      . $self->_dump_curr_open() . ')'
  1009
+    );
  1010
+    DEBUG and print "Ignoring mistargetted =end $content\n";
  1011
+    return 1;
  1012
+  }
  1013
+  
  1014
+  unless(@$curr_open and $curr_open->[-1][0] eq '=for') {
  1015
+    $self->whine(
  1016
+      $para->[1]{'start_line'},
  1017
+      "=end $content without matching =begin.  (Stack: "
  1018
+      . $self->_dump_curr_open() . ')'
  1019
+    );
  1020
+    DEBUG and print "Ignoring mistargetted =end $content\n";
  1021
+    return 1;
  1022
+  }
  1023
+  
  1024
+  unless($content eq $curr_open->[-1][1]{'target'}) {
  1025
+    $self->whine(
  1026
+      $para->[1]{'start_line'},
  1027
+      "=end $content doesn't match =begin " 
  1028
+      . $curr_open->[-1][1]{'target'}
  1029
+      . ".  (Stack: "
  1030
+      . $self->_dump_curr_open() . ')'
  1031
+    );
  1032
+    DEBUG and print "Ignoring mistargetted =end $content at line $para->[1]{'start_line'}\n";
  1033
+    return 1;
  1034
+  }
  1035
+
  1036
+  # Else it's okay to close...
  1037
+  if(grep $_->[1]{'~ignore'}, @$curr_open) {
  1038
+    DEBUG > 1 and print "Not firing any event for this =end $content because in an ignored region\n";
  1039
+    # And that may be because of this to-be-closed =for region, or some
  1040
+    #  other one, but it doesn't matter.
  1041
+  } else {
  1042
+    $curr_open->[-1][1]{'start_line'} = $para->[1]{'start_line'};
  1043
+      # what's that for?
  1044
+    
  1045
+    $self->{'content_seen'} ||= 1;
  1046
+    $self->_handle_element_end( my $scratch = 'for' );
  1047
+  }
  1048
+  DEBUG > 1 and print "Popping $curr_open->[-1][0] $curr_open->[-1][1]{'target'} because of =end $content\n";
  1049
+  pop @$curr_open;
  1050
+
  1051
+  return 1;
  1052
+} 
  1053
+
  1054
+sub _ponder_doc_end {
  1055
+  my ($self,$para,$curr_open,$paras) = @_;
  1056
+  if(@$curr_open) { # Deal with things left open
  1057
+    DEBUG and print "Stack is nonempty at end-document: (",
  1058
+      $self->_dump_curr_open(), ")\n";
  1059
+      
  1060
+    DEBUG > 9 and print "Stack: ", pretty($curr_open), "\n";
  1061
+    unshift @$paras, $self->_closers_for_all_curr_open;
  1062
+    # Make sure there is exactly one ~end in the parastack, at the end:
  1063
+    @$paras = grep $_->[0] ne '~end', @$paras;
  1064
+    push @$paras, $para, $para;
  1065
+     # We need two -- once for the next cycle where we
  1066
+     #  generate errata, and then another to be at the end
  1067
+     #  when that loop back around to process the errata.
  1068
+    return 1;
  1069
+    
  1070
+  } else {
  1071
+    DEBUG and print "Okay, stack is empty now.\n";
  1072
+  }
  1073
+  
  1074
+  # Try generating errata section, if applicable
  1075
+  unless($self->{'~tried_gen_errata'}) {
  1076
+    $self->{'~tried_gen_errata'} = 1;
  1077
+    my @extras = $self->_gen_errata();
  1078
+    if(@extras) {
  1079
+      unshift @$paras, @extras;
  1080
+      DEBUG and print "Generated errata... relooping...\n";
  1081
+      return 1;  # I.e., loop around again to process these fake-o paragraphs
  1082
+    }
  1083
+  }
  1084
+  
  1085
+  splice @$paras; # Well, that's that for this paragraph buffer.
  1086
+  DEBUG and print "Throwing end-document event.\n";
  1087
+
  1088
+  $self->_handle_element_end( my $scratch = 'Document' );
  1089
+  return 1; # Hasta la byebye
  1090
+}
  1091
+
  1092
+sub _ponder_pod {
  1093
+  my ($self,$para,$curr_open,$paras) = @_;
  1094
+  $self->whine(
  1095
+    $para->[1]{'start_line'},
  1096
+    "=pod directives shouldn't be over one line long!  Ignoring all "
  1097
+     . (@$para - 2) . " lines of content"
  1098
+  ) if @$para > 3;
  1099
+  # Content is always ignored.
  1100
+  return;
  1101
+}
  1102
+
  1103
+sub _ponder_over {
  1104
+  my ($self,$para,$curr_open,$paras) = @_;
  1105
+  return 1 unless @$paras;
  1106
+  my $list_type;
  1107
+
  1108
+  if($paras->[0][0] eq '=item') { # most common case
  1109
+    $list_type = $self->_get_initial_item_type($paras->[0]);
  1110
+
  1111
+  } elsif($paras->[0][0] eq '=back') {
  1112
+    # Ignore empty lists.  TODO: make this an option?
  1113
+    shift @$paras;
  1114
+    return 1;
  1115
+    
  1116
+  } elsif($paras->[0][0] eq '~end') {
  1117
+    $self->whine(
  1118
+      $para->[1]{'start_line'},
  1119
+      "=over is the last thing in the document?!"
  1120
+    );
  1121
+    return 1; # But feh, ignore it.
  1122
+  } else {
  1123
+    $list_type = 'block';
  1124
+  }
  1125
+  $para->[1]{'~type'} = $list_type;
  1126
+  push @$curr_open, $para;
  1127
+   # yes, we reuse the paragraph as a stack item
  1128
+  
  1129
+  my $content = join ' ', splice @$para, 2;
  1130
+  my $overness;
  1131
+  if($content =~ m/^\s*$/s) {
  1132
+    $para->[1]{'indent'} = 4;
  1133
+  } elsif($content =~ m/^\s*((?:\d*\.)?\d+)\s*$/s) {
  1134
+    no integer;
  1135
+    $para->[1]{'indent'} = $1;
  1136
+    if($1 == 0) {
  1137
+      $self->whine(
  1138
+        $para->[1]{'start_line'},
  1139
+        "Can't have a 0 in =over $content"
  1140
+      );
  1141
+      $para->[1]{'indent'} = 4;
  1142
+    }
  1143
+  } else {
  1144
+    $self->whine(
  1145
+      $para->[1]{'start_line'},
  1146
+      "=over should be: '=over' or '=over positive_number'"
  1147
+    );
  1148
+    $para->[1]{'indent'} = 4;
  1149
+  }
  1150
+  DEBUG > 1 and print "=over found of type $list_type\n";
  1151
+  
  1152
+  $self->{'content_seen'} ||= 1;
  1153
+  $self->_handle_element_start((my $scratch = 'over-' . $list_type), $para->[1]);
  1154
+
  1155
+  return;
  1156
+}
  1157
+      
  1158
+sub _ponder_back {
  1159
+  my ($self,$para,$curr_open,$paras) = @_;
  1160
+  # TODO: fire off </item-number> or </item-bullet> or </item-text> ??
  1161
+
  1162
+  my $content = join ' ', splice @$para, 2;
  1163
+  if($content =~ m/\S/) {
  1164
+    $self->whine(
  1165
+      $para->[1]{'start_line'},
  1166
+      "=back doesn't take any parameters, but you said =back $content"
  1167
+    );
  1168
+  }
  1169
+
  1170
+  if(@$curr_open and $curr_open->[-1][0] eq '=over') {
  1171
+    DEBUG > 1 and print "=back happily closes matching =over\n";
  1172
+    # Expected case: we're closing the most recently opened thing
  1173
+    #my $over = pop @$curr_open;
  1174
+    $self->{'content_seen'} ||= 1;
  1175
+    $self->_handle_element_end( my $scratch =
  1176
+      'over-' . ( (pop @$curr_open)->[1]{'~type'} )
  1177
+    );
  1178
+  } else {
  1179
+    DEBUG > 1 and print "=back found without a matching =over.  Stack: (",
  1180
+        join(', ', map $_->[0], @$curr_open), ").\n";
  1181
+    $self->whine(
  1182
+      $para->[1]{'start_line'},
  1183
+      '=back without =over'
  1184
+    );
  1185
+    return 1; # and ignore it
  1186
+  }
  1187
+}
  1188
+
  1189
+sub _ponder_item {
  1190
+  my ($self,$para,$curr_open,$paras) = @_;
  1191
+  my $over;
  1192
+  unless(@$curr_open and ($over = $curr_open->[-1])->[0] eq '=over') {
  1193
+    $self->whine(
  1194
+      $para->[1]{'start_line'},
  1195
+      "'=item' outside of any '=over'"
  1196
+    );
  1197
+    unshift @$paras,
  1198
+      ['=over', {'start_line' => $para->[1]{'start_line'}}, ''],
  1199
+      $para
  1200
+    ;
  1201
+    return 1;
  1202
+  }
  1203
+  
  1204
+  
  1205
+  my $over_type = $over->[1]{'~type'};
  1206
+  
  1207
+  if(!$over_type) {
  1208
+    # Shouldn't happen1
  1209
+    die "Typeless over in stack, starting at line "
  1210
+     . $over->[1]{'start_line'};
  1211
+
  1212
+  } elsif($over_type eq 'block') {
  1213
+    unless($curr_open->[-1][1]{'~bitched_about'}) {
  1214
+      $curr_open->[-1][1]{'~bitched_about'} = 1;
  1215
+      $self->whine(
  1216
+        $curr_open->[-1][1]{'start_line'},
  1217
+        "You can't have =items (as at line "
  1218
+        . $para->[1]{'start_line'}
  1219
+        . ") unless the first thing after the =over is an =item"
  1220
+      );
  1221
+    }
  1222
+    # Just turn it into a paragraph and reconsider it
  1223
+    $para->[0] = '~Para';
  1224
+    unshift @$paras, $para;
  1225
+    return 1;
  1226
+
  1227
+  } elsif($over_type eq 'text') {
  1228
+    my $item_type = $self->_get_item_type($para);
  1229
+      # That kills the content of the item if it's a number or bullet.
  1230
+    DEBUG and print " Item is of type ", $para->[0], " under $over_type\n";
  1231
+    
  1232
+    if($item_type eq 'text') {
  1233
+      # Nothing special needs doing for 'text'
  1234
+    } elsif($item_type eq 'number' or $item_type eq 'bullet') {
  1235
+      die "Unknown item type $item_type"
  1236
+       unless $item_type eq 'number' or $item_type eq 'bullet';
  1237
+      # Undo our clobbering:
  1238
+      push @$para, $para->[1]{'~orig_content'};
  1239
+      delete $para->[1]{'number'};
  1240
+       # Only a PROPER item-number element is allowed
  1241
+       #  to have a number attribute.
  1242
+    } else {
  1243
+      die "Unhandled item type $item_type"; # should never happen
  1244
+    }
  1245
+    
  1246
+    # =item-text thingies don't need any assimilation, it seems.
  1247
+
  1248
+  } elsif($over_type eq 'number') {
  1249
+    my $item_type = $self->_get_item_type($para);
  1250
+      # That kills the content of the item if it's a number or bullet.
  1251
+    DEBUG and print " Item is of type ", $para->[0], " under $over_type\n";
  1252
+    
  1253
+    my $expected_value = ++ $curr_open->[-1][1]{'~counter'};
  1254
+    
  1255
+    if($item_type eq 'bullet') {
  1256
+      # Hm, it's not numeric.  Correct for this.
  1257
+      $para->[1]{'number'} = $expected_value;
  1258
+      $self->whine(
  1259
+        $para->[1]{'start_line'},
  1260
+        "Expected '=item $expected_value'"
  1261
+      );
  1262
+      push @$para, $para->[1]{'~orig_content'};
  1263
+        # restore the bullet, blocking the assimilation of next para
  1264
+
  1265
+    } elsif($item_type eq 'text') {
  1266
+      # Hm, it's not numeric.  Correct for this.
  1267
+      $para->[1]{'number'} = $expected_value;
  1268
+      $self->whine(
  1269
+        $para->[1]{'start_line'},
  1270
+        "Expected '=item $expected_value'"
  1271
+      );
  1272
+      # Text content will still be there and will block next ~Para
  1273
+
  1274
+    } elsif($item_type ne 'number') {
  1275
+      die "Unknown item type $item_type"; # should never happen
  1276
+
  1277
+    } elsif($expected_value == $para->[1]{'number'}) {
  1278
+      DEBUG > 1 and print " Numeric item has the expected value of $expected_value\n";
  1279
+      
  1280
+    } else {
  1281
+      DEBUG > 1 and print " Numeric item has ", $para->[1]{'number'},
  1282
+       " instead of the expected value of $expected_value\n";
  1283
+      $self->whine(
  1284
+        $para->[1]{'start_line'},
  1285
+        "You have '=item " . $para->[1]{'number'} .
  1286
+        "' instead of the expected '=item $expected_value'"
  1287
+      );
  1288
+      $para->[1]{'number'} = $expected_value;  # correcting!!
  1289
+    }
  1290
+      
  1291
+    if(@$para == 2) {
  1292
+      # For the cases where we /didn't/ push to @$para
  1293
+      if($paras->[0][0] eq '~Para') {
  1294
+        DEBUG and print "Assimilating following ~Para content into $over_type item\n";
  1295
+        push @$para, splice @{shift @$paras},2;
  1296
+      } else {
  1297
+        DEBUG and print "Can't assimilate following ", $paras->[0][0], "\n";
  1298
+        push @$para, '';  # Just so it's not contentless
  1299
+      }
  1300
+    }
  1301
+
  1302
+
  1303
+  } elsif($over_type eq 'bullet') {
  1304
+    my $item_type = $self->_get_item_type($para);
  1305
+      # That kills the content of the item if it's a number or bullet.
  1306
+    DEBUG and print " Item is of type ", $para->[0], " under $over_type\n";
  1307
+    
  1308
+    if($item_type eq 'bullet') {
  1309
+      # as expected!
  1310
+
  1311
+      if( $para->[1]{'~_freaky_para_hack'} ) {
  1312
+        DEBUG and print "Accomodating '=item * Foo' tolerance hack.\n";
  1313
+        push @$para, delete $para->[1]{'~_freaky_para_hack'};
  1314
+      }
  1315
+
  1316
+    } elsif($item_type eq 'number') {
  1317
+      $self->whine(
  1318
+        $para->[1]{'start_line'},
  1319
+        "Expected '=item *'"
  1320
+      );
  1321
+      push @$para, $para->[1]{'~orig_content'};
  1322
+       # and block assimilation of the next paragraph
  1323
+      delete $para->[1]{'number'};
  1324
+       # Only a PROPER item-number element is allowed
  1325
+       #  to have a number attribute.
  1326
+    } elsif($item_type eq 'text') {
  1327
+      $self->whine(
  1328
+        $para->[1]{'start_line'},
  1329
+        "Expected '=item *'"
  1330
+      );
  1331
+       # But doesn't need processing.  But it'll block assimilation
  1332
+       #  of the next para.
  1333
+    } else {
  1334
+      die "Unhandled item type $item_type"; # should never happen
  1335
+    }
  1336
+
  1337
+    if(@$para == 2) {
  1338
+      # For the cases where we /didn't/ push to @$para
  1339
+      if($paras->[0][0] eq '~Para') {
  1340
+        DEBUG and print "Assimilating following ~Para content into $over_type item\n";
  1341
+        push @$para, splice @{shift @$paras},2;
  1342
+      } else {
  1343
+        DEBUG and print "Can't assimilate following ", $paras->[0][0], "\n";
  1344
+        push @$para, '';  # Just so it's not contentless
  1345
+      }
  1346
+    }
  1347
+
  1348
+  } else {
  1349
+    die "Unhandled =over type \"$over_type\"?";
  1350
+    # Shouldn't happen!
  1351
+  }
  1352
+  $para->[0] .= '-' . $over_type;
  1353
+
  1354
+  return;
  1355
+}
  1356
+
  1357
+sub _ponder_Plain {
  1358
+  my ($self,$para) = @_;
  1359
+  DEBUG and print " giving plain treatment...\n";
  1360
+  unless( @$para == 2 or ( @$para == 3 and $para->[2] eq '' )
  1361
+    or $para->[1]{'~cooked'}
  1362
+  ) {
  1363
+    push @$para,
  1364
+    @{$self->_make_treelet(
  1365
+      join("\n", splice(@$para, 2)),
  1366
+      $para->[1]{'start_line'}
  1367
+    )};
  1368
+  }
  1369
+  # Empty paragraphs don't need a treelet for any reason I can see.
  1370
+  # And precooked paragraphs already have a treelet.
  1371
+  return;
  1372
+}
  1373
+
  1374
+sub _ponder_Verbatim {
  1375
+  my ($self,$para) = @_;
  1376
+  DEBUG and print " giving verbatim treatment...\n";
  1377
+
  1378
+  $para->[1]{'xml:space'} = 'preserve';
  1379
+  for(my $i = 2; $i < @$para; $i++) {
  1380
+    foreach my $line ($para->[$i]) { # just for aliasing
  1381
+      while( $line =~
  1382
+        # Sort of adapted from Text::Tabs -- yes, it's hardwired in that
  1383
+        # tabs are at every EIGHTH column.  For portability, it has to be
  1384
+        # one setting everywhere, and 8th wins.
  1385
+        s/^([^\t]*)(\t+)/$1.(" " x ((length($2)<<3)-(length($1)&7)))/e
  1386
+      ) {}
  1387
+
  1388
+      # TODO: whinge about (or otherwise treat) unindented or overlong lines
  1389
+
  1390
+    }
  1391
+  }
  1392
+  
  1393
+  # Now the VerbatimFormatted hoodoo...
  1394
+  if( $self->{'accept_codes'} and
  1395
+      $self->{'accept_codes'}{'VerbatimFormatted'}
  1396
+  ) {
  1397
+    while(@$para > 3 and $para->[-1] !~ m/\S/) { pop @$para }
  1398
+     # Kill any number of terminal newlines
  1399
+    $self->_verbatim_format($para);
  1400
+  } elsif ($self->{'codes_in_verbatim'}) {
  1401
+    push @$para,
  1402
+    @{$self->_make_treelet(
  1403
+      join("\n", splice(@$para, 2)),
  1404
+      $para->[1]{'start_line'}, $para->[1]{'xml:space'}
  1405
+    )};
  1406
+    $para->[-1] =~ s/\n+$//s; # Kill any number of terminal newlines
  1407
+  } else {
  1408
+    push @$para, join "\n", splice(@$para, 2) if @$para > 3;
  1409
+    $para->[-1] =~ s/\n+$//s; # Kill any number of terminal newlines
  1410
+  }
  1411
+  return;
  1412
+}
  1413
+
  1414
+sub _ponder_Data {
  1415
+  my ($self,$para) = @_;
  1416
+  DEBUG and print " giving data treatment...\n";
  1417
+  $para->[1]{'xml:space'} = 'preserve';
  1418
+  push @$para, join "\n", splice(@$para, 2) if @$para > 3;
  1419
+  return;
  1420
+}
  1421
+
  1422
+
  1423
+
  1424
+
  1425
+###########################################################################
  1426
+
1193 1427
 sub _traverse_treelet_bit {  # for use only by the routine above
1194 1428
   my($self, $name) = splice @_,0,2;
1195 1429
 
@@ -1382,12 +1616,17 @@ sub _treelet_from_formatting_codes {
1382 1616
   #            "!"
1383 1617
   #       ]
1384 1618
   
1385  
-  my($self, $para, $start_line) = @_;
  1619
+  my($self, $para, $start_line, $preserve_space) = @_;
  1620
+  
1386 1621
   my $treelet = ['~Top', {'start_line' => $start_line},];
1387 1622
   
1388  
-  $para =~ s/\s+/ /g; # collapse and trim all whitespace first.
1389  
-  $para =~ s/ $//g;
1390  
-  $para =~ s/^ //g;
  1623
+  unless ($preserve_space) {
  1624
+    $para =~ s/\.  /\.\xA0 /g if $self->{'fullstop_space_harden'};
  1625
+  
  1626
+    $para =~ s/\s+/ /g; # collapse and trim all whitespace first.
  1627
+    $para =~ s/ $//;
  1628
+    $para =~ s/^ //;
  1629
+  }
1391 1630
   
1392 1631
   # Only apparent problem the above code is that N<<  >> turns into
1393 1632
   # N<< >>.  But then, word wrapping does that too!  So don't do that!
30  t/corpus/greek_iso_8859_7.pod
Source Rendered
... ...
@@ -0,0 +1,30 @@
  1
+
  2
+=encoding iso-8859-7
  3
+
  4
+=head1 NAME
  5
+
  6
+Ολυμπιακός Ύμνος -- Κωστής Παλαμάς
  7
+
  8
+=head1 DESCRIPTION
  9
+
  10
+Αρχαίο Πνεύμ' αθάνατον, αγνέ πατέρα
  11
+του ωραίου, του μεγάλου και τ' αληθινού,
  12
+
  13
+κατέβα, φανερώσου κι άστραψ' εδώ πέρα
  14
+στη δόξα της δικής σου γης και τ' ουρανού.
  15
+
  16
+Στο δρόμο και στο πάλεμα και στο λιθάρι,
  17
+στων ευγενών Αγώνων λάμψε την ορμή,
  18
+
  19
+και με τ' αμάραντο στεφάνωσε κλωνάρι
  20
+και σιδερένιο πλάσε κι άξιο το κορμί.