File Coverage

lib/Template/Plugin/Latex.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             #============================================================= -*-perl-*-
2             #
3             # Template::Plugin::Latex
4             #
5             # $Id:$
6             #
7             # DESCRIPTION
8             # Template Toolkit plugin for Latex
9             #
10             # AUTHOR
11             # Andrew Ford <a.ford@ford-mason.co.uk> (current maintainer)
12             # Andy Wardley <abw@wardley.org> (original author)
13             #
14             # COPYRIGHT
15             # Copyright (C) 2006-2007 Andrew Ford. All Rights Reserved.
16             # Copyright (C) 1996-2006 Andy Wardley. All Rights Reserved.
17             #
18             # This module is free software; you can redistribute it and/or
19             # modify it under the same terms as Perl itself.
20             #
21             # HISTORY
22             # * Originally written by Craig Barratt, Apr 28 2001.
23             # * Win32 additions by Richard Tietjen.
24             # * Extracted into a separate Template::Plugin::Latex module by
25             # Andy Wardley, 27 May 2006
26             # * Removed the program pathname options on the FILTER call
27             # Andrew Ford, 05 June 2006
28             # * Totally rewritten by Andrew Ford September 2007
29             # * Version 3.00 released March 2009
30             #
31             #========================================================================
32              
33             package Template::Plugin::Latex;
34              
35 4     4   90610 use strict;
  4         10  
  4         147  
36 4     4   23 use warnings;
  4         7  
  4         114  
37 4     4   20 use base 'Template::Plugin';
  4         8  
  4         43529  
38              
39 4     4   4082 use File::Spec;
  4         9  
  4         103  
40 4     4   4346 use LaTeX::Driver 0.07;
  0            
  0            
41             use LaTeX::Encode;
42             use LaTeX::Table;
43              
44              
45             our $VERSION = 3.06; # Update "=head1 VERSION" below!!!!
46             our $DEBUG; $DEBUG = 0 unless defined $DEBUG;
47             our $ERROR = '';
48             our $FILTER = 'latex';
49             our $THROW = 'latex'; # exception type
50              
51             #------------------------------------------------------------------------
52             # constructor
53             #
54             #------------------------------------------------------------------------
55              
56             sub new {
57             my ($class, $context, $options) = @_;
58              
59             # make sure that $options is a hash ref
60             $options ||= {};
61              
62             # create a closure to generate filters with additional options
63             my $filter_factory = sub {
64             my $factory_context = shift;
65             my $filter_opts = ref $_[-1] eq 'HASH' ? pop : { };
66             my $filter_args = [ @_ ];
67             @$filter_opts{ keys %$options } = values %$options;
68             return sub {
69             # Template::Plugin::Latex::_filter->run($context, $filter_opts, $filter_args, @_);
70             _tt_latex_filter($class, $factory_context, $filter_opts, $filter_args, @_);
71             };
72             };
73              
74             # create a closure to generate filters with additional options
75             my $encode_filter_factory = sub {
76             my $factory_context = shift;
77             my $filter_opts = ref $_[-1] eq 'HASH' ? pop : { };
78             my $filter_args = [ @_ ];
79             @$filter_opts{ keys %$options } = values %$options;
80             return sub {
81             # Template::Plugin::Latex::_filter->run($context, $filter_opts, $filter_args, @_);
82             _tt_latex_encode_filter($class, $factory_context, $filter_opts, $filter_args, @_);
83             };
84             };
85              
86             # and a closure to represent the plugin
87             my $plugin = sub {
88             my $plugopt = ref $_[-1] eq 'HASH' ? pop : { };
89             @$plugopt{ keys %$options } = values %$options;
90             # Template::Plugin::Latex::_filter->run($context, $plugopt, @_ );
91             _tt_latex_filter($class, $context, $plugopt, {}, @_ );
92             };
93              
94              
95             # now define the filter and return the plugin
96             $context->define_filter('latex_encode', [ $encode_filter_factory => 1 ]);
97             $context->define_filter($options->{filter} || $FILTER, [ $filter_factory => 1 ]);
98              
99             return bless $plugin, $class;
100             }
101              
102              
103             #------------------------------------------------------------------------
104             # _tt_latex_encode_filter
105             #
106             #
107             #------------------------------------------------------------------------
108              
109             sub _tt_latex_encode_filter {
110             my ($class, $context, $options, $filter_args, @text) = @_;
111             my $text = join('', @text);
112             return latex_encode($text, %{$options});
113             }
114              
115              
116             #------------------------------------------------------------------------
117             # _tt_latex_filter
118             #
119             #
120             #------------------------------------------------------------------------
121              
122             sub _tt_latex_filter {
123             my ($class, $context, $options, $filter_args, @text) = @_;
124             my $text = join('', @text);
125              
126             # Get the output and format options
127              
128             # my $output = $options->{output};
129             my $output = delete $options->{ output } || shift(@$filter_args) || '';
130             my $format = $options->{format};
131              
132             # If the output is just a format specifier then set the format to
133             # that and undef the output
134              
135             if ($output =~ /^ (?: dvi | ps | pdf(?:\(\w+\))? ) $/x) {
136             ($format, $output) = ($output, undef);
137             }
138              
139             # If the output is a filename then convert to a full pathname in
140             # the OUTPUT_PATH directory, outherwise set the output to a
141             # reference to a temporary variable.
142              
143             if ($output) {
144             my $path = $context->config->{ OUTPUT_PATH }
145             or $class->_throw('OUTPUT_PATH is not set');
146             $output = File::Spec->catfile($path, $output);
147             }
148             else {
149             my $temp;
150             $output = \$temp;
151             }
152              
153             # Run the formatter
154              
155             eval {
156             my $drv = LaTeX::Driver->new( source => \$text,
157             output => $output,
158             format => $format,
159             maxruns => $options->{maxruns},
160             extraruns => $options->{extraruns},
161             texinputs => _setup_texinput_paths($context),
162             );
163             $drv->run;
164             };
165             if (my $e = LaTeX::Driver::Exception->caught()) {
166             $class->_throw("$e");
167             }
168              
169             # Return the text if it was output to a scalar variable, otherwise
170             # return nothing.
171              
172             return ref $output ? $$output : '';
173             }
174              
175              
176             #------------------------------------------------------------------------
177             # $self->setup_texinput_paths
178             #
179             # setup the TEXINPUT path environment variables
180             #------------------------------------------------------------------------
181              
182             sub _setup_texinput_paths {
183             my ($context) = @_;
184             my $template_name = $context->stash->get('template.name');
185             my $include_path = $context->config->{INCLUDE_PATH} || [];
186             $include_path = [ $include_path ] unless ref $include_path;
187              
188             my @texinput_paths = ("");
189             foreach my $path (@$include_path) {
190             my $template_path = File::Spec->catfile($path, $template_name);
191             if (-f $template_path) {
192             my($volume, $dir) = File::Spec->splitpath($template_path);
193             $dir = File::Spec->catfile($volume, $dir);
194             unshift @texinput_paths, $dir;
195             next if $dir eq $path;
196             }
197             push @texinput_paths, $path;
198             }
199             return \@texinput_paths;
200             }
201              
202              
203             sub _throw {
204             my $self = shift;
205             die Template::Exception->new( $THROW => join('', @_) );
206             }
207              
208              
209             sub table {
210             my $args = ref($_[-1]) eq 'HASH' ? pop(@_) : { };
211             my ($table, $text);
212             eval {
213             $table = LaTeX::Table->new($args);
214             $text = $table->generate_string;
215             };
216             if ($@) {
217             die Template::Exception->new( $THROW => $@ );
218             }
219             return $text;
220             }
221              
222              
223             1;
224              
225             __END__
226              
227             =head1 NAME
228              
229             Template::Plugin::Latex - Template Toolkit plugin for Latex
230              
231             =head1 VERSION
232              
233             This documentation refers to C<Template::Plugin::Latex> version 3.06
234              
235             =head1 SYNOPSIS
236              
237             Sample Template Toolkit code:
238              
239             [%- USE Latex;
240              
241             mystr = "a, b & c" | latex_encode;
242              
243             FILTER latex("pdf"); -%]
244              
245             \documentclass{article}
246             \begin{document}
247             This is a PDF document generated by
248             LaTeX and the Template Toolkit, with some
249             interpolated data: [% mystr %]
250             \end{document}
251              
252             [% END; -%]
253              
254              
255             =head1 DESCRIPTION
256              
257             The C<Latex> Template Toolkit plugin provides a C<latex> filter that
258             allows the use of LaTeX to generate PDF, PostScript and DVI output files
259             from the Template Toolkit. The plugin uses L<LaTeX::Driver> to run the
260             various LaTeX programs.
261              
262             Processing of the LaTeX document takes place in a temporary directory
263             that is deleted once processing is complete. The standard LaTeX
264             programs (C<latex> or C<pdflatex>, C<bibtex> and C<makeindex>) are run
265             and re-run as necessary until all references, indexes, bibliographies,
266             table of contents, and lists of figures and tables are stable or it is
267             apparent that they will not stabilize. The format converters C<dvips>,
268             C<dvipdf>, C<ps2pdf> and C<pdf2ps> are run as necessary to convert the
269             output document to the requested format. The C<TEXINPUTS> environment
270             variable is set up to include the template directory and the C<INCLUDES>
271             directories, so that LaTeX file inclusion commands should find the
272             intended files.
273              
274             The output of the filter is binary data (although PDF and PostScript are
275             not stictly binary). You should be careful not to prepend or append any
276             extraneous characters (even space characters) or text outside the FILTER
277             block as this text will be included in the file output. Notice in the
278             example below how we use the post-chomp flags ('-') at the end of the
279             C<USE> and C<END> directives to remove the trailing newline characters:
280              
281             [% USE Latex(format='pdf') -%]
282             [% FILTER latex %]
283             ...LaTeX document...
284             [% END -%]
285              
286             If you're redirecting the output to a file via the third argument of
287             the Template module's C<process()> method then you should also pass
288             the C<binmode> parameter, set to a true value to indicate that it is a
289             binary file.
290              
291             use Template;
292              
293             my $tt = Template->new({
294             INCLUDE_PATH => '/path/to/templates',
295             OUTPUT_PATH => '/path/to/pdf/output',
296             });
297             my $vars = {
298             title => 'Hello World',
299             }
300             $tt->process('example.tt2', $vars, 'example.pdf', binmode => 1)
301             || die $tt->error();
302              
303             If you want to capture the output to a template variable, you can do
304             so like this:
305              
306             [% output = FILTER latex %]
307             ...LaTeX document...
308             [% END %]
309              
310             You can pass additional arguments when you invoke the filter, for
311             example to specify the output format.
312              
313             [% FILTER latex(format='pdf') -%]
314             ...LaTeX document...
315             [% END %]
316              
317             If you want to write the output to a file then you can specify an
318             C<output> parameter.
319              
320             [% FILTER latex(output='example.pdf') %]
321             ...LaTeX document...
322             [% END %]
323              
324             If you don't explicity specify an output format then the filename
325             extension (e.g. 'pdf' in the above example) will be used to determine
326             the correct format.
327              
328             You can specify a different filter name using the C<filter> parameter.
329              
330             [% USE Latex(filter='pdf') -%]
331             [% FILTER pdf %]
332             ...LaTeX document...
333             [% END %]
334              
335             You can also specify the default output format. This value can be
336             C<latex>, C<pdf> or C<dvi>.
337              
338             [% USE Latex(format='pdf') %]
339              
340              
341             Note: the C<LaTeX::Driver> distribution includes three filter programs
342             (C<latex2dvi>, C<latex2pdf> and C<latex2ps>) that use the
343             C<LaTeX::Driver> package to process LaTeX source data into DVI, PDF or
344             PostScript file respectively. These programs have a C<-tt2> option to
345             run their input through the Template Toolkit before processing as LaTeX
346             source. The programs do not use the C<Latex> plugin unless the template
347             requests it, but they may provide an alternative way of processing
348             Template Toolkit templates to generate typeset output.
349              
350              
351             =head1 SUBROUTINES/METHODS
352              
353             =head2 C<USE Latex(options)>
354              
355             This statement loads the plugin (note that prior to version 2.15 the
356             filter was built in to Template Toolkit so this statement was
357             unnecessary; it is now required).
358              
359              
360             =head2 The C<latex> Filter
361              
362             The C<latex> filter accepts a number of options, which may be
363             specified on the USE statement or on the filter invocation.
364              
365             =over 4
366              
367             =item C<format>
368              
369             specifies the format of the output; one of C<dvi> (TeX device
370             independent format), C<ps> (PostScript) or C<pdf> (Adobe Portable
371             Document Format). The follow special values are also accepted:
372             C<pdf(ps)> (generates PDF via PostScript, using C<dvips> and
373             C<ps2pdf>), C<pdf(dvi)> (generates PDF via dvi, using C<dvipdfm>)
374              
375             =item C<output>
376              
377             the name of the output file, or just the output format
378              
379             =item C<indexstyle>
380              
381             the name of the C<makeindex> style file to use (this is passed with
382             the C<-s> option to C<makeindex>)
383              
384             =item C<indexoptions>
385              
386             options to be passed to C<makeindex>. Useful options are C<-l> for
387             letter ordering of index terms (rather than the default word
388             ordering), C<-r> to disable implicit page range formation, and C<-c>
389             to compress intermediate blanks in index keys. Refer to L<makeindex(1)>
390             for full details.
391              
392             =item C<maxruns>
393              
394             The maximum number of runs of the formatter program (defaults to 10).
395              
396             =item C<extraruns>
397              
398             The number of additional runs of the formatter program after it seems
399             that the formatting of the document has stabilized (default 0). Note
400             that the setting of C<maxruns> takes precedence, so if C<maxruns> is
401             set to 10 and C<extraruns> is set to 3, and formatting stabilizes
402             after 8 runs then only 2 extra runs will be performed.
403              
404             =back
405              
406              
407             =head2 The C<latex_encode> filter
408              
409             The C<latex_encode> filter encodes LaTeX special characters in its
410             input into their LaTeX encoded representations. It also encodes other characters that have
411              
412             The special characters are: C<\> (command character), C<{> (open
413             group), C<}> (end group), C<&> (table column separator), C<#>
414             (parameter specifier), C<%> (comment character), C<_> (subscript),
415             C<^> (superscript), C<~> (non-breakable space), C<$> (mathematics mode).
416              
417              
418             =over 4
419              
420             =item C<except>
421              
422             Lists the characters that should be excluded from encoding. By
423             default no special characters are excluded, but it may be useful to
424             specify C<except = "\\{}"> to allow the input string to contain LaTeX
425             commands such as C<"this is \textbf{bold} text">.
426              
427             =item C<use_textcomp>
428              
429             By default the C<latex_encode> filter will encode characters with the
430             encodings provided by the C<textcomp> LaTeX package (for example the
431             Pounds Sterling symbol is encoded as C<\textsterling{}>). Setting
432             C<use_textcomp = 0> turns off these encodings.
433              
434             =back
435              
436             =head2 C<table()>
437              
438             The C<table()> function provides an interface to the C<LaTeX::Table> module.
439              
440             The following example shows how a simple table can be set up.
441              
442             [%- USE Latex;
443              
444             data = [ [ 'London', 'United Kingdom' ],
445             [ 'Berlin', 'Germany' ],
446             [ 'Paris', 'France' ],
447             [ 'Washington', 'USA' ] ] );
448              
449             text = Latex.table( caption = 'Capitol Cities',
450             label = 'table:capitols',
451             headings = [ [ 'City', 'Country' ] ],
452             data = data );
453             -%]
454              
455             The variable C<text> will hold the LaTeX commands to typeset the table
456             and can be further interpolated into a LaTeX document template.
457              
458             =head1 DIAGNOSTICS
459              
460             Most failures result from invalid LaTeX input and are propogated up from
461             L<LaTeX::Driver>, L<LaTeX::Encode> or L<LaTeX::Table>.
462              
463             Failures detected in this module include:
464              
465             =over 4
466              
467             =item C<OUTPUT_PATH is not set>
468              
469             an output filename was specified but the C<OUTPUT_PATH> configuration
470             option has not been set.
471              
472             =back
473              
474              
475             =head1 DEPENDENCIES
476              
477             =over 4
478              
479             =item L<Template>
480              
481             The Template Toolkit.
482              
483             =item L<LaTeX::Driver>
484              
485             Provides the logic for driving the LaTeX programs.
486              
487             =item L<LaTeX::Encode>
488              
489             Underpins the C<latex_encode> filter.
490              
491             =item L<LaTeX::Table>
492              
493             Underpins the C<table> function.
494              
495             =back
496              
497              
498             =head1 INCOMPATIBILITIES
499              
500             The C<latex> filter was distributed as part of the core
501             Template Toolkit distribution until version 2.15 (released in May 2006),
502             when it was moved into the separate Template-Latex distribution. The
503             C<Latex> plugin must now be explicity to enable the C<latex> filter.
504              
505              
506             =head1 BUGS AND LIMITATIONS
507              
508             The paths to the F<latex>, F<pdflatex> and F<dvips> should be
509             pre-defined as part of the installation process of L<LaTeX::Driver>
510             (i.e. when you run C<perl Makefile.PL> for that package). Alternative
511             values can be specified from Perl code using the C<program_path> class
512             method from that package, but there are deliberately no options to
513             specify these paths from TT code.
514              
515              
516             =head1 AUTHOR
517              
518             Andrew Ford E<lt>a.ford@ford-mason.co.ukE<gt> (current maintainer)
519              
520             Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
521              
522             The original Latex plugin on which this is based was written by Craig
523             Barratt with additions for Win32 by Richard Tietjen. The code has
524             subsequently been radically refactored by Andrew Ford.
525              
526             =head1 LICENSE AND COPYRIGHT
527              
528             Copyright (C) 2006-2009 Andrew Ford. All Rights Reserved.
529              
530             Copyright (C) 1996-2006 Andy Wardley. All Rights Reserved.
531              
532             This module is free software; you can redistribute it and/or
533             modify it under the same terms as Perl itself.
534              
535             This software is distributed in the hope that it will be useful, but
536             WITHOUT ANY WARRANTY; without even the implied warranty of
537             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
538              
539             =head1 SEE ALSO
540              
541             L<Template>, L<LaTeX::Driver>, L<LaTeX::Table>, L<LaTeX::Encode>
542              
543              
544             L<latex2dvi(1)>, L<latex2pdf(1)> and L<latex2ps(1)> (part of the
545             C<LaTeX::Driver> distribution)
546              
547             =cut
548              
549              
550             # Local Variables:
551             # mode: perl
552             # perl-indent-level: 4
553             # indent-tabs-mode: nil
554             # End:
555             #
556             # vim: expandtab shiftwidth=4: