unit class Pod::To::Text; method render($pod) { pod2text($pod) } my &colored = sub ($text, $) {$text } if %*ENV { (try require Terminal::ANSIColor <&colored>) !=== Nil and &OUTER::colored = &colored }; sub pod2text($pod) is export { given $pod { when Pod::Heading { heading2text($pod) } when Pod::Block::Code { code2text($pod) } when Pod::Block::Named { named2text($pod) } when Pod::Block::Para { para2text($pod) } when Pod::Block::Table { table2text($pod) } when Pod::Block::Declarator { declarator2text($pod) } when Pod::Item { item2text($pod) } when Pod::Defn { pod2text($pod.term) ~ "\n" ~ pod2text($pod.contents) } when Pod::FormattingCode { formatting2text($pod) } when Positional { .flatĀ».&pod2text.grep(?*).join: "\n\n" } when Pod::Block::Comment { '' } when Pod::Config { '' } default { $pod.Str } } } sub heading2text($pod) { given $pod.level { when 1 { pod2text($pod.contents) } when 2 { ' ' ~ pod2text($pod.contents) } default { ' ' ~ pod2text($pod.contents) } } } sub code2text($pod) { $pod.contents>>.&pod2text.join.indent(4) } sub item2text($pod) { ('* ' ~ pod2text($pod.contents).chomp.chomp).indent(2 * $pod.level) } sub named2text($pod) { given $pod.name { when 'pod' { pod2text($pod.contents) } when 'para' { pod2text($pod.contents) } when 'config' { } when 'nested' { pod2text($pod.contents).indent(4) } default { $pod.name ~ "\n" ~ pod2text($pod.contents) } } } sub para2text($pod) { twrap( $pod.contents.map({pod2text($_)}).join("") ) } sub table2text($pod) { my @rows = $pod.contents; @rows.unshift($pod.headers.item) if $pod.headers; my @maxes; my $cols = [max] @rows.map({ .elems }); for ^$cols -> $i { @maxes.push([max] @rows.map({ $i < $_ ?? $_[$i].chars !! 0 })); } @maxes[*-1] = 0; # Don't pad last column with spaces my $ret; if $pod.config { $ret = $pod.config ~ "\n" } for @rows -> $row { # Gutter of two spaces between columns $ret ~= ' ' ~ join ' ', (@maxes Z=> @$row).map: { .value.fmt("%-{.key}s") }; $ret ~= "\n"; } $ret } sub declarator2text($pod) { next unless $pod.WHEREFORE.WHY; my $what = do given $pod.WHEREFORE { when Method { my @params = $_.signature.params.skip; @params.pop if @params.tail.name eq '%_'; 'method ' ~ $_.name ~ signature2text(@params, $_.returns) } when Sub { 'sub ' ~ $_.name ~ signature2text($_.signature.params, $_.returns) } when Attribute { 'attribute ' ~ $_.gist } when .HOW ~~ Metamodel::EnumHOW { "enum $_.raku() { signature2text $_.enums.pairs } \n" } when .HOW ~~ Metamodel::ClassHOW { 'class ' ~ $_.raku } when .HOW ~~ Metamodel::ModuleHOW { 'module ' ~ $_.raku } when .HOW ~~ Metamodel::SubsetHOW { 'subset ' ~ $_.raku ~ ' of ' ~ $_.^refinee().raku } when .HOW ~~ Metamodel::PackageHOW { 'package ' ~ $_.raku } default { '' } } "$what\n{$pod.WHEREFORE.WHY.contents}" } sub signature2text($params, Mu $returns?) { my $result = '('; if $params.elems { $result ~= "\n\t" ~ $params.map(¶m2text).join("\n\t") } unless $returns<> =:= Mu { $result ~= "\n\t--> " ~ $returns.raku } if $result.chars > 1 { $result ~= "\n"; } $result ~= ')'; return $result; } sub param2text($p) { $p.raku ~ ',' ~ ( $p.WHY ?? ' # ' ~ $p.WHY !! ' ') } my %formats = C => "bold", L => "underline", D => "underline", R => "inverse" ; sub formatting2text($pod) { my $text = $pod.contents>>.&pod2text.join; $pod.type ~~ %formats ?? colored($text, %formats{$pod.type}) !! $text } sub twine2text($_) { .map({ when Pod::Block { twine2text .contents }; .&pod2text }).join } sub twrap($text is copy, :$wrap=75 ) { $text ~~ s:g/(. ** {$wrap} <[\s]>*)\s+/$0\n/; $text } # vim: expandtab shiftwidth=4