Raku / user-experience

Identifying issues in and improving the Raku user experience
Artistic License 2.0
25 stars 5 forks source link

Pod::To::Xxxx options processing support #47

Closed dwarring closed 2 years ago

dwarring commented 2 years ago

I'm wanting to support options processing in some Pod rendering modules, such as:

raku --doc=PDF my.pod --/index  --save-as=my.pdf

As far as I can work out the options are available in @*ARGS.

But I can't see any Rakuish way of processing the arguments.

-- @*ARGS-TO-CAPTURE has limited scope and isn't available here

-- I can't see anything on the ecosystem (GetOpt::Long seems Perlish, wont handle '--/index')

Could Raku's built-in option parsing somehow be better made available to Pod renders?

dwarring commented 2 years ago

Here's a short example, that demonstrates current behavior:

unit class Pod::To::Raku;

method render($pod, Int :$foo=42, Bool :$bar = True) {
    warn %( :$foo, :$bar, args => @*ARGS ).raku;
    warn $pod.raku.substr(0, 10) ~ '...';
}

when run with: raku --doc=Raku lib/Pod/To/PDF/Lite.rakumod --foo=12 --/bar, outputs:

 {:args($["--foo=12", "--/bar"]), :bar(Bool::True), :foo(42)}
  in method render at /tmp/lib/Pod/To/Raku.rakumod (Pod::To::Raku) line 4
$[Pod::Blo...
  in method render at /tmp/lib/Pod/To/Raku.rakumod (Pod::To::Raku) line 5
tbrowder commented 2 years ago

Hi, David. I personally don't think that's the way to go. For arg handling, I think it's better to write one's own driver program and handle args with either the sub MAIN way or one's own arg handler (which I prefer).

Altai-man commented 2 years ago

Agreed, writing a generic driver as a module/bin sounds like a good idea, it doesn't involve increasing of Rakudo's complexity.

finanalyst commented 2 years ago

First thing. The $pod variable is receiving an array of POD6 trees that are associated with the program processed by raku. This is all that is needed. The renderer then transforms the pod trees into some output form. Rakudo assumes that when you call raku --doc=XXX there is a distribution that provides a class Pod::To::XXXX and that class has a method render. Second: Beware !! There is a bug in Rakudo, so that the render method is called twice. The workaround is to have some sort of state variable to track when render is called first, returning the rendered content, and then on the second time just return the rendered content.

Third, I have written a general renderer which uses templates. It also allows for custom headers and custom FormattingCodes. For example, I have included a block =graphviz that generates a png from the dot description of a graph.

So, rather then working out how to deal with every Pod Block that might occur and generating pdf, you could write the templates for pdf output.

This might be easier because things like =item for lists and =defn take some thinking about.

dwarring commented 2 years ago

Thanks all. I'm using custom parsing, as suggested by Tom:

 for @*ARGS {
            when /^'--page-numbers'$/  { $page-numbers = True }
            when /^'--width='(\d+)$/   { $width  = $0.Int }
            when /^'--height='(\d+)$/  { $height = $0.Int }
            when /^'--save-as='(.+)$/  { $pdf-file = $0.Str }
            default { note "ignoring $_ argument" }
        }