Template-Plugin-Latex-3.02/0000755000175000017500000000000011156274541015050 5ustar andrewandrewTemplate-Plugin-Latex-3.02/MANIFEST0000644000175000017500000000132110705227610016170 0ustar andrewandrewMANIFEST This list of files README General information, installation, etc. INSTALL Changes TODO Makefile.PL lib/Template/Latex.pm lib/Template/Plugin/Latex.pm t/README t/00-latex.t t/01-latex2dvi.t t/02-latex2pdf.t t/03-latex2ps.t t/10-output.t t/11-plugin-errors.t t/12-template.t t/13-latex-encode.t t/20-references.t t/21-includes.t t/22-tableofcontents.t t/23-makeindex.t t/24-bibliography.t t/input/bibfiles/testbib.bib t/input/deeply/nested/directory/testinc2.tex t/input/testinc.tex t/input/testrefs.dvi t/input/testrefs.tex t/lib/Template/Test/Latex.pm t/output/README texinputs/tt2.sty META.yml Module meta-data (added by MakeMaker) Template-Plugin-Latex-3.02/texinputs/0000755000175000017500000000000011156274540017112 5ustar andrewandrewTemplate-Plugin-Latex-3.02/texinputs/tt2.sty0000644000175000000130000000175210705227610017152 0ustar andrew%\iffalse \NeedsTeXFormat{LaTeX2e}[1994/12/01} \ProvidesPackage{tt2} %\fi % \title{The \textsf{tt2} package} % \author{\copyright\ 2007, Andrew Ford} % \maketitle % % \section{Overview} % % This package defines a single command, |\TTCODE|, which can be used % to identify Template Toolkit (TT2) code in a template LaTeX file. % % \section{|\TTCODE| command} % % The |\TTCODE| command is used to wrap Template Toolkit code. % % When run from the Template Toolkit LaTeX plugin the command % |\TTLATEX| is defined; in this case we define |\TTCODE| as a no-op, % taking no arguments -- the TT code will get evaluated by TT and we % typset the resulting text. % % If |\TTLATEX| is not defined then we define |\TTCODE| as a macro % taking one argument -- the TT code -- which we set in a small % typewriter font. % % \begin{macrocode} \expandafter\ifx\csname TTLATEX\endcsname\relax \newcommand{\TTCODE}[1]{\texttt{\small #1}} \else \newcommand{\TTCODE}{} \fi % \end{macrocode} % % \Finale % \endinput Template-Plugin-Latex-3.02/TODO0000644000175000000130000000401510705227610014320 0ustar andrew#================================================== -*- indented-text -*- # # TODO # # DESCRIPTION # TODO list for the Template Latex plugin version 3.x, containing # known bugs, limitations, planned enhancements, long term visions # and a few whacky ideas. # # AUTHOR # Andrew Ford # #------------------------------------------------------------------------ # $Id: TODO 83 2007-10-12 23:48:30Z ford $ #======================================================================== #------------------------------------------------------------------------ # Miscellaneous #------------------------------------------------------------------------ * check the mechanism whereby latex (or pdflatex) is re-run if the document contains undefined references after the first run. Bibtex is re-run if undefined citations are reported by latex, and makeindex is run if the driver detects a ".idx" file. If bibtex or makeindex are run then latex (or pdflatex) are run up to three more times to allow forward references to stabilize. This should all be coped with now but need to check on edge cases * look at how path variables could be specified to the filter (TEXINPUTS, TEXINPUTS_latex, TEXINPUTS_pdflatex, BIBINPUTS, etc), and how these should interact with the system paths. * get the filter working on Win32 how does one set environment variables with command.exe? * write unit tests for error conditions (invalid .bib file, etc) * provide a facility for specifying pre- and post-processors, e.g. gnuplot, metapost, tpic or other graphics processors. May need to copy data files from the source location to the temporary directory. * benchmark the filter Note that the latex filter runs up to eight external programs, so it isn't very fast. But for modest documents the performance is adequate, even for interactive applications. * expand the documentation * review the security implications of allowing templates to specify program paths for latex, pdflatex and dvips. * add examples Template-Plugin-Latex-3.02/t/0000755000175000017500000000000011156274541015313 5ustar andrewandrewTemplate-Plugin-Latex-3.02/t/input/0000755000175000017500000000000011156274541016452 5ustar andrewandrewTemplate-Plugin-Latex-3.02/t/input/testinc.tex0000644000175000000130000000003010705227604017421 0ustar andrewThis is included text. Template-Plugin-Latex-3.02/t/input/testrefs.tex0000644000175000000130000000043010705227604017613 0ustar andrew\documentclass{article} \begin{document} \section{Introduction} Including a file. \include{testinc} % use \input on nested directory rather than \include, as LaTeX will % try to write an aux file to the relative directory \input{deeply/nested/directory/testinc2} \end{document} Template-Plugin-Latex-3.02/t/input/testrefs.dvi0000644000175000000130000000010010705227604017567 0ustar andrew[% USE Latex; INCLUDE testrefs.tex FILTER latex(file.dvi) -%]Template-Plugin-Latex-3.02/t/input/deeply/0000755000175000017500000000000011156274540017733 5ustar andrewandrewTemplate-Plugin-Latex-3.02/t/input/deeply/nested/0000755000175000017500000000000011156274540021215 5ustar andrewandrewTemplate-Plugin-Latex-3.02/t/input/deeply/nested/directory/0000755000175000017500000000000011156274540023221 5ustar andrewandrewTemplate-Plugin-Latex-3.02/t/input/deeply/nested/directory/testinc2.tex0000644000175000000130000000003510705227604024260 0ustar andrewThis is more included text. Template-Plugin-Latex-3.02/t/input/bibfiles/0000755000175000017500000000000011156274540020230 5ustar andrewandrewTemplate-Plugin-Latex-3.02/t/input/bibfiles/testbib.bib0000644000175000000130000000122410705227604021125 0ustar andrew%% This is a test bibliography merely intended for testing Template::Latex @Book{wardley-ptt-2003, title = "Perl Template Toolkit", author = "Andy Wardley and Darren Chamberlain and Dave Cross", publisher = "O'Reilly Media", year = "2003", } @Book{butcher-81, title = "Copy-editing", author = "Judith Butcher", publisher = "Cambridge University Press", year = "1981", edition = "2nd", } @Book{chicago-82, title = "The {C}hicago Manual of Style", author = "`Chicago'", year = "1982", publisher = "University of Chicago Press", edition = "13th", } Template-Plugin-Latex-3.02/t/24-bibliography.t0000755000175000000130000000410511155773353017173 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/24-bibliography.t # # Test the Latex plugin's ability to generate bibliographies. # # Written by Andrew Ford # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Template; use Template::Test; use Template::Test::Latex; use File::Spec; require_dvitype(); my $out = 'output'; my $dir = -d 't' ? File::Spec->catfile('t', $out) : $out; my $files = { pdf => 'test1.pdf', ps => 'test1.ps', dvi => 'test1.dvi', }; clean_file($_) for values %$files; my $ttcfg = { OUTPUT_PATH => $dir, INCLUDE_PATH => [ "$FindBin::Bin/input" ], VARIABLES => { dir => $dir, file => $files, check => \&check_file, grep_dvi => sub { grep_dvi($dir, @_) }, }, }; test_expect(\*DATA, $ttcfg); sub clean_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); unlink($file); } sub check_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); return -f $path ? "PASS - $file exists" : "FAIL - $file does not exist"; } __END__ # Check generation of bibliographies # We use the 'alpha' bibliography style as that generates citation # references that are easily distinguishable -- test -- [% USE Latex; FILTER latex(file.dvi) -%] \documentclass{article} \begin{document} \section{Introduction} This file has a bibliography that includes the Badger book\cite{wardley-ptt-2003}. \bibliography{bibfiles/testbib} \bibliographystyle{alpha} \end{document} [% END -%] [% grep_dvi(file.dvi, 'Badger book\\[') %] [% grep_dvi(file.dvi, '\\[WCC03]') %] [% grep_dvi(file.dvi, 'Andy Wardley, Darren Chamberlain, and Dave Cross') %] -- expect -- -- process -- PASS - found 'Badger book\[' PASS - found '\[WCC03]' PASS - found 'Andy Wardley, Darren Chamberlain, and Dave Cross' Template-Plugin-Latex-3.02/t/01-latex2dvi.t0000755000175000000130000000421011155773353016412 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/01-latex2dvi.t # # Test the Latex filter with DVI output. Because of likely variations in # installed fonts etc, we don't verify the entire DVI file. We simply # make sure the filter runs without error and the first two bytes of the # output file have the correct value (0xf7 0x02 for DVI). # # Written by Craig Barratt # Updated for the Template-Latex distribution by Andy Wardley. # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Template; use Template::Test; use Template::Test::Latex; my $ttcfg = { FILTERS => { head => [ \&head_factory, 1], } }; test_expect(\*DATA, $ttcfg); # Grab just the first $len bytes of the input, and optionally convert # to a hex string if $hex is set sub head_factory { my($context, $len, $hex) = @_; $len ||= 72; return sub { my $text = shift; return $text if length($text) < $len; $text = substr($text, 0, $len); $text =~ s/(.)/sprintf("%02x", ord($1))/eg if $hex; return $text; } } __END__ -- test -- [% USE Latex; out = FILTER latex(format="dvi") -%] \documentclass{article} \begin{document} \section{Introduction} This is the introduction. \end{document} [% END -%] [% out | head(2, 1) %] -- expect -- f702 -- test -- [% USE Latex format="dvi"; out = FILTER latex -%] \documentclass{article} \begin{document} \section{Introduction} This is the introduction. \end{document} [% END -%] [% out | head(2, 1) %] -- expect -- f702 -- test -- [% USE Latex; TRY; out = FILTER latex("dvi") -%] \documentclass{article} \begin{document} \section{Introduction} \badmacro This is the introduction. \end{document} [% END; out | head(100, 1); CATCH latex; "ERROR: $error"; END -%] -- expect -- ERROR: latex error - latex exited with errors: ! Undefined control sequence. l.4 \badmacro Template-Plugin-Latex-3.02/t/00-latex.t0000755000175000000130000000330611155773353015631 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/00-latex.t # # Test the Template::Latex module. # # Written by Andy Wardley # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib") ); use Template::Latex; use Template::Test; use constant TL => 'Template::Latex'; ntests(13); #------------------------------------------------------------------------ # test methods to get/set paths #------------------------------------------------------------------------ ok( TL->latex_path('/path/to/latex'), 'set latex path' ); is( TL->latex_path(), '/path/to/latex', 'get latex path' ); ok( TL->pdflatex_path('/path/to/pdflatex'), 'set pdflatex path' ); is( TL->pdflatex_path(), '/path/to/pdflatex', 'get pdflatex path' ); ok( TL->dvips_path('/path/to/dvips'), 'set dvips path' ); is( TL->dvips_path(), '/path/to/dvips', 'get dvips path' ); my $paths = TL->latex_paths(); is( ref $paths, 'HASH', 'got paths' ); is( $paths->{ latex }, '/path/to/latex', 'paths latex' ); is( $paths->{ pdflatex }, '/path/to/pdflatex', 'paths pdflatex' ); is( $paths->{ dvips }, '/path/to/dvips', 'paths dvips' ); TL->latex_paths({ latex => '/new/path/to/latex', pdflatex => '/new/path/to/pdflatex', dvips => '/new/path/to/dvips', }); is( TL->latex_path(), '/new/path/to/latex', 'new latex' ); is( TL->pdflatex_path(), '/new/path/to/pdflatex', 'new pdflatex' ); is( TL->dvips_path(), '/new/path/to/dvips', 'new dvips' ); Template-Plugin-Latex-3.02/t/23-makeindex.t0000755000175000000130000000320311155773353016462 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/23-makeindex.t # # Test the Latex plugin's ability to generate output files. # # Written by Andy Wardley # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Template; use Template::Test; use Template::Test::Latex; use File::Spec; require_dvitype(); my $out = 'output'; my $dir = -d 't' ? File::Spec->catfile('t', $out) : $out; my $files = { pdf => 'test1.pdf', ps => 'test1.ps', dvi => 'test1.dvi', }; clean_file($_) for values %$files; my $ttcfg = { OUTPUT_PATH => $dir, VARIABLES => { dir => $dir, file => $files, check => \&check_file, grep_dvi => sub { grep_dvi($dir, @_) }, }, }; test_expect(\*DATA, $ttcfg); sub clean_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); unlink($file); } sub check_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); return -f $path ? "PASS - $file exists" : "FAIL - $file does not exist"; } __END__ # Check index file generation -- test -- [% USE Latex; FILTER latex(file.dvi) -%] \documentclass{article} \usepackage{makeidx} \makeindex \begin{document} \tableofcontents \section{Introduction} Concept \index{xyzzy} \printindex \end{document} [% END -%] [% grep_dvi(file.dvi, 'xyzzy, 1') %] -- expect -- -- process -- PASS - found 'xyzzy, 1' Template-Plugin-Latex-3.02/t/11-plugin-errors.t0000755000175000000130000001466011155773464017336 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/11-plugin.t # # THIS TEST SCRIPT DOES NOT YET PASS - THE ERRORS ARE IN THE SCRIPT ITSELF # # Test the Template::Plugin::Latex module. # # Written by Andy Wardley # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Test::More skip_all => "need to realign the tests here with the errors thrown by LaTeX::Driver"; use Template; use Template::Test; use Template::Test::Latex; my $ttcfg = { OUTPUT_PATH => 'output', FILTERS => { head => [ \&head_factory, 1], }, }; # Read in the tests from the DATA section and add a test to check that # the latex filter isn't installed if we the plugin is not loaded. # The test is not added if the TT2 version is less than 2.16 as up to # that point the latex filter was included in Template::Filters. my $tests = join '', ; if ($Template::VERSION > 2.15) { $tests = join "\n", ("-- test --", "[% # 1: Latex plugin not loaded", " TRY; ", " hello | latex;", " CATCH undef;", " error;", " END", "-%]", "-- expect --", "undef error - latex: filter not found", $tests); } test_expect($tests, $ttcfg); # Grab just the first $len bytes of the input, and optionally convert # to a hex string if $hex is set sub head_factory { my($context, $len, $hex) = @_; $len ||= 72; return sub { my $text = shift; return $text if length $text < $len; $text = substr($text, 0, $len); $text =~ s/(.)/sprintf("%02x", ord($1))/eg if $hex; return $text; } } __END__ -- test -- [[% # 2. USE, but then no FILTER - should work USE Latex %]] -- expect -- [] #------------------------------------------------------------------------ # test error handling #------------------------------------------------------------------------ -- test -- [% # 3. invalid LaTeX source text USE Latex; TRY; "hello world" FILTER latex; CATCH latex; error; END %] -- expect -- latex error - pdflatex exited with errors: ! LaTeX Error: Missing \begin{document}. l.1 h ! Emergency stop. ! ==> Fatal error occurred, no output PDF file produced! -- test -- [% # 4. invalid format on USE USE Latex format="nonsense"; TRY; "hello world" FILTER latex; CATCH latex; error; END %] -- expect -- latex error - invalid output format: 'nonsense' -- test -- [% # 5. invalid format on FILTER USE Latex; TRY; "hello world" FILTER latex(format="rubbish"); CATCH latex; error; END %] -- expect -- latex error - invalid output format: 'rubbish' -- test -- [% # 6. non-existent file USE Latex; TRY; "hello world" FILTER latex("nonsense"); CATCH latex; error; END %] -- expect -- latex error - cannot determine output format from file name: nonsense #------------------------------------------------------------------------ # test the ability to grok the format from output argument #------------------------------------------------------------------------ -- test -- [% USE Latex -%] [% TRY; "hello world" FILTER latex("example.pdf"); CATCH latex; error | head(42); END %] -- expect -- latex error - pdflatex exited with errors: -- test -- [% USE Latex -%] [% TRY; "hello world" FILTER latex("EXAMPLE.PDF"); CATCH latex; error | head(42); END %] -- expect -- latex error - pdflatex exited with errors: -- test -- [% USE Latex -%] [% TRY; "hello world" FILTER latex("example.ps"); CATCH latex; error | head(39); END %] -- expect -- latex error - latex exited with errors: -- test -- [% USE Latex -%] [% TRY; "hello world" FILTER latex("example.dvi"); CATCH latex; error | head(39); END %] -- expect -- latex error - latex exited with errors: #------------------------------------------------------------------------ # same again with named output/format parameters #------------------------------------------------------------------------ -- test -- [% USE Latex -%] [% TRY; "hello world" FILTER latex(output="example.pdf"); CATCH latex; error | head(42); END %] -- expect -- latex error - pdflatex exited with errors: -- test -- [% USE Latex -%] [% TRY; "hello world" FILTER latex(format="pdf"); CATCH latex; error | head(42); END %] -- expect -- latex error - pdflatex exited with errors: -- test -- [% USE Latex -%] [% TRY; "hello world" FILTER latex(output="example.ps"); CATCH latex; error | head(39); END %] -- expect -- latex error - latex exited with errors: -- test -- [% USE Latex -%] [% TRY; "hello world" FILTER latex(output="example.ps", format="pdf"); CATCH latex; error | head(42); END %] -- expect -- latex error - pdflatex exited with errors: -- test -- [% USE Latex -%] [% TRY; "hello world" FILTER latex("example.dvi"); CATCH latex; error | head(39); END %] -- expect -- latex error - latex exited with errors: #------------------------------------------------------------------------ # test the old-skool usage where the single argument is the format #------------------------------------------------------------------------ -- test -- [% # 16. latex("pdf") on invalid input USE Latex; TRY; "hello world" FILTER latex("pdf"); CATCH latex; error | head(42); END %] -- expect -- latex error - pdflatex exited with errors: -- test -- [% # 17. latex("ps") on invalid input USE Latex; TRY; "hello world" FILTER latex("ps"); CATCH latex; error | head(39); END %] -- expect -- latex error - latex exited with errors: -- test -- [% # 18. latex("dvi") on invalid input USE Latex; TRY; "hello world" FILTER latex("dvi"); CATCH latex; error | head(39); END %] -- expect -- latex error - latex exited with errors: #------------------------------------------------------------------------ # try a different filter name #------------------------------------------------------------------------ -- test -- [% # 19. invoke filter with a different name USE Latex filter='pdf' format='pdf'; TRY; "hello world" FILTER pdf("example.pdf"); CATCH latex; error | head(42); END %] -- expect -- latex error - pdflatex exited with errors: Template-Plugin-Latex-3.02/t/21-includes.t0000755000175000000130000000477611155773353016341 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/21-includes.t # # Test the Latex plugin's ability to cope with included files. # # Written by Andrew Ford # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Template; use Template::Test; use Template::Test::Latex; use File::Spec; require_dvitype(); my $out = 'output'; my $dir = -d 't' ? File::Spec->catfile('t', $out) : $out; my $files = { pdf => 'test1.pdf', ps => 'test1.ps', dvi => 'test1.dvi', }; clean_file($_) for values %$files; my $ttcfg = { OUTPUT_PATH => $dir, INCLUDE_PATH => [ "$FindBin::Bin/input" ], VARIABLES => { dir => $dir, file => $files, check => \&check_file, grep_dvi => sub { grep_dvi($dir, @_) }, }, }; test_expect(\*DATA, $ttcfg); sub clean_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); unlink($path); } sub check_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); return -f $path ? "PASS - $file exists" : "FAIL - $file does not exist"; } __END__ # Check that included files work # ============================== # # 1. process inline LaTeX source -- test -- [% USE Latex; FILTER latex(file.dvi) -%] \documentclass{article} \begin{document} \section{Introduction} Including a file. \include{testinc} \input{deeply/nested/directory/testinc2} \end{document} [% END -%] [% grep_dvi(file.dvi, 'This is included text') %] [% grep_dvi(file.dvi, 'This is more included text.') %] -- expect -- -- process -- PASS - found 'This is included text' PASS - found 'This is more included text.' # 2. include a LaTeX file and filter it -- test -- [% INCLUDE 'testrefs.tex' FILTER latex(file.dvi) -%] [% grep_dvi(file.dvi, 'This is included text.') %] [% grep_dvi(file.dvi, 'This is more included text.') %] -- expect -- -- process -- PASS - found 'This is included text.' PASS - found 'This is more included text.' # 3. process a TT2 file that includes and filters a LaTeX file -- test -- [% PROCESS 'testrefs.dvi' -%] [% grep_dvi(file.dvi, 'This is included text.') %] [% grep_dvi(file.dvi, 'This is more included text.') %] -- expect -- -- process -- PASS - found 'This is included text.' PASS - found 'This is more included text.' Template-Plugin-Latex-3.02/t/lib/0000755000175000017500000000000011156274541016061 5ustar andrewandrewTemplate-Plugin-Latex-3.02/t/lib/Template/0000755000175000017500000000000011156274541017634 5ustar andrewandrewTemplate-Plugin-Latex-3.02/t/lib/Template/Test/0000755000175000017500000000000011156274541020553 5ustar andrewandrewTemplate-Plugin-Latex-3.02/t/lib/Template/Test/Latex.pm0000644000175000017500000000363511156274304022172 0ustar andrewandrewpackage Template::Test::Latex; use strict; use vars qw(@ISA @EXPORT); use Config; use Template::Test; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(find_program grep_dvi dvitype require_dvitype); our $WIN32 = ($^O eq 'MSWin32'); $Template::Plugin::Latex::DEBUG = grep(/-d/, @ARGV); $Template::Plugin::Latex::DEBUG = $Template::Plugin::Latex::DEBUG; my $dvitype = find_program($ENV{PATH}, "dvitype"); sub dvitype { return $dvitype; } sub require_dvitype { if (!$dvitype || ! -x $dvitype) { skip_all("'dvitype' is not available"); exit(0); } } #------------------------------------------------------------------------ # find_program($path, $prog) # # Find a program, $prog, by traversing the given directory path, $path. # Returns full path if the program is found. # # Written by Craig Barratt, Richard Tietjen add fixes for Win32. # # abw changed name from studly caps findProgram() to find_program() :-) #------------------------------------------------------------------------ sub find_program { my($path, $prog) = @_; foreach my $dir ( split($Config{path_sep}, $path) ) { my $file = File::Spec->catfile($dir, $prog); if ( !$WIN32 ) { return $file if ( -x $file ); } else { # Windows executables end in .xxx, exe precedes .bat and .cmd foreach my $dx ( qw/exe bat cmd/ ) { return "$file.$dx" if ( -x "$file.$dx" ); } } } } sub grep_dvi { my $dir = shift; my $file = shift; my $regexp = shift; my $path = File::Spec->catfile($dir, $file); return "FAIL - $file does not exist" unless -f $path; return "FAIL - can't find dvitype" unless $dvitype and -x $dvitype; my $dvioutput = `$dvitype $path`; foreach (split(/\n/, $dvioutput)) { next unless /^\[(.*)\]$/; return "PASS - found '$regexp'" if /$regexp/; } return "FAIL - '$regexp' not found"; } 1; Template-Plugin-Latex-3.02/t/README0000644000175000000130000000067510705227572014772 0ustar andrewThis is the Template::Latex unit test directory. It contains the unit test files and the directories: lib contains a test helper module input contains test input files output this is the destination for testing of generated DVI/PS/PDF documents The unit test 11-plugin-errors.t is does not yet pass - the errors are in the test script. I have marked the script as skip_all until I get round to sorting out the tests again. Template-Plugin-Latex-3.02/t/10-output.t0000755000175000000130000000414011155773353016052 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/10-output.t # # Test the Latex plugin's ability to generate output files. # # Written by Andy Wardley # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Carp; use Template; use Template::Test; use Template::Plugin::Latex; use File::Spec; my $out = 'output'; my $dir = -d 't' ? File::Spec->catfile('t', $out) : $out; my $files = { pdf => 'test1.pdf', ps => 'test1.ps', dvi => 'test1.dvi', }; clean_file($_) for values %$files; my $ttcfg = { OUTPUT_PATH => $dir, VARIABLES => { dir => $dir, file => $files, check => \&check_file, }, }; test_expect(\*DATA, $ttcfg); sub clean_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); if (-f $path) { unlink($path) or carp "cannot unlink $file ($!)"; } } sub check_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); return -f $path ? "PASS - $file exists" : "FAIL - $file does not exist"; } __END__ -- test -- [% USE Latex; FILTER latex(file.pdf) -%] \documentclass{article} \begin{document} This is a PDF document generated by Latex and the Template Toolkit. \end{document} [% END -%] [% check(file.pdf) %] -- expect -- -- process -- PASS - [% file.pdf %] exists -- test -- [% USE Latex; FILTER latex(output=file.ps) -%] \documentclass{article} \begin{document} This is a PostScript document generated by Latex and the Template Toolkit. \end{document} [% END -%] [% check(file.ps) %] -- expect -- -- process -- PASS - [% file.ps %] exists -- test -- [% USE Latex; FILTER latex(file.dvi) -%] \documentclass{article} \begin{document} This is a DVI document generated by Latex and the Template Toolkit. \end{document} [% END -%] [% check(file.dvi) %] -- expect -- -- process -- PASS - [% file.dvi %] exists Template-Plugin-Latex-3.02/t/20-references.t0000755000175000000130000000333611155773353016642 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/20-references.t # # Test the Latex plugin's ability to re-run Latex to resolve forward references # # Written by Andrew Ford # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Template; use Template::Test; use Template::Test::Latex; use File::Spec; my $out = 'output'; my $dir = -d 't' ? File::Spec->catfile('t', $out) : $out; require_dvitype(); my $files = { pdf => 'test1.pdf', ps => 'test1.ps', dvi => 'test1.dvi', }; clean_file($_) for values %$files; my $ttcfg = { OUTPUT_PATH => $dir, INCLUDE_PATH => [ "$FindBin::Bin/input" ], VARIABLES => { dir => $dir, file => $files, check => \&check_file, grep_dvi => sub { grep_dvi($dir, @_) }, }, }; test_expect(\*DATA, $ttcfg); sub clean_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); unlink($file); } sub check_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); return -f $path ? "PASS - $file exists" : "FAIL - $file does not exist"; } __END__ # Check that forward references work -- test -- [% USE Latex; FILTER latex(file.dvi) -%] \documentclass{article} \begin{document} \section{Introduction} See page~\pageref{pagetwo}. \par \pagebreak This is the second page\label{pagetwo}. \end{document} [% END -%] [% grep_dvi(file.dvi, 'See page 2') %] -- expect -- -- process -- PASS - found 'See page 2' Template-Plugin-Latex-3.02/t/12-template.t0000755000175000000130000000454011155773353016333 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/12-template.t # # Test the Template::Latex module as a wrapper around Template. # # Written by Andy Wardley # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Template::Latex; use Template::Test; use Template::Test::Latex; use File::Spec; my $out = 'output'; my $dir = -d 't' ? File::Spec->catfile('t', $out) : $out; my $files = { blank => 'test2', pdf => 'test2.pdf', ps => 'test2.ps', dvi => 'test2.dvi', }; clean_file($_) for values %$files; my $ttcfg = { OUTPUT_PATH => $dir, LATEX_FORMAT => 'pdf', VARIABLES => { dir => $dir, file => $files, check => \&check_file, }, }; my $tt = Template::Latex->new($ttcfg); test_expect(\*DATA, $tt); sub clean_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); unlink($file); } sub check_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); return -f $path ? "PASS - $file exists" : "FAIL - $file does not exist"; } __END__ -- test -- [% FILTER latex(file.pdf) -%] \documentclass{article} \begin{document} This is a PDF document generated by Latex and the Template Toolkit. \end{document} [% END -%] [% check(file.pdf) %] -- expect -- -- process -- PASS - [% file.pdf %] exists -- test -- [% FILTER latex(output=file.ps) -%] \documentclass{article} \begin{document} This is a PostScript document generated by Latex and the Template Toolkit. \end{document} [% END -%] [% check(file.ps) %] -- expect -- -- process -- PASS - [% file.ps %] exists -- test -- [% FILTER latex(file.dvi) -%] \documentclass{article} \begin{document} This is a DVI document generated by Latex and the Template Toolkit. \end{document} [% END -%] [% check(file.dvi) %] -- expect -- -- process -- PASS - [% file.dvi %] exists -- test -- [% FILTER latex(file.blank) -%] \documentclass{article} \begin{document} This is a PDF document generated by Latex and the Template Toolkit. \end{document} [% END -%] [% check(file.blank) %] -- expect -- -- process -- PASS - [% file.blank %] exists Template-Plugin-Latex-3.02/t/13-latex-encode.t0000755000175000000130000000455111155773353017073 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/13-latex_encode.t # # Test the Latex plugin's latex_encode filter # # Written by Andrew Ford # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Template; use Template::Test; use Template::Test::Latex; use File::Spec; my $out = 'output'; my $dir = -d 't' ? File::Spec->catfile('t', $out) : $out; my $ttcfg = { OUTPUT_PATH => $dir, }; test_expect(\*DATA, $ttcfg); __END__ # Latex_Encodeify string with no special characters -- test -- [% USE Latex; "abc" | latex_encode; %] -- expect -- abc # Latex_Encodeify string with a "&" -- test -- [% USE Latex; "AT&T" | latex_encode; %] -- expect -- AT\&T # Latex_Encodeify string with a "%" -- test -- [% USE Latex; "42%" | latex_encode; %] -- expect -- 42\% # Latex_Encodeify string with a "_" -- test -- [% USE Latex; "mod_perl" | latex_encode; %] -- expect -- mod\_perl # Latex_Encodeify string with a "{" and "}" -- test -- [% USE Latex; "{..}" | latex_encode; %] -- expect -- \{..\} # Latex_Encodeify string with a "\" -- test -- [% USE Latex; "\\LaTeX" | latex_encode; %] -- expect -- \textbackslash LaTeX # Latex_Encodeify string with a "#" -- test -- [% USE Latex; "#" | latex_encode; %] -- expect -- \# # Latex_Encodeify string with a "$" -- test -- [% USE Latex; '$0.01' | latex_encode; %] -- expect -- \$0.01 # Latex_Encodeify a string with multiple special characters -- test -- [% USE Latex; "\\&#_^{}\\&#_^{}" | latex_encode; %] -- expect -- \textbackslash\&\#\_\^{ }\{\}\textbackslash\&\#\_\^{ }\{\} # Latex_Encodeify string with intelligent double quotes -- test -- [% USE Latex; 'blah "double-quoted-string" blah' | latex_encode(iquotes = 1); %] -- expect -- blah ``double-quoted-string'' blah # Latex_Encodeify string with intelligent single quotes -- test -- [% USE Latex; "blah 'single-quoted-string' blah" | latex_encode(iquotes = 1); %] -- expect -- blah `single-quoted-string' blah # Latex_Encodeify string with -- test -- [% USE Latex; 'blah \textbf{%^&*} blah' | latex_encode(except = "\\{}"); %] -- expect -- blah \textbf{\%\^{ }\&*} blah Template-Plugin-Latex-3.02/t/22-tableofcontents.t0000755000175000000130000000366611155773353017723 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/22-tableofcontents.t # # Test the Latex plugin's ability to process files with tables of contents. # # Written by Andrew Ford # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Template; use Template::Test; use Template::Test::Latex; use File::Spec; require_dvitype(); my $out = 'output'; my $dir = -d 't' ? File::Spec->catfile('t', $out) : $out; my $files = { pdf => 'test1.pdf', ps => 'test1.ps', dvi => 'test1.dvi', }; clean_file($_) for values %$files; my $ttcfg = { OUTPUT_PATH => $dir, VARIABLES => { dir => $dir, file => $files, check => \&check_file, grep_dvi => sub { grep_dvi($dir, @_) }, }, }; test_expect(\*DATA, $ttcfg); sub clean_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); unlink($file); } sub check_file { my $file = shift; my $path = File::Spec->catfile($dir, $file); return -f $path ? "PASS - $file exists" : "FAIL - $file does not exist"; } __END__ # Check that table of contents work # We specify an optional TOC entry for the first section - this is not # included in the text of the document but just in the table of # contents, so if we find it in the dvi file then the TOC must have # bneen formatted. -- test -- [% USE Latex; FILTER latex(file.dvi) -%] \documentclass{article} \begin{document} \tableofcontents \section[First Section TOC Entry]{First Section} \end{document} [% END -%] [% grep_dvi(file.dvi, 'Contents') %] [% grep_dvi(file.dvi, 'First Section TOC Entry') %] -- expect -- -- process -- PASS - found 'Contents' PASS - found 'First Section TOC Entry' Template-Plugin-Latex-3.02/t/03-latex2ps.t0000755000175000000130000000420411155773353016257 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/03-latex2ps.t # # Test the Latex filter with PS (PostScript) output. Because of likely # variations in installed fonts etc, we don't verify the entire PS # file. We simply make sure the filter runs without error and the # first four characters of the output file have the correct value # "%!PS". # # Written by Craig Barratt # Updated for the Template-Latex distribution by Andy Wardley. # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Template; use Template::Test; use Template::Test::Latex; my $ttcfg = { FILTERS => { head => [ \&head_factory, 1], } }; test_expect(\*DATA, $ttcfg); # Grab just the first $len bytes of the input, and optionally convert # to a hex string if $hex is set sub head_factory { my($context, $len, $hex) = @_; $len ||= 72; return sub { my $text = shift; return $text if length($text) < $len; $text = substr($text, 0, $len); $text =~ s/(.)/sprintf("%02x", ord($1))/eg if $hex; return $text; } } __END__ -- test -- [% USE Latex; out = FILTER latex(format="ps") -%] \documentclass{article} \begin{document} \section{Introduction} This is the introduction. \end{document} [% END -%] [% out | head(4) %] -- expect -- %!PS -- test -- [% USE Latex format="ps"; out = FILTER latex -%] \documentclass{article} \begin{document} \section{Introduction} This is the introduction. \end{document} [% END -%] [% out | head(4) %] -- expect -- %!PS -- test -- [% USE Latex; TRY; out = FILTER latex("ps") -%] \documentclass{article} \begin{document} \section{Introduction} \badmacro This is the introduction. \end{document} [% END; out | head(100, 1); CATCH latex; "ERROR: $error"; END -%] -- expect -- ERROR: latex error - latex exited with errors: ! Undefined control sequence. l.4 \badmacro Template-Plugin-Latex-3.02/t/output/0000755000175000017500000000000011156274540016652 5ustar andrewandrewTemplate-Plugin-Latex-3.02/t/output/README0000644000175000000130000000016010705227604016313 0ustar andrewThis directory is used as the destination for generated PDF, PS and DVI documents. See the t/10-output.t test. Template-Plugin-Latex-3.02/t/02-latex2pdf.t0000755000175000000130000000417711155773353016416 0ustar andrew#!/usr/bin/perl -- ========================================== -*-perl-*- # # t/02-latex2pdf.t # # Test the Latex filter with PDF output. Because of likely variations in # installed fonts etc, we don't verify the entire PDF file. We simply # make sure the filter runs without error and the first four characters # of the output file have the correct value "%PDF". # # Written by Craig Barratt # Updated for the Template-Latex distribution by Andy Wardley. # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # #======================================================================== use strict; use warnings; use FindBin qw($Bin); use Cwd qw(abs_path); use lib ( abs_path("$Bin/../lib"), "$Bin/lib" ); use Template; use Template::Test; use Template::Test::Latex; my $ttcfg = { FILTERS => { head => [ \&head_factory, 1], } }; test_expect(\*DATA, $ttcfg); # Grab just the first $len bytes of the input, and optionally convert # to a hex string if $hex is set sub head_factory { my($context, $len, $hex) = @_; $len ||= 72; return sub { my $text = shift; return $text if length($text) < $len; $text = substr($text, 0, $len); $text =~ s/(.)/sprintf("%02x", ord($1))/eg if $hex; return $text; } } __END__ -- test -- [% USE Latex; out = FILTER latex(format="pdf") -%] \documentclass{article} \begin{document} \section{Introduction} This is the introduction. \end{document} [% END -%] [% out | head(4) %] -- expect -- %PDF -- test -- [% USE Latex format="pdf"; out = FILTER latex -%] \documentclass{article} \begin{document} \section{Introduction} This is the introduction. \end{document} [% END -%] [% out | head(4) %] -- expect -- %PDF -- test -- [% USE Latex; TRY; out = FILTER latex("pdf") -%] \documentclass{article} \begin{document} \section{Introduction} \badmacro This is the introduction. \end{document} [% END; out | head(100, 1); CATCH latex; "ERROR: $error"; END -%] -- expect -- ERROR: latex error - pdflatex exited with errors: ! Undefined control sequence. l.4 \badmacro Template-Plugin-Latex-3.02/META.yml0000664000175000017500000000113511156274541016323 0ustar andrewandrew--- #YAML:1.0 name: Template-Plugin-Latex version: 3.02 abstract: Latex support for the Template Toolkit author: - Andrew Ford license: unknown distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 requires: LaTeX::Driver: 0.07 LaTeX::Encode: 0.02 LaTeX::Table: 0 Template: 2.16 no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.48 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 Template-Plugin-Latex-3.02/lib/0000755000175000017500000000000011156274540015615 5ustar andrewandrewTemplate-Plugin-Latex-3.02/lib/Template/0000755000175000017500000000000011156274540017370 5ustar andrewandrewTemplate-Plugin-Latex-3.02/lib/Template/Plugin/0000755000175000017500000000000011156274540020626 5ustar andrewandrewTemplate-Plugin-Latex-3.02/lib/Template/Plugin/Latex.pm0000644000175000000130000004065211156267711021040 0ustar andrew#============================================================= -*-perl-*- # # Template::Plugin::Latex # # $Id:$ # # DESCRIPTION # Template Toolkit plugin for Latex # # AUTHOR # Andrew Ford (current maintainer) # Andy Wardley (original author) # # COPYRIGHT # Copyright (C) 2006-2007 Andrew Ford. All Rights Reserved. # Copyright (C) 1996-2006 Andy Wardley. All Rights Reserved. # # This module is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # # HISTORY # * Originally written by Craig Barratt, Apr 28 2001. # * Win32 additions by Richard Tietjen. # * Extracted into a separate Template::Plugin::Latex module by # Andy Wardley, 27 May 2006 # * Removed the program pathname options on the FILTER call # Andrew Ford, 05 June 2006 # * Totally rewritten by Andrew Ford September 2007 # * Version 3.00 released March 2009 # #======================================================================== package Template::Plugin::Latex; use strict; use warnings; use base 'Template::Plugin'; use File::Spec; use LaTeX::Driver 0.07; use LaTeX::Encode; use LaTeX::Table; our $VERSION = 3.02; # Update "=head1 VERSION" below!!!! our $DEBUG; $DEBUG = 0 unless defined $DEBUG; our $ERROR = ''; our $FILTER = 'latex'; our $THROW = 'latex'; # exception type #------------------------------------------------------------------------ # constructor # #------------------------------------------------------------------------ sub new { my ($class, $context, $options) = @_; # make sure that $options is a hash ref $options ||= {}; # create a closure to generate filters with additional options my $filter_factory = sub { my $factory_context = shift; my $filter_opts = ref $_[-1] eq 'HASH' ? pop : { }; my $filter_args = [ @_ ]; @$filter_opts{ keys %$options } = values %$options; return sub { # Template::Plugin::Latex::_filter->run($context, $filter_opts, $filter_args, @_); _tt_latex_filter($class, $factory_context, $filter_opts, $filter_args, @_); }; }; # create a closure to generate filters with additional options my $encode_filter_factory = sub { my $factory_context = shift; my $filter_opts = ref $_[-1] eq 'HASH' ? pop : { }; my $filter_args = [ @_ ]; @$filter_opts{ keys %$options } = values %$options; return sub { # Template::Plugin::Latex::_filter->run($context, $filter_opts, $filter_args, @_); _tt_latex_encode_filter($class, $factory_context, $filter_opts, $filter_args, @_); }; }; # and a closure to represent the plugin my $plugin = sub { my $plugopt = ref $_[-1] eq 'HASH' ? pop : { }; @$plugopt{ keys %$options } = values %$options; # Template::Plugin::Latex::_filter->run($context, $plugopt, @_ ); _tt_latex_filter($class, $context, $plugopt, {}, @_ ); }; # now define the filter and return the plugin $context->define_filter('latex_encode', [ $encode_filter_factory => 1 ]); $context->define_filter($options->{filter} || $FILTER, [ $filter_factory => 1 ]); return bless $plugin, $class; } #------------------------------------------------------------------------ # _tt_latex_encode_filter # # #------------------------------------------------------------------------ sub _tt_latex_encode_filter { my ($class, $context, $options, $filter_args, @text) = @_; my $text = join('', @text); return latex_encode($text, %{$options}); } #------------------------------------------------------------------------ # _tt_latex_filter # # #------------------------------------------------------------------------ sub _tt_latex_filter { my ($class, $context, $options, $filter_args, @text) = @_; my $text = join('', @text); # Get the output and format options # my $output = $options->{output}; my $output = delete $options->{ output } || shift(@$filter_args) || ''; my $format = $options->{format}; # If the output is just a format specifier then set the format to # that and undef the output if ($output =~ /^ (?: dvi | ps | pdf(?:\(\w+\))? ) $/x) { ($format, $output) = ($output, undef); } # If the output is a filename then convert to a full pathname in # the OUTPUT_PATH directory, outherwise set the output to a # reference to a temporary variable. if ($output) { my $path = $context->config->{ OUTPUT_PATH } or $class->_throw('OUTPUT_PATH is not set'); $output = File::Spec->catfile($path, $output); } else { my $temp; $output = \$temp; } # Run the formatter eval { my $drv = LaTeX::Driver->new( source => \$text, output => $output, format => $format, maxruns => $options->{maxruns}, extraruns => $options->{extraruns}, texinputs => _setup_texinput_paths($context), ); $drv->run; }; if (my $e = LaTeX::Driver::Exception->caught()) { $class->_throw("$e"); } # Return the text if it was output to a scalar variable, otherwise # return nothing. return ref $output ? $$output : ''; } #------------------------------------------------------------------------ # $self->setup_texinput_paths # # setup the TEXINPUT path environment variables #------------------------------------------------------------------------ sub _setup_texinput_paths { my ($context) = @_; my $template_name = $context->stash->get('template.name'); my $include_path = $context->config->{INCLUDE_PATH} || []; $include_path = [ $include_path ] unless ref $include_path; my @texinput_paths = (""); foreach my $path (@$include_path) { my $template_path = File::Spec->catfile($path, $template_name); if (-f $template_path) { my($volume, $dir) = File::Spec->splitpath($template_path); $dir = File::Spec->catfile($volume, $dir); unshift @texinput_paths, $dir; next if $dir eq $path; } push @texinput_paths, $path; } return \@texinput_paths; } sub _throw { my $self = shift; die Template::Exception->new( $THROW => join('', @_) ); } sub table { my $args = ref($_[-1]) eq 'HASH' ? pop(@_) : { }; my ($table, $text); eval { $table = LaTeX::Table->new($args); $text = $table->generate_string; }; if ($@) { die Template::Exception->new( $THROW => $@ ); } return $text; } 1; __END__ =head1 NAME Template::Plugin::Latex - Template Toolkit plugin for Latex =head1 VERSION This documentation refers to C version 3.02. =head1 SYNOPSIS Sample Template Toolkit code: [%- USE Latex; mystr = "a, b & c" | latex_encode; FILTER latex("pdf"); -%] \documentclass{article} \begin{document} This is a PDF document generated by LaTeX and the Template Toolkit, with some interpolated data: [% mystr %] \end{document} [% END; -%] =head1 DESCRIPTION The C Template Toolkit plugin provides a C filter that allows the use of LaTeX to generate PDF, PostScript and DVI output files from the Template Toolkit. The plugin uses L to run the various LaTeX programs. Processing of the LaTeX document takes place in a temporary directory that is deleted once processing is complete. The standard LaTeX programs (C or C, C and C) are run and re-run as necessary until all references, indexes, bibliographies, table of contents, and lists of figures and tables are stable or it is apparent that they will not stabilize. The format converters C, C, C and C are run as necessary to convert the output document to the requested format. The C environment variable is set up to include the template directory and the C directories, so that LaTeX file inclusion commands should find the intended files. The output of the filter is binary data (although PDF and PostScript are not stictly binary). You should be careful not to prepend or append any extraneous characters (even space characters) or text outside the FILTER block as this text will be included in the file output. Notice in the example below how we use the post-chomp flags ('-') at the end of the C and C directives to remove the trailing newline characters: [% USE Latex(format='pdf') -%] [% FILTER latex %] ...LaTeX document... [% END -%] If you're redirecting the output to a file via the third argument of the Template module's C method then you should also pass the C parameter, set to a true value to indicate that it is a binary file. use Template; my $tt = Template->new({ INCLUDE_PATH => '/path/to/templates', OUTPUT_PATH => '/path/to/pdf/output', }); my $vars = { title => 'Hello World', } $tt->process('example.tt2', $vars, 'example.pdf', binmode => 1) || die $tt->error(); If you want to capture the output to a template variable, you can do so like this: [% output = FILTER latex %] ...LaTeX document... [% END %] You can pass additional arguments when you invoke the filter, for example to specify the output format. [% FILTER latex(format='pdf') -%] ...LaTeX document... [% END %] If you want to write the output to a file then you can specify an C parameter. [% FILTER latex(output='example.pdf') %] ...LaTeX document... [% END %] If you don't explicity specify an output format then the filename extension (e.g. 'pdf' in the above example) will be used to determine the correct format. You can specify a different filter name using the C parameter. [% USE Latex(filter='pdf') -%] [% FILTER pdf %] ...LaTeX document... [% END %] You can also specify the default output format. This value can be C, C or C. [% USE Latex(format='pdf') %] Note: the C distribution includes three filter programs (C, C and C) that use the C package to process LaTeX source data into DVI, PDF or PostScript file respectively. These programs have a C<-tt2> option to run their input through the Template Toolkit before processing as LaTeX source. The programs do not use the C plugin unless the template requests it, but they may provide an alternative way of processing Template Toolkit templates to generate typeset output. =head1 SUBROUTINES/METHODS =head2 C This statement loads the plugin (note that prior to version 2.15 the filter was built in to Template Toolkit so this statement was unnecessary; it is now required). =head2 The C Filter The C filter accepts a number of options, which may be specified on the USE statement or on the filter invocation. =over 4 =item C specifies the format of the output; one of C (TeX device independent format), C (PostScript) or C (Adobe Portable Document Format). The follow special values are also accepted: C (generates PDF via PostScript, using C and C), C (generates PDF via dvi, using C) =item C the name of the output file, or just the output format =item C the name of the C style file to use (this is passed with the C<-s> option to C) =item C options to be passed to C. Useful options are C<-l> for letter ordering of index terms (rather than the default word ordering), C<-r> to disable implicit page range formation, and C<-c> to compress intermediate blanks in index keys. Refer to L for full details. =item C The maximum number of runs of the formatter program (defaults to 10). =item C The number of additional runs of the formatter program after it seems that the formatting of the document has stabilized (default 0). Note that the setting of C takes precedence, so if C is set to 10 and C is set to 3, and formatting stabilizes after 8 runs then only 2 extra runs will be performed. =back =head2 The C filter The C filter encodes LaTeX special characters in its input into their LaTeX encoded representations. It also encodes other characters that have The special characters are: C<\> (command character), C<{> (open group), C<}> (end group), C<&> (table column separator), C<#> (parameter specifier), C<%> (comment character), C<_> (subscript), C<^> (superscript), C<~> (non-breakable space), C<$> (mathematics mode). =over 4 =item C Lists the characters that should be excluded from encoding. By default no special characters are excluded, but it may be useful to specify C to allow the input string to contain LaTeX commands such as C<"this is \textbf{bold} text">. =item C By default the C filter will encode characters with the encodings provided by the C LaTeX package (for example the Pounds Sterling symbol is encoded as C<\textsterling{}>). Setting C turns off these encodings. =back =head2 C The C function provides an interface to the C module. The following example shows how a simple table can be set up. [%- USE Latex; data = [ [ 'London', 'United Kingdom' ], [ 'Berlin', 'Germany' ], [ 'Paris', 'France' ], [ 'Washington', 'USA' ] ] ); text = Latex.table( caption = 'Capitol Cities', label = 'table:capitols', headings = [ [ 'City', 'Country' ] ], data = data ); -%] The variable C will hold the LaTeX commands to typeset the table and can be further interpolated into a LaTeX document template. =head1 DIAGNOSTICS Most failures result from invalid LaTeX input and are propogated up from L, L or L. Failures detected in this module include: =over 4 =item C an output filename was specified but the C configuration option has not been set. =back =head1 DEPENDENCIES =over 4 =item L