package cf::pod;
use Pod::POM;
our $indent;
our $level;
our @result;
package cf::pod::AsParagraphs;
use strict;
use base "Pod::POM::View";
sub asxml($) {
local $_ = $_[0];
s/&/&/g;
s/>/>/g;
s/</g;
$_
}
sub flatten($) {
local $_ = $_[0];
s/<[^>]+>//g;
s/^\s+//;
s/\s+$//;
s/\s+/ /g;
$_
}
*view_seq_file =
*view_seq_code =
*view_seq_bold = sub { "$_[1]" };
*view_seq_italic = sub { "$_[1]" };
*view_seq_zero = sub { };
*view_seq_space = sub { my $text = $_[1]; $text =~ s/ /\xa0/g; $text };
*view_seq_index = sub { push @{ $result[-1]{index} }, $_[1]; "" };
sub view_seq_text {
my $text = $_[1];
$text =~ s/\s+/ /g;
asxml $text
}
sub view_seq_link {
my (undef, $link) = @_;
my $text = $link =~ s/^(.*)\|// ? $1 : $link;
if ($link =~ /http:/) {
"" . (asxml $link) . ""
} else {
()
}
}
sub view_item {
push @result, {
type => "item",
indent => $indent * 8,
level => $level,
};
my $title = $_[1]->title->present ($_[0]);
$result[-1]{markup} = $title if length $title;
$title = flatten $title; unshift @{ $result[-1]{index} }, $title if length $title;
local $level = $level + 1;
$_[1]->content->present ($_[0]);
()
}
sub view_verbatim {
push @result, {
type => "verbatim",
indent => $indent * 16,
level => $level,
markup => asxml $_[1],
};
()
}
sub view_textblock {
push @result, {
indent => $indent * 16,
level => $level,
markup => flatten $_[1],
};
()
}
sub view_head1 {
push @result, {
type => "head1",
indent => $indent * 16,
level => $level,
};
my $title = $_[1]->title->present ($_[0]);
$result[-1]{markup} = $title if length $title;
$title = flatten $title; unshift @{ $result[-1]{index} }, $title if length $title;
local $level = $level + 1;
$_[1]->content->present ($_[0]);
()
};
sub view_head2 {
push @result, {
type => "head2",
indent => $indent * 16,
level => $level,
};
my $title = $_[1]->title->present ($_[0]);
$result[-1]{markup} = $title if length $title;
$title = flatten $title; unshift @{ $result[-1]{index} }, $title if length $title;
local $level = $level + 1;
$_[1]->content->present ($_[0]);
()
};
sub view_head3 {
push @result, {
type => "head3",
indent => $indent * 16,
level => $level,
};
my $title = $_[1]->title->present ($_[0]);
$result[-1]{markup} = $title if length $title;
$title = flatten $title; unshift @{ $result[-1]{index} }, $title if length $title;
local $level = $level + 1;
$_[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,
# level => $level,
# markup => (::special image => "pod/" . $_->text),
# };
}
()
}
sub view_begin {
()
}
sub view {
my ($self, $type, $item) = @_;
$item->content->present ($self);
}
#############################################################################
package cf::pod;
sub pom_as_paragraphs($) {
my ($pom) = @_;
# we suckers use global variables, unfortunately.
my $guard = cf::lock_acquire "cf::pod::as_paragraphs";
local $indent = 0;
local $level = 1;
local @result = ( { } );
$pom->present ("cf::pod::AsParagraphs");
[grep $_->{index} || exists $_->{markup}, @result]
}
sub load_pod($) {
my ($path) = @_;
Coro::Storable::thaw cf::cache "cf::pod::as_paragraphs/$path" => [$path],
2 => sub {
my ($src) = @_;
cf::fork_call {
my $pod = $src->[0];
utf8::decode $pod;
Coro::Storable::blocking_nfreeze pom_as_paragraphs +(Pod::POM->new->parse_text ($pod))
}
};
}
# format as cfpod-style text
sub as_cfpod($) {
my ($pars) = @_;
my $res;
for my $par (@$pars) {
if ($par->{type} =~ /^head\d+$/) {
$res .= "B<$par->{markup}>\n\n";
} elsif ($par->{type} eq "verbatim") {
$res .= "\n$par->{markup}\n\n";
} elsif ($par->{type} eq "item") {
$res .= "\n* I<$par->{markup}>\n\n";
} else {
$res .= "$par->{markup}\n\n";
}
}
$res
}
1;