NAME

Sub::Spec::To::Org - Generate Org documentation from sub spec

VERSION

version 0.003

SYNOPSIS

use Sub::Spec::To::Org qw(spec_to_org);
my $org = spec_to_org(spec => $spec,
                      # other options
                     );

DESCRIPTION

NOTICE: This module and the Sub::Spec standard is deprecated as of Jan 2012. Rinci is the new specification to replace Sub::Spec, it is about 95% compatible with Sub::Spec, but corrects a few issues and is more generic. Perinci::* is the Perl implementation for Rinci and many of its modules can handle existing Sub::Spec sub specs.

EARLY RELEASE. NO IMPLEMENTATION YET!

This module can generate Org document from sub spec.

This module uses Log::Any logging framework.

$pod .= "=head2 $sub_spec->{name}(\%args) -> ".
    ($naked ? "RESULT" : "[STATUS_CODE, ERR_MSG, RESULT]")."\n\n";

if ($sub_spec->{summary}) {
    $pod .= "$sub_spec->{summary}.\n\n";
}

my $desc = $sub_spec->{description};
if ($desc) {
    $desc =~ s/^\n+//; $desc =~ s/\n+$//;
    $pod .= "$desc\n\n";
}

if ($naked) {

} else {
    $pod .= <<'_';
Returns a 3-element arrayref. STATUS_CODE is 200 on success, or an error code
between 3xx-5xx (just like in HTTP). ERR_MSG is a string containing error
message, RESULT is the actual result.

_ }

my $features = $sub_spec->{features} // {};
if ($features->{reverse}) {
    $pod .= <<'_';
This function supports reverse operation. To reverse, add argument C<-reverse>
=> 1.

_ } if ($features->{undo}) { $pod .= <<'_'; This function supports undo operation. See Sub::Spec::Clause::features for details on how to perform do/undo/redo.

_ } if ($features->{dry_run}) { $pod .= <<'_'; This function supports dry-run (simulation) mode. To run in dry-run mode, add argument -dry_run => 1.

_ } if ($features->{pure}) { $pod .= <<'_'; This function is declared as pure, meaning it does not change any external state or have any side effects.

_ }

my $args  = $sub_spec->{args} // {};
$args = { map {$_ => _parse_schema($args->{$_})} keys %$args };
my $has_cat = grep { $_->{clause_sets}[0]{arg_category} }
    values %$args;

if (scalar keys %$args) {
    my $noted_star_req;
    my $prev_cat;
    for my $name (sort {
        (($args->{$a}{clause_sets}[0]{arg_category} // "") cmp
             ($args->{$b}{clause_sets}[0]{arg_category} // "")) ||
                 (($args->{$a}{clause_sets}[0]{arg_pos} // 9999) <=>
                      ($args->{$b}{clause_sets}[0]{arg_pos} // 9999)) ||
                          ($a cmp $b) } keys %$args) {
        my $arg = $args->{$name};
        my $ah0 = $arg->{clause_sets}[0];

        my $cat = $ah0->{arg_category} // "";
        if (!defined($prev_cat) || $prev_cat ne $cat) {
            $pod .= "=back\n\n" if defined($prev_cat);
            $pod .= ($cat ? ucfirst("$cat arguments") :
                         ($has_cat ? "General arguments":"Arguments"));
            $pod .= " (C<*> denotes required arguments)"
                unless $noted_star_req++;
            $pod .= ":\n\n=over 4\n\n";
            $prev_cat = $cat;
        }

        $pod .= "=item * B<$name>".($ah0->{req} ? "*" : "")." => ";
        my $type;
        if ($arg->{type} eq 'any') {
            my @schemas = map {_parse_schema($_)} @{$ah0->{of}};
            my @types   = map {$_->{type}} @schemas;
            @types      = sort List::MoreUtils::uniq(@types);
            $type       = join("|", @types);
        } else {
            $type       = $arg->{type};
        }
        $pod .= "I<$type>";
        $pod .= " (default ".
            (defined($ah0->{default}) ?
                 "C<".Data::Dump::Partial::dumpp($ah0->{default}).">"
                     : "none").
                         ")"
                           if defined($ah0->{default});
        $pod .= "\n\n";

        my $aliases = $ah0->{arg_aliases};
        if ($aliases && keys %$aliases) {
            $pod .= "Aliases: ";
            my $i = 0;
            for my $al (sort keys %$aliases) {
                $pod .= ", " if $i++;
                my $alinfo = $aliases->{$al};
                $pod .= "B<$al>".
                    ($alinfo->{summary} ? " ($alinfo->{summary})" : "");
            }
            $pod .= "\n\n";
        }

        $pod .= "Value must be one of:\n\n".
            join("", map {" $_\n"} split /\n/,
                 Data::Dump::dump($ah0->{in}))."\n\n"
                       if defined($ah0->{in});

        #my $o = $ah0->{arg_pos};
        #my $g = $ah0->{arg_greedy};

        $pod .= "$ah0->{summary}.\n\n" if $ah0->{summary};

        my $desc = $ah0->{description};
        if ($desc) {
            $desc =~ s/^\n+//; $desc =~ s/\n+$//;
            # XXX format/rewrap
            $pod .= "$desc\n\n";
        }
    }
    $pod .= "=back\n\n";

} else {

    $pod .= "No known arguments at this time.\n\n";

}

FUNCTIONS

None of the functions are exported by default, but they are exportable.

spec_to_org(%args) -> RESULT

Generate Org documentation from sub spec.

Arguments (* denotes required arguments):

  • spec* => hash

SEE ALSO

Sub::Spec

Other Sub::Spec::To::* modules.

AUTHOR

Steven Haryanto <stevenharyanto@gmail.com>

COPYRIGHT AND LICENSE

This software is copyright (c) 2012 by Steven Haryanto.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.