5

I use perl v5.10 (on windows 7) + TT v2.22. When I use TT, for each source line, I get in the produced html an extra CR :

Source text (windows format):

"Some_html" CR LF  

Output text :

"Some_html" CR  
CR LF

However, when I convert my source file to unix format, and then I run TT, I get :
Source text (unix format):

"Some_html" LF   

Output text :

"Some_html" CR LF

(I use notepad++ to show the CR & LF characters; also to change unix <-> windows formats in the source template).

When I google the problem, I get some (few) posts about extra ^M on windows, but I couldn't find explanation as for the root cause neither a true solution (just some workaround how to get rid of extra ^M).

Although not a real problem, I find it quite "unclean".
Is there some configuration that i should turn on (I reviewed www.template-toolkit.org/docs/manual/Config.html but could not find anything) ?
Some other solution ? (other than post-fixing the output file).
Thanks

gerard
  • 1,703
  • 1
  • 11
  • 14

3 Answers3

11

Template Toolkit reads source files for templates in binary mode, but writing in text mode. Data from template (that contains CR LF) are translated during output in text mode, so the LF becomes CR LF.

The easiest solution for the problem is to write files in binary mode (note the raw modifier to open call):

my $tt = Template->new;
my $output_file = 'some_file.txt';
open my $out_fh, '>:raw', $output_file    or die "$output_file: $!\n";
$tt->process('template', \%data, $out_fh) or die $tt->error();
bvr
  • 9,599
  • 20
  • 28
0

bvr's solution unfortunately doesn't work for output generated using [% FILTER redirect(...) %]. On Windows 10, template

[% FILTER redirect("bar.txt") %]
This text is for bar.txt.
[% END %]
This text is for foo.txt.

(with DOS-style CR-LF line endings) expanded through

#! /bin/perl
use strict;
use warnings;

use Template;

my $tt = Template->new({
                        OUTPUT_PATH => '.',
                        RELATIVE => 1,
                       }) || die "$Template::ERROR\n";

my $srcfile = 'foo.txt.tt';
my $tgtfile = 'foo.txt';

open my $ofh, '>:raw', $tgtfile or die;

$tt->process($srcfile, {}, $ofh, { binmode => ':raw' })
    || die $tt->error . "\n";

creates output file foo.txt with the expected CR-LF line endings, but creates bar.txt with bad CR-CR-LF line endings:

> od -c bar.txt
0000000  \r  \r  \n   T   h   i   s       t   e   x   t       i   s
0000020   f   o   r       b   a   r   .   t   x   t   .  \r  \r  \n
0000037

I reported this problem to the TT author at https://github.com/abw/Template2/issues/63.

I found a simple workaround solution: In sub Template::_output (in Template.pm), change

my $bm = $options->{ binmode };

to

my $bm = $options->{ binmode } // $BINMODE;

Then in your main perl script set

$Template::BINMODE = ':raw';

Then you can process the template using

$tt->process($srcfile, {}, $tgtfile) || die $tt->error . "\n";

and get CR-LF line endings in both the main and redirected output.

Louis Strous
  • 734
  • 7
  • 13
0

Have a good day, I found a very simple solution on this:

my $tt = Template->new({
        ...,
        PRE_CHOMP  => 1,
        POST_CHOMP => 1,
        ...
});

This config will instruct the template engine to remove all pre and post CR LF of the template text.

Thien Pham
  • 81
  • 1
  • 4