Perinci-Sub-To-CLIDocData

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

    Perinci::Sub::To::CLIDocData - From Rinci function metadata, generate
    structure convenient for producing CLI documentation (help/usage/POD)

VERSION
    This document describes version 0.305 of Perinci::Sub::To::CLIDocData
    (from Perl distribution Perinci-Sub-To-CLIDocData), released on
    2022-11-14.

SYNOPSIS
     use Perinci::Sub::To::CLIDocData qw(gen_cli_doc_data_from_meta);
     my $clidocdata = gen_cli_doc_data_from_meta(meta => $meta);

    Sample function metadata ($meta):

     {
       args => {
         bool1 => {
                    cmdline_aliases => { z => { summary => "This is summary for option `-z`" } },
                    schema => "bool",
                    summary => "Another bool option",
                    tags => ["category:cat1"],

lib/Perinci/Sub/To/CLIDocData.pm  view on Meta::CPAN

        Perinci::Sub::GetArgs::Argv::gen_getopt_long_spec_from_meta(
            meta=>$meta, meta_is_normalized=>1, common_opts=>$common_opts,
            per_arg_json => $args{per_arg_json},
            per_arg_yaml => $args{per_arg_yaml},
        );
    };
    $ggls_res->[0] == 200 or return $ggls_res;

    my $langprop_args = {lang=>$lang, mark_different_lang=>$mark_different_lang};
    my $args_prop = $meta->{args} // {};
    my $clidocdata = {
        option_categories => {},
        example_categories => {},
    };

    # a mapping from arg spec keys to %opts keys, so we can create a POD link
    # from a positional argument in usage line to option, later when generating
    # usage line
    my %arg_spec_to_opts;

    # a mapping from keys in func.specmeta (ospec) to %opts keys, so we can

lib/Perinci/Sub/To/CLIDocData.pm  view on Meta::CPAN

                    $opt->{$_} = $arg_spec->{$_} if defined $arg_spec->{$_};
                }

                {
                    # we don't want argument options to end up in "Other" like
                    # --help or -v, they are put at the end. so if an argument
                    # option does not have category, we'll put it in the "main"
                    # category.
                    local $arg_spec->{tags} = ['category0:main']
                        if !$arg_spec->{tags} || !@{$arg_spec->{tags}};
                    _add_category_from_spec($clidocdata->{option_categories},
                                            $opt, $arg_spec, "options", 1);
                }
                _add_default_from_arg_spec($opt, $arg_spec);

            } else {
                # option from common_opts

                my $spec = $common_opts->{$ospec->{common_opt}};

                # for bool, only display either the positive (e.g. --bool)

lib/Perinci/Sub/To/CLIDocData.pm  view on Meta::CPAN

                        $rimeta->langprop($langprop_args, 'summary.alt.bool.not') :
                            $rimeta->langprop($langprop_args, 'summary'),
                    (schema => $spec->{schema}) x !!$spec->{schema},
                    ('x.schema.entity' => $spec->{'x.schema.entity'}) x !!$spec->{'x.schema.entity'},
                    ('x.schema.element_entity' => $spec->{'x.schema.element_entity'}) x !!$spec->{'x.schema.element_entity'},
                    description =>
                        $rimeta->langprop($langprop_args, 'description'),
                    (default => $spec->{default}) x !!(exists($spec->{default}) && !$show_neg),
                };

                _add_category_from_spec($clidocdata->{option_categories},
                                        $opt, $spec, "options", 1);

            }

            $opts{$optkey} = $opt;
            $arg_spec_to_opts{ $ospec->{arg} } = $optkey if $ospec->{arg};
            $ospec_to_opts{$k} = $optkey;
        } # while @k

        # link ungrouped alias to its main opt

lib/Perinci/Sub/To/CLIDocData.pm  view on Meta::CPAN

                next if $arg_opt->{is_alias} || $arg_opt->{is_base64} ||
                    $arg_opt->{is_json} || $arg_opt->{is_yaml};
                next unless defined($arg_opt->{arg}) &&
                    $arg_opt->{arg} eq $opt->{arg};
                $opt->{main_opt} = $k2;
                next OPT1;
            }
        }

    } # GEN_LIST_OF_OPTIONS
    $clidocdata->{opts} = \%opts;

    #use DDC; dd \%arg_spec_to_opts;
    #use DDC; dd \%ospec_to_opts;

  GEN_USAGE_LINE: {
        my @plain_args;
        my @pod_args;

        my %args_prop = %$args_prop; # copy because we want to iterate & delete
        my $max_pos = -1;

lib/Perinci/Sub/To/CLIDocData.pm  view on Meta::CPAN

            $key =~ s/_/-/g;

            #say "D:ospec=$ospec -> key=$key, ospecmeta->{arg}=$ospecmeta->{arg}";

            $opt_locations{$key} //= scalar @plain_opts;
            push @{ $plain_opts[ $opt_locations{$key} ] }, $plain_opt;
            push @{ $pod_opts  [ $opt_locations{$key} ] }, $pod_opt;
            #use Data::Dmp; print "key: $key, ospec: $ospec, ospecmeta: ", dmp($ospecmeta), ", argprop: ", dmp($argprop), ", copt: ", dmp($copt), "\n";
        }

        $clidocdata->{compact_usage_line} = "[[prog]]".
            (keys(%args_prop) || keys(%$common_opts) ? " [options]" : ""). # XXX translatable?
            (@plain_args ? " ".join(" ", @plain_args) : "");
        $clidocdata->{usage_line} = "[[prog]]".
            (@plain_opts+@plain_args ? " ".
             join(" ",
                  (map { "[". join("|", @$_) . "]" } @plain_opts),
                  (@plain_opts && @plain_args ? ("--") : ()),
                  @plain_args,
              ) : "");
        $clidocdata->{'usage_line.alt.fmt.pod'} = "B<[[prog]]>".
            (@pod_opts+@pod_args ? " ".
             join(" ",
                  (map { "[". join("|", @$_) . "]" } @pod_opts),
                  (@pod_opts && @pod_args ? ("--") : ()),
                  @pod_args,
              ) : "");
    } # GEN_USAGE_LINE

    # filter and format examples
    my @examples;

lib/Perinci/Sub/To/CLIDocData.pm  view on Meta::CPAN

                    $cmdline .= " $qarg"; # XXX markup with color?
                }
            }
            my $egdata = {
                cmdline      => $cmdline,
                summary      => $rimeta->langprop($langprop_args, 'summary'),
                description  => $rimeta->langprop($langprop_args, 'description'),
                example_spec => $eg,
            };
            # XXX show result from $eg
            _add_category_from_spec($clidocdata->{example_categories},
                                    $egdata, $eg, "examples", $has_cats);
            push @examples, $egdata;
        }
    }
    $clidocdata->{examples} = \@examples;

    [200, "OK", $clidocdata];
}

1;
# ABSTRACT: From Rinci function metadata, generate structure convenient for producing CLI documentation (help/usage/POD)

__END__

=pod

=encoding UTF-8

lib/Perinci/Sub/To/CLIDocData.pm  view on Meta::CPAN


Perinci::Sub::To::CLIDocData - From Rinci function metadata, generate structure convenient for producing CLI documentation (help/usage/POD)

=head1 VERSION

This document describes version 0.305 of Perinci::Sub::To::CLIDocData (from Perl distribution Perinci-Sub-To-CLIDocData), released on 2022-11-14.

=head1 SYNOPSIS

 use Perinci::Sub::To::CLIDocData qw(gen_cli_doc_data_from_meta);
 my $clidocdata = gen_cli_doc_data_from_meta(meta => $meta);

Sample function metadata (C<$meta>):

 {
   args => {
     bool1 => {
                cmdline_aliases => { z => { summary => "This is summary for option `-z`" } },
                schema => "bool",
                summary => "Another bool option",
                tags => ["category:cat1"],



( run in 0.347 second using v1.01-cache-2.11-cpan-454fe037f31 )