Index: t/strip_verbatim_indent.t
===================================================================
--- t/strip_verbatim_indent.t (revision 0)
+++ t/strip_verbatim_indent.t (revision 0)
@@ -0,0 +1,111 @@
+#!/usr/bin/perl -w
+
+# t/strip_verbatim_indent.t.t - check verabtim indent stripping feature
+
+BEGIN {
+ chdir 't' if -d 't';
+}
+
+use strict;
+use lib '../lib';
+#use Test::More tests => 71;
+use Test::More 'no_plan';
+
+use_ok('Pod::Simple::XHTML') or exit;
+use_ok('Pod::Simple::XMLOutStream') or exit;
+
+isa_ok my $parser = Pod::Simple::XHTML->new, 'Pod::Simple::XHTML';
+
+ok $parser->strip_verbatim_indent(' '), 'Should be able to set striper to " "';
+ok $parser->strip_verbatim_indent(' '), 'Should be able to set striper to " "';
+ok $parser->strip_verbatim_indent("t"), 'Should be able to set striper to "\\t"';
+ok $parser->strip_verbatim_indent(sub { ' ' }), 'Should be able to set striper to coderef';
+
+for my $spec (
+ [
+ "\n=pod\n\n foo bar baz\n",
+ undef,
+ qq{<Document><Verbatim\nxml:space="preserve"> foo bar baz</Verbatim></Document>},
+ "<pre><code> foo bar baz</code></pre>\n\n",
+ 'undefined indent'
+ ],
+ [
+ "\n=pod\n\n foo bar baz\n",
+ ' ',
+ qq{<Document><Verbatim\nxml:space="preserve">foo bar baz</Verbatim></Document>},
+ "<pre><code>foo bar baz</code></pre>\n\n",
+ 'single space indent'
+ ],
+ [
+ "\n=pod\n\n foo bar baz\n",
+ ' ',
+ qq{<Document><Verbatim\nxml:space="preserve"> foo bar baz</Verbatim></Document>},
+ "<pre><code> foo bar baz</code></pre>\n\n",
+ 'too large indent'
+ ],
+ [
+ "\n=pod\n\n foo bar baz\n",
+ ' ',
+ qq{<Document><Verbatim\nxml:space="preserve">foo bar baz</Verbatim></Document>},
+ "<pre><code>foo bar baz</code></pre>\n\n",
+ 'double space indent'
+ ],
+ [
+ "\n=pod\n\n foo bar baz\n",
+ sub { ' ' },
+ qq{<Document><Verbatim\nxml:space="preserve">foo bar baz</Verbatim></Document>},
+ "<pre><code>foo bar baz</code></pre>\n\n",
+ 'code ref stripper'
+ ],
+ [
+ "\n=pod\n\n foo bar\n\n baz blez\n",
+ ' ',
+ qq{<Document><Verbatim\nxml:space="preserve">foo bar\n\nbaz blez</Verbatim></Document>},
+ "<pre><code>foo bar\n\nbaz blez</code></pre>\n\n",
+ 'single space indent and empty line'
+ ],
+ [
+ "\n=pod\n\n foo bar\n\n baz blez\n",
+ sub { ' ' },
+ qq{<Document><Verbatim\nxml:space="preserve">foo bar\n\nbaz blez</Verbatim></Document>},
+ "<pre><code>foo bar\n\nbaz blez</code></pre>\n\n",
+ 'code ref indent and empty line'
+ ],
+ [
+ "\n=pod\n\n foo bar\n\n baz blez\n",
+ sub { (my $s = shift->[0]) =~ s/\S.*//; $s },
+ qq{<Document><Verbatim\nxml:space="preserve">foo bar\n\nbaz blez</Verbatim></Document>},
+ "<pre><code>foo bar\n\nbaz blez</code></pre>\n\n",
+ 'heuristic code ref indent'
+ ],
+ [
+ "\n=pod\n\n foo bar\n baz blez\n",
+ sub { s/^\s+// for @{ $_[0] } },
+ qq{<Document><Verbatim\nxml:space="preserve">foo bar\nbaz blez</Verbatim></Document>},
+ "<pre><code>foo bar\nbaz blez</code></pre>\n\n",
+ 'militant code ref'
+ ],
+) {
+ my ($pod, $indent, $xml, $xhtml, $desc) = @$spec;
+ # Test XML output.
+ ok my $p = Pod::Simple::XMLOutStream->new, "Construct XML parser to test $desc";
+ $p->hide_line_numbers(1);
+ my $output = '';
+ $p->output_string( \$output );
+ is $indent, $p->strip_verbatim_indent($indent),
+ 'Set stripper for XML to ' . (defined $indent ? qq{"$indent"} : 'undef');
+ ok $p->parse_string_document( $pod ), "Parse POD to XML for $desc";
+ is $output, $xml, "Should have expected XML output for $desc";
+
+
+ # Test XHTML output.
+ ok $p = Pod::Simple::XHTML->new, "Construct XHMTL parser to test $desc";
+ $p->html_header('');
+ $p->html_footer('');
+ $output = '';
+ $p->output_string( \$output );
+ is $indent, $p->strip_verbatim_indent($indent),
+ 'Set stripper for XHTML to ' . (defined $indent ? qq{"$indent"} : 'undef');
+ ok $p->parse_string_document( $pod ), "Parse POD to XHTML for $desc";
+ is $output, $xhtml, "Should have expected XHTML output for $desc";
+}
Index: lib/Pod/Simple.pm
===================================================================
--- lib/Pod/Simple.pm (revision 370)
+++ lib/Pod/Simple.pm (working copy)
@@ -67,7 +67,7 @@
'hide_line_numbers', # For some dumping subclasses: whether to pointedly
# suppress the start_line attribute
-
+
'line_count', # the current line number
'pod_para_count', # count of pod paragraphs seen so far
@@ -87,6 +87,7 @@
# text up into several events
'preserve_whitespace', # whether to try to keep whitespace as-is
+ 'strip_verbatim_indent', # What indent to strip from verbatim
'content_seen', # whether we've seen any real Pod content
'errors_seen', # TODO: document. whether we've seen any errors (fatal or not)
@@ -98,7 +99,7 @@
#Called like:
# $code_handler->($line, $self->{'line_count'}, $self) if $code_handler;
# $cut_handler->($line, $self->{'line_count'}, $self) if $cut_handler;
-
+
);
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Index: lib/Pod/Simple/BlackBox.pm
===================================================================
--- lib/Pod/Simple/BlackBox.pm (revision 370)
+++ lib/Pod/Simple/BlackBox.pm (working copy)
@@ -1369,8 +1369,19 @@
DEBUG and print " giving verbatim treatment...\n";
$para->[1]{'xml:space'} = 'preserve';
+
+ my $indent = $self->strip_verbatim_indent;
+ if ($indent && ref $indent eq 'CODE') {
+ my @shifted = (shift @{$para}, shift @{$para});
+ $indent = $indent->($para);
+ unshift @{$para}, @shifted;
+ }
+
for(my $i = 2; $i < @$para; $i++) {
foreach my $line ($para->[$i]) { # just for aliasing
+ # Strip indentation.
+ $line =~ s/^\E$indent// if $indent
+ && !($self->{accept_codes} && $self->{accept_codes}{VerbatimFormatted});
while( $line =~
# Sort of adapted from Text::Tabs -- yes, it's hardwired in that
# tabs are at every EIGHTH column. For portability, it has to be
Index: lib/Pod/Simple.pod
===================================================================
--- lib/Pod/Simple.pod (revision 370)
+++ lib/Pod/Simple.pod (working copy)
@@ -173,9 +173,52 @@
This returns true if C<$parser> has read from a source, and come to the
end of that source.
+=item C<< $parser->strip_verbatim_indent( I<SOMEVALUE> ) >>
+
+The perlpod spec for a Verbatim paragraph is "It should be reproduced
+exactly...", which means that the whitespace you've used to indent your
+verbatim blocks will be preserved in the output. This can be annoying for
+outputs such as HTML, where that whitespace will remain in front of every
+line. It's an unfortunate case where syntax is turned into semantics.
+
+If the POD your parsing adheres to a consistent indentation policy, you can
+have such indentation stripped from the beginning of every line of your
+verbatim blocks. This method tells Pod::Simple what to strip. For two-space
+indents, you'd use:
+
+ $parser->strip_verbatim_indent(' ');
+
+For tab indents, you'd use a tab character:
+
+ $parser->strip_verbatim_indent("\t");
+
+If the POD is inconsistent about the indentation of verbatim blocks, but you
+have figured out a heuristic to determine how much a particular verbatim block
+is indented, you can pass a code reference instead. The code reference will be
+executed with one argument, an array reference of all the lines in the
+verbatim block, and should return the value to be stripped from each line. For
+example, if you decide that you're fine to use the first line of the verbatim
+block to set the standard for indentation of the rest of the block, you can
+look at the first line and return the appropriate value, like so:
+
+ $new->strip_verbatim_indent(sub {
+ my $lines = shift;
+ (my $indent = $lines->[0]) =~ s/\S.*//;
+ return $indent;
+ });
+
+If you'd rather treat each line individually, you can do that, too, by just
+transforming them in-place in the code reference and returning C<undef>. Say
+that you don't want I<any> lines indented. You can do something like this:
+
+ $new->strip_verbatim_indent(sub {
+ my $lines = shift;
+ sub { s/^\s+// for @{ $lines },
+ return undef;
+ });
+
=back
-
=head1 CAVEATS
This is just a beta release -- there are a good number of things still
Index: ChangeLog
===================================================================
--- ChangeLog (revision 371)
+++ ChangeLog (working copy)
@@ -7,6 +7,7 @@
Add support for an index (TOC) in the XHTML output from David E.
Wheeler.
+ Add strip_verbatim_indent() from David E. Wheeler.
2009-07-16 Allison Randal <allison@perl.org>
* Release 3.08