File: pod2pandoc.pm

package info (click to toggle)
libpod-pandoc-perl 0.5.0-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 248 kB
  • sloc: perl: 587; makefile: 5
file content (179 lines) | stat: -rw-r--r-- 4,725 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package App::pod2pandoc;
use strict;
use warnings;
use 5.010;

our $VERSION = '0.3.2';

use Getopt::Long qw(:config pass_through);
use Pod::Usage;
use Pod::Simple::Pandoc;
use Pandoc;
use Pandoc::Elements;
use Scalar::Util qw(reftype blessed);
use JSON;
use Carp;

use parent 'Exporter';
our @EXPORT    = qw(pod2pandoc);
our @EXPORT_OK = qw(pod2pandoc parse_arguments);

sub parse_arguments {
    my %opt;
    Getopt::Long::GetOptionsFromArray(
        \@_,       \%opt,            'help|h|?', 'version',
        'parse=s', 'podurl=s',       'ext=s',    'index=s',
        'wiki',    'default-meta=s', 'update',   'quiet',
        'name',
    ) or exit 1;
    pod2usage(1) if $opt{help};
    if ( $opt{version} ) {
        say "$0 $VERSION";
        exit 0;
    }

    my @input = @_ ? () : '-';

    my ($index) = grep { $_[$_] eq '--' } ( 0 .. @_ - 1 );

    if ( defined $index ) {
        push @input, shift @_ for 0 .. $index - 1;
        shift @_;    # --
    }
    else {
        push( @input, shift @_ ) while @_ and $_[0] !~ /^-./;
    }

    if ( $opt{parse} and $opt{parse} ne '*' ) {
        $opt{parse} = [ split /[, ]+/, $opt{parse} ];
    }

    return ( \@input, \%opt, @_ );
}

# TODO: move to Pandoc::Elements
sub _add_default_meta {
    my ( $doc, $meta ) = @_;
    return unless $meta;
    $doc->meta->{$_} //= $meta->{$_} for keys %$meta;
}

sub _default_meta {
    my $meta = shift || {};
    return $meta if ref $meta;

    # read default metadata from file
    if ( $meta =~ /\.json$/ ) {
        open( my $fh, "<:encoding(UTF-8)", $meta )
          or croak "failed to open $meta";
        local $/;
        $meta = decode_json(<$fh>);
        for ( keys %$meta ) {
            $meta->{$_} = metadata( $meta->{$_} );
        }
        return $meta;
    }
    else {
        pandoc->require('1.12.1');
        return pandoc->file($meta)->meta;
    }
}

sub pod2pandoc {
    my $input = shift;
    my $opt   = ref $_[0] ? shift : {};
    my @args  = @_;

    $opt->{meta} =
      _default_meta( $opt->{meta} // delete $opt->{'default-meta'} );

    # directories
    if ( @$input > 0 and -d $input->[0] ) {
        my $target = @$input > 1 ? pop @$input : $input->[0];

        my $modules = Pod::Pandoc::Modules->new;
        foreach my $dir (@$input) {
            my $found = Pod::Simple::Pandoc->new->parse_modules($dir);
            warn "no .pm, .pod or Perl script found in $dir\n"
              unless %$found or $opt->{quiet};
            $modules->add( $_ => $found->{$_} ) for keys %$found;
        }

        _add_default_meta( $modules->{$_}, $opt->{meta} ) for %$modules;

        $modules->serialize( $target, $opt, @args );
    }

    # files and/or module names
    else {
        my $parser = Pod::Simple::Pandoc->new(%$opt);
        my $doc = $parser->parse_and_merge( @$input ? @$input : '-' );

        _add_default_meta( $doc, $opt->{meta} );

        if (@args) {
            pandoc->require('1.12.1');
            $doc->pandoc_version( pandoc->version );
            print $doc->to_pandoc(@args);
        }
        else {
            print $doc->to_json, "\n";
        }
    }
}

1;
__END__

=head1 NAME

App::pod2pandoc - implements pod2pandoc command line script

=head1 SYNOPSIS

  use App::pod2pandoc;

  # pod2pandoc command line script
  my ($input, $opt, @args) = parse_arguments(@ARGV);
  pod2pandoc($input, $opt, @args);

  # parse a Perl/Pod file and print its JSON serialization
  pod2pandoc( ['example.pl'], {} );

  # parse a Perl/Pod file and convert to HTML with a template
  pod2pandoc( ['example.pl'], {}, '--template', 'template.html' );

  # process directory of Perl modules
  pod2pandoc( [ lib => 'doc'], { ext => 'html' }, '--standalone' );

=head1 DESCRIPTION

This module implements the command line script L<pod2pandoc>.

=head1 FUNCTIONS

=head2 pod2pandoc( \@input, [ \%options, ] \@arguments )

Processed input files with given L<pod2pandoc> options (C<data-sections>,
C<podurl>, C<ext>, C<wiki>, C<meta>, C<update>, and C<quiet>) .  Additional
arguments are passed to C<pandoc> executable via module L<Pandoc>.

Input can be either files and/or module names or directories to recursively
search for C<.pm> and C<.pod> files. If no input is specified, Pod is read from
STDIN. When processing directories, the last input directory is used as output
directory.

This function is exported by default.

=head2 parse_arguments( @argv )

Parses options and input arguments from given command line arguments. May
terminate the program with message, for instance with argument C<--help>.

=head1 SEE ALSO

This module is part of L<Pod::Pandoc> and based on the modules
L<Pod::Simple::Pandoc>, L<Pod::Pandoc::Modules>, L<Pandoc::Element> and
L<Pandoc>.

=cut