package CFClient::Pod; use strict; use Pod::POM; use CFClient; use CFClient::UI; our $VERSION = 1; # bump if resultant formatting changes our @result; our $indent; package CFClient::Pod::AsXML; use strict; use base "Pod::POM::View::Text"; *view_seq_code = *view_seq_bold = sub { "$_[1]" }; *view_seq_italic = sub { "$_[1]" }; *view_seq_space = *view_seq_link = *view_seq_index = sub { CFClient::asxml $_[1] }; sub view_seq_text { my $text = $_[1]; $text =~ s/\s+/ /g; CFClient::asxml $text } sub view_item { ("\t" x ($indent / 4)) . $_[1]->title->present ($_[0]) . "\n\n" . $_[1]->content->present ($_[0]) } sub view_verbatim { (join "", map +("\t" x ($indent / 2)) . "$_\n", split /\n/, CFClient::asxml $_[1]) . "\n" } sub view_textblock { ("\t" x ($indent / 2)) . "$_[1]\n\n" } sub view_head1 { "\n\n" . $_[1]->title->present ($_[0]) . "\n\n" . $_[1]->content->present ($_[0]) }; sub view_head2 { "\n" . $_[1]->title->present ($_[0]) . "\n\n" . $_[1]->content->present ($_[0]) }; sub view_head3 { "\n" . $_[1]->title->present ($_[0]) . "\n\n" . $_[1]->content->present ($_[0]) }; sub view_over { local $indent = $indent + $_[1]->indent; $_[1]->content->present ($_[0]) } package CFClient::Pod::AsParagraphs; use strict; use base "Pod::POM::View"; *view_seq_code = *view_seq_bold = sub { "$_[1]" }; *view_seq_italic = sub { "$_[1]" }; *view_seq_space = *view_seq_link = *view_seq_index = sub { CFClient::asxml $_[1] }; sub view_seq_text { my $text = $_[1]; $text =~ s/\s+/ /g; CFClient::asxml $text } sub view_item { push @result, { indent => $indent * 8, text => $_[1]->title->present ($_[0]) . "\n\n", }; $_[1]->content->present ($_[0]); () } sub view_verbatim { push @result, { indent => $indent * 16, text => "" . (CFClient::asxml $_[1]) . "", }; () } sub view_textblock { push @result, { indent => $indent * 16, text => "$_[1]\n", }; () } sub view_head1 { push @result, { indent => $indent * 16, text => "\n\n" . $_[1]->title->present ($_[0]) . "\n", }; $_[1]->content->present ($_[0]); () }; sub view_head2 { push @result, { indent => $indent * 16, text => "\n\n" . $_[1]->title->present ($_[0]) . "\n", }; $_[1]->content->present ($_[0]); () }; sub view_head3 { push @result, { indent => $indent * 16, text => "\n\n" . $_[1]->title->present ($_[0]) . "\n", }; $_[1]->content->present ($_[0]); () }; sub view_over { local $indent = $indent + $_[1]->indent; push @result, { indent => $indent }; $_[1]->content->present ($_[0]); () } sub view_for { if ($_[1]->format eq "image") { push @result, { indent => $indent * 16, text => "\x{fffc}", obj => [new CFClient::UI::Image path => "pod/" . $_[1]->text], }; } () } sub view { my ($self, $type, $item) = @_; $item->content->present ($self); } package CFClient::Pod; my $pod_cache = CFClient::db_table "pod_cache"; sub load($$$$) { my ($path, $filtertype, $filterversion, $filtercb) = @_; stat $path or die "$path: $!"; my $phash = join ",", $filterversion, $VERSION, (stat _)[7,9]; my ($chash, $pom) = eval { @{ Storable::thaw $pod_cache->get ("$path/$filtertype") } }; return $pom if $chash eq $phash; my $pod = do { local $/; open my $pod, "<:utf8", $_[0] or die "$_[0]: $!"; <$pod> }; #utf8::downgrade $pod; $pom = $filtercb->(Pod::POM->new->parse_text ($pod)); $pod_cache->put ("$path/$filtertype" => Storable::nfreeze [$phash, $pom]); $pom } sub as_xml($) { my ($pom) = @_; local $indent = 0; $pom->present ("CFClient::Pod::AsXML") } sub as_paragraphs($) { my ($pom) = @_; local @result = ( { } ); local $indent = 0; $pom->present ("CFClient::Pod::AsParagraphs"); [grep exists $_->{text}, @result] }