File Coverage

blib/lib/Template/Provider/Pandoc.pm
Criterion Covered Total %
statement 20 23 86.9
branch n/a
condition n/a
subroutine 7 10 70.0
pod n/a
total 27 33 81.8


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Template::Provider::Pandoc - pre-process templates with Pandoc
4              
5             =head1 SYNOPSIS
6              
7             use Template;
8             use Template::Provider::Pandoc;
9              
10             my $tt = Template->new(
11             LOAD_TEMPLATES => [ Template::Provider::Pandoc->new ],
12             );
13              
14             $tt->process('template.md', \%vars)
15              
16             =head1 DESCRIPTION
17              
18             Template::Provider::Pandoc is an extension to the Template Toolkit
19             which automatically processes templates using Pandoc before they are
20             processed by TT.
21              
22             =head1 USAGE
23              
24             Like any Template provider module, you will usually use this module by
25             creating an instance of the object and passing that in the
26             C<LOAD_TEMPLATES> parameter to the Template module's C<new> method.
27              
28             This module accepts all of the standard parameters that can be passed
29             to any Template provider module. See L<Template::Provider> for the full
30             list.
31              
32             This module accepts three extra parameters, C<EXTENSIONS>, which defines the
33             file extensions that is used to identify files that require conversion,
34             C<OUTPUT_FORMAT> which defines the the format that template will be converted
35             into and C<STRIP_FRONT_MATTER> which will remove Jekyll-style front matter
36             from the file content before returning it.
37              
38             C<EXTENSIONS> is a hash reference. The default is to only handle Markdown
39             files (which are identified by the extension .md). You can get a full list
40             of the allowed input formats by running
41              
42             $ pandoc --list-input-formats
43              
44             at a command line.
45              
46             The C<EXTENSIONS> option supports one special option. If you use `*` as
47             an extenstion, then files with any extension will be converted using the
48             supplied format. So code like:
49              
50             my $provider = Template::Provider::Pandoc(
51             EXTENSIONS => { '*' => 'markdown' },
52             );
53              
54             will lead to all files being pre-processed as Markdown files before being
55             handed to the Template Toolkit.
56              
57             C<OUTPUT_FORMAT> is a single, scalar value containing the name of an output
58             format. The default value is C<html>. You can get a full list of the
59             allowed putput values by running
60              
61             $ pandoc --list-output-values
62              
63             at a command line.
64              
65             C<STRIP_FRONT_MATTER> is a flag that is either true or false. The default
66             value is false. If it is true then this module will remove any Jekyll-style
67             front matter from the file contents before returning them.
68              
69             Jekyll-style front matter is a format used by Jekyll and other, similar,
70             static site builders. It is a fragmant of YAML that is inserted at the top
71             of the file between two lines that consist only of three dashes, like this:
72              
73             ---
74             title: Title of the page
75             author: Joe Author
76             tags:
77             - list
78             - of
79             -tags
80             ---
81              
82             The current implementation doesn't check that the front matter is actually
83             YAML. It simply removes everything from the first line of dashes to the
84             second.
85              
86             =head1 Template::Provider::Markdown::Pandoc
87              
88             This module is a successor to Template::Provider::Markdown::Pandoc. This
89             replacement module has all the functionality of the older module, and a lot
90             more besides. And, as a bonus, it has a shorter name!
91              
92             =cut
93              
94             package Template::Provider::Pandoc;
95              
96 3     3   131837 use strict;
  3         8  
  3         104  
97 3     3   11 use warnings;
  3         5  
  3         157  
98 3     3   59 use 5.010;
  3         11  
99              
100 3     3   1653 use Moose;
  3         1515725  
  3         24  
101 3     3   27364 use MooseX::NonMoose;
  3         3667  
  3         13  
102             extends 'Template::Provider';
103              
104 3     3   216429 use Pandoc ();
  3         160748  
  3         1776  
105              
106             our $VERSION = '0.1.1';
107              
108             has pandoc => (
109             isa => 'Pandoc',
110             is => 'ro',
111             lazy_build => 1,
112             handles => [qw[convert]],
113             );
114              
115             sub _build_pandoc {
116 0     0     return Pandoc->new;
117             }
118              
119             has default_extensions => (
120             isa => 'HashRef',
121             is => 'ro',
122             lazy_build => 1,
123             );
124              
125             sub _build_default_extensions {
126             return {
127 0     0     md => 'markdown',
128             };
129             }
130              
131             has default_output_format => (
132             isa => 'Str',
133             is => 'ro',
134             lazy_build => 1,
135             );
136              
137             sub _build_default_output_format {
138 0     0     return 'html';
139             }
140              
141             before _init => sub {
142             my $self = shift;
143             my ($opts) = @_;
144              
145             my $exts = $self->default_extensions;
146              
147             if (exists $opts->{EXTENSIONS}) {
148             $exts->{$_} = $opts->{EXTENSIONS}{$_} for keys %{$opts->{EXTENSIONS}};
149             delete $opts->{EXTENSIONS};
150             }
151              
152             $self->{EXTENSIONS} = $exts;
153              
154             $self->{OUTPUT_FORMAT} =
155             $opts->{OUTPUT_FORMAT} // $self->default_output_format;
156              
157             $self->{STRIP_FRONT_MATTER} = $opts->{STRIP_FRONT_MATTER} // 0;
158             };
159              
160             around _template_content => sub {
161             my $orig = shift;
162             my $self = shift;
163             my ($path) = @_;
164              
165             my ($data, $error, $mod_date) = $self->$orig(@_);
166              
167             if ($self->{STRIP_FRONT_MATTER}) {
168             $data =~ s/\A---\n.+?\n---\n//s;
169             }
170              
171             my $done = 0;
172              
173             for (keys %{$self->{EXTENSIONS}}) {
174             next if $_ eq '*';
175             if ($path =~ /\.\Q$_\E$/) {
176             if (defined $self->{EXTENSIONS}{$_}) {
177             $data = $self->convert(
178             $self->{EXTENSIONS}{$_} => $self->{OUTPUT_FORMAT}, $data
179             );
180             }
181             $done = 1;
182             last;
183             }
184             }
185              
186             if (not $done and exists $self->{EXTENSIONS}{'*'}) {
187             $data = $self->convert(
188             $self->{EXTENSIONS}{'*'} => $self->{OUTPUT_FORMAT}, $data
189             );
190             }
191              
192             return ($data, $error, $mod_date) if wantarray;
193             return $data;
194             };
195              
196 3     3   36 no Moose;
  3         7  
  3         31  
197             # no need to fiddle with inline_constructor here
198             __PACKAGE__->meta->make_immutable;
199              
200             1;
201              
202             =head1 AUTHOR
203              
204             Dave Cross E<lt>dave@perlhacks.comE<gt>
205              
206             =head1 COPYRIGHT
207              
208             Copyright (c) 2017 Magnum Solutions Ltd. All rights reserved.
209              
210             This module is free software; you can redistribute it and/or
211             modify it under the same terms as Perl itself.
212              
213             =head1 SEE ALSO
214              
215             L<Template>, L<Template::Provider>, L<Pandoc>.
216              
217             =cut