Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Perl 6, how do I keep a module's pod at the bottom of a file while still using declarator blocks to document method/subs?

Tags:

raku

Let's say I have the following module:

module Simple-Mod;

#| Calculate the nth fibonacci number.
multi fib( 0 ) { 1 }
multi fib( 1 ) { 1 }
multi fib( Int $n where * > 1 ) {
    fib($n - 2 ) + fib($n - 1);
}

#| Say hello to  a person.
sub hello( $person ) { say "Hello, $person!" }

=begin pod
=head1 SYNOPSIS

A really simple module.

=head1 Example
=begin code
use Simple-Mod;

say fib(3);    #=> 2
hello("Gina"); #=> Hello, Gina!

=end code

=head1 Subroutines

=end pod

At the moment, when I extract the Pod from this module, I obtain this:

sub fib(
        Int $ where { ... }, 
)
Calculate the nth fibonacci number.

sub hello(
        $person, 
)
Say hello to a person.

SYNOPSIS

A really simple module.

Example

    use Simple-Mod;

    say fib(3);    #=> 2
    hello("Gina"); #=> Hello, Gina!

Subroutines

Is it possible to instruct the Pod parsing process to place the subroutine definitions and comments after the Subroutines header? Like this:

SYNOPSIS

A really simple module.

Example

    use Simple-Mod;

    say fib(3);    #=> 2
    hello("Gina"); #=> Hello, Gina!

Subroutines

sub fib(
        Int $ where { ... }, 
)
Calculate the nth fibonacci number.

sub hello(
        $person, 
)
Say hello to a person.

I could probably place everything from the =begin pod to the =head1 Subroutines (followed by =end pod) directive at the top of file and then the usual code with the declarator blocks. However I'd like to keep all the Pod at the bottom of the file if possible.

like image 224
Luis F. Uceta Avatar asked Dec 23 '18 19:12

Luis F. Uceta


1 Answers

By tinkering with the Pod::To::Text module, I came up a somewhat hackish solution that is far from robust. It solely depends on a new subroutine and some changes to the render, pod2text and heading2text routines:

unit class Pod::To::Textx;

my $top-pod = Any;
method render($pod, Bool $declarator-displacement = False) {
    $top-pod = $pod if $declarator-displacement;
    pod2text($pod)
}


sub pod2text($pod) is export {
     # other code

     when Pod::Block::Declarator { if $top-pod { succeed        } 
                                   else { declarator2text($pod) }
                                  }
     # remaining code
 }


sub add-code-info($pod) {
    return pod2text($pod.contents) unless $top-pod;

    if $pod.contents.head.contents.lc.contains("routines") {
        pod2text($pod.contents) ~ 
        @($top-pod).grep({ $_ ~~ Pod::Block::Declarator })
                   .map({ "\n\n" ~ declarator2text($_)  })
    }
}

sub heading2text($pod) {
    given $pod.level {
        when 1  {          add-code-info($pod)      }
        when 2  { '  '   ~ pod2text($pod.contents)  }
        default { '    ' ~ pod2text($pod.contents)  }
    }
 }

 # rest of code

To render the Pod in a .p6 file and place the declarator blocks underneath a heading level 1 titled Subroutines/Routines, use:

 use Pod::To::Textx;

 say Text.new().render($=pod, True);

inside the file.

like image 131
Luis F. Uceta Avatar answered Nov 06 '22 11:11

Luis F. Uceta