10

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.

uzluisf
  • 2,586
  • 1
  • 9
  • 27
  • Perhaps [my answer to another SO question: "Don't show declarator blocks with p6doc"](https://stackoverflow.com/questions/50983870/dont-show-declarator-blocks-with-p6doc/50991656#50991656), in particular the bit about `perl6 --doc=MyFilter.pm6`, and "a search of modules.perl6.org for pod::to", is of interest. – raiph Dec 24 '18 at 01:59
  • You can put your pod wherever you want. Is there some reason why you want to keep it at the bottom of a file? – jjmerelo Dec 24 '18 at 08:05
  • @raiph So what I gather from your another SO answer is that I should create my own filter to achieve the task at hand? – uzluisf Dec 24 '18 at 17:35
  • @jjmerelo It's likely a matter of personal preference. However by placing the pod at the bottom, the information (e.g. routines's signatures and documentations) gathered from the declarator blocks is misplaced. – uzluisf Dec 24 '18 at 17:42
  • @uzlxxx You could write a new filter. But perhaps one of the existing filters can easily be made to do what you want? Perhaps the two *default* filters (see my other SO answer) can? (Thinking ahead... I daresay others would like to put pod at the bottom. So if you *do* end up with a solution, it would presumably be nice if you made a Pull Request to make that solution available out of the box for everyone, whether that change is just a new paragraph of doc, or some code. And presumably the ideal solution would be that the default filters did it *automatically* if that's reasonable.) – raiph Dec 25 '18 at 11:03
  • 1
    @raiph I've edited my question and added the little code I came up with. It's quite specific since it just targets a `head1` containing the word "routines" but I'm sure it could be improved on. – uzluisf Dec 26 '18 at 20:57
  • 1
    @uzlxxx Awesome. :) Maybe someone will come up with something more robust at a later date but right now it seems you've done the work to sufficiently solve your original problem. Btw it's perfectly acceptable on SO to answer your own question. So consider cutting the edit out of your question and pasting it into an answer. If you do so, maybe add a bit of commentary (maybe just copy your "It's quite specific ... improved on." sentence above). If you do, I'll have the pleasure of giving your answer an upvote to go with the one for the question. Either way, welcome to SO and happy holidays. :) – raiph Dec 27 '18 at 00:15

1 Answers1

2

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.

uzluisf
  • 2,586
  • 1
  • 9
  • 27