App-sdview
view release on metacpan or search on metacpan
lib/App/sdview/Parser/Man.pm view on Meta::CPAN
package App::sdview::Parser::Man 0.20;
class App::sdview::Parser::Man :strict(params);
apply App::sdview::Parser;
use Sublike::Extended 0.29 'sub';
use Parse::Man::DOM 0.03;
use String::Tagged;
use constant sort_order => 30;
sub find_file ( $class, $name )
{
open my $f, "-|", "man", "--path", $name;
my $file = <$f>; chomp $file if defined $file;
close $f;
$? == 0 or return undef;
return $file;
}
sub can_parse_file ( $class, $file )
{
return $file =~ m/\.[0-9](pm)?(\.gz)?/n;
}
field @_paragraphs;
method parse_file ( $fh )
{
return $self->_parse( Parse::Man::DOM->new->from_file( $fh ) );
}
method parse_string ( $str )
{
return $self->_parse( Parse::Man::DOM->new->from_string( $str ) );
}
method _parse ( $dom )
{
# Not much we can do with the meta sections
@_paragraphs = ();
foreach my $para ( $dom->paras ) {
my $type = $para->type;
if( my $code = $self->can( "_handle_$type" ) ) {
$self->$code( $para );
}
else {
print STDERR "TODO: para->type = $type\n";
}
}
return @_paragraphs;
}
my %FONTTAGS = (
B => { bold => 1 },
I => { italic => 1 },
CW => { monospace => 1 },
);
sub _chunklist_to_taggedstring ( $chunks, :$linefeed = " " )
{
my $ret = String::Tagged->new;
foreach my $chunk ( $chunks->@* ) {
my %tags;
my $font = $chunk->font // "";
%tags = $FONTTAGS{$font}->%* if $FONTTAGS{$font};
my $text = $chunk->text;
$text = "\n" if $chunk->is_space;
$text = $linefeed if $chunk->is_linebreak;
$text = "\n\n" if $chunk->is_break;
$ret->append_tagged( $text, %tags );
}
# Trim trailing space
$ret =~ m/([ \n]+)$/ and
$ret->set_substr( $-[1], $+[1]-$-[1], "" );
return $ret;
}
method _handle_heading ( $para )
{
push @_paragraphs, App::sdview::Para::Heading->new(
level => $para->level,
text => String::Tagged->new( $para->text ),
);
}
method _handle_plain ( $para )
{
push @_paragraphs, App::sdview::Para::Plain->new(
text => _chunklist_to_taggedstring( [ $para->body->chunks ] ),
indent => $para->indent,
);
}
method _handle_term ( $para )
{
my $list;
if( @_paragraphs and $_paragraphs[-1]->type eq "list-text" ) {
$list = $_paragraphs[-1];
}
else {
push @_paragraphs, $list = App::sdview::Para::List->new(
listtype => "text",
indent => 4,
);
}
$list->push_item(
App::sdview::Para::ListItem->new(
( run in 0.539 second using v1.01-cache-2.11-cpan-39bf76dae61 )