Permalink
Browse files

Eliminate nested tags in XHTML TOC items.

Thanks to Ben Bullock for the test case. I did not use his solution, though.
Instead, cache header text separately from body text, and use the text-only
output in the TOC and its IDs. This also eliminates other elements from the
TOC, such as the `<b>` elements seen in `t/xhtml10.t`, which I think makes for
more consistent TOC output in general.

Closes #31.
  • Loading branch information...
1 parent 5cb92a1 commit 29306b765cc859f139655c34528e9b510a0452d9 @theory committed Jun 9, 2012
Showing with 24 additions and 16 deletions.
  1. +8 −0 ChangeLog
  2. +13 −10 lib/Pod/Simple/XHTML.pm
  3. +1 −4 t/xhtml-bkb.t
  4. +2 −2 t/xhtml10.t
View
8 ChangeLog
@@ -1,6 +1,14 @@
# ChangeLog for Pod::Simple dist
#---------------------------------------------------------------------------
+ * Release 3.22
+
+ Eliminated nested elements in table of contents (index) items
+ output of Pod::Simple::XHTML. This was especially problematic for
+ headers that included links, as the TOC then got nested anchor
+ elements, which simply would not work. Thanks to Ben Bullock for
+ the report and test case (RT #77686).
+
2012-05-27 David E. Wheeler <david@justatheory.org>
* Release 3.22
View
23 lib/Pod/Simple/XHTML.pm
@@ -336,9 +336,12 @@ sub handle_text {
return $_[0]->handle_code( $_[1] );
}
# escape special characters in HTML (<, >, &, etc)
- $_[0]{'scratch'} .= $_[0]->__in_literal_xhtml_region
- ? $_[1]
- : $_[0]->encode_entities( $_[1] );
+ my $text = $_[0]->__in_literal_xhtml_region
+ ? $_[1]
+ : $_[0]->encode_entities( $_[1] );
+
+ $_[0]{'scratch'} .= $text;
+ $_[0]{htext} .= $text if $_[0]{'in_head'};
}
sub handle_code {
@@ -348,10 +351,10 @@ sub handle_code {
sub start_Para { $_[0]{'scratch'} = '<p>' }
sub start_Verbatim { $_[0]{'scratch'} = '<pre>'; $_[0]{'in_code'} = 1; }
-sub start_head1 { $_[0]{'in_head'} = 1 }
-sub start_head2 { $_[0]{'in_head'} = 2 }
-sub start_head3 { $_[0]{'in_head'} = 3 }
-sub start_head4 { $_[0]{'in_head'} = 4 }
+sub start_head1 { $_[0]{'in_head'} = 1; $_[0]{htext} = ''; }
+sub start_head2 { $_[0]{'in_head'} = 2; $_[0]{htext} = ''; }
+sub start_head3 { $_[0]{'in_head'} = 3; $_[0]{htext} = ''; }
+sub start_head4 { $_[0]{'in_head'} = 4; $_[0]{htext} = ''; }
sub start_item_number {
$_[0]{'scratch'} = "</li>\n" if ($_[0]{'in_li'}->[-1] && pop @{$_[0]{'in_li'}});
@@ -421,14 +424,14 @@ sub _end_head {
$add = 1 unless defined $add;
$h += $add - 1;
- my $id = $_[0]->idify($_[0]{scratch});
+ my $id = $_[0]->idify($_[0]{htext});
my $text = $_[0]{scratch};
- $_[0]{'scratch'} = $_[0]->backlink && ($h - $add == 0)
+ $_[0]{'scratch'} = $_[0]->backlink && ($h - $add == 0)
# backlinks enabled && =head1
? qq{<a href="#_podtop_"><h$h id="$id">$text</h$h></a>}
: qq{<h$h id="$id">$text</h$h>};
$_[0]->emit;
- push @{ $_[0]{'to_index'} }, [$h, $id, $text];
+ push @{ $_[0]{'to_index'} }, [$h, $id, delete $_[0]{'htext'}];
}
sub end_head1 { shift->_end_head(@_); }
View
5 t/xhtml-bkb.t
@@ -18,7 +18,4 @@ $d->index (1);
my $e;
$d->output_string (\$e);
$d->parse_string_document ($c);
-TODO: {
- local $TODO = 'See bug report';
- unlike ($e, qr!<a[^>]+><a[^>]+>!);
-};
+unlike ($e, qr!<a[^>]+><a[^>]+>!);
View
4 t/xhtml10.t
@@ -74,8 +74,8 @@ ok $parser->parse_string_document( "=head1 Foo B<Bar>\n\n=head1 Foo B<Baz>" ),
'Parse two multiword headers';
is $results, <<'EOF', 'Should have the index';
<ul id="index">
- <li><a href="#Foo-Bar">Foo <b>Bar</b></a></li>
- <li><a href="#Foo-Baz">Foo <b>Baz</b></a></li>
+ <li><a href="#Foo-Bar">Foo Bar</a></li>
+ <li><a href="#Foo-Baz">Foo Baz</a></li>
</ul>
<h1 id="Foo-Bar">Foo <b>Bar</b></h1>

0 comments on commit 29306b7

Please sign in to comment.