我让这个模板正常工作:
$ cat matrix.tt
[% DEFAULT
ncols = 3
elems = [1,2,3,4,5,6,7,8,9]
%]
\left[\begin{matrix}
[% WHILE elems.size %]
[% elems.splice(0,ncols).join(' & ') %]
[% IF elems.size %]\\[% END %]
[% END %]
\end{matrix}\right]
$ tpage --pre_chomp --post_chomp matrix.tt
\left[\begin{matrix}1 & 2 & 3\\4 & 5 & 6\\7 & 8 & 9\end{matrix}\right]
但这不起作用:
$ tpage --define ncols=2 --define elems=[1,2,3,4] matrix.tt
undef error - WHILE loop terminated (> 1000 iterations)
我发现使用以下代码,使用--define
选项将数组传递给tpage
并不是一件容易的事。
$ cat pk.tt
[% DEFAULT
ho = [1,2]
-%]
ho is [% ho %]
po is [% po %]
$ tpage --define po=[1,3] pk.tt #I want po to be interpreted as an array
ho is ARRAY(0x1a3fd00)
po is [1,3]
输出显示po是标量。我想从命令行传递数组有没有办法做到这一点?
答案 0 :(得分:1)
根据数组中值的复杂程度,您可以使用以下内容:
[%- el = elems.split(',') -%]
\left[\begin{matrix}
[% WHILE el.size %]
[% el.splice(0,ncols).join(' & ') %]
... #etc
$ tpage --define ncols=2 --define elems="1,2,3,4" matrix.tt
但是当然如果elems
不受控制,或者嵌入了可能导致痛苦的元字符或逗号。但是,使用.split()
VMethod将标量提升为数组非常简单。
答案 1 :(得分:1)
以下是一种从命令行将任何数据传递到tpage
的方法,而无需调整tpage
来源或模板。
$ cat matrix.tt
[% DEFAULT
ncols = 3
elems = [1,2,3,4,5,6,7,8,9,10,11,12]
%]
\left[\begin{matrix}
[% WHILE elems.size %]
[% elems.splice(0,ncols).join(' & ') %]
[% IF elems.size %]\\[% END %]
[% END %]
\end{matrix}\right]
$ cat <(echo '[% elems=["x","y","z",1,2,3] %]') matrix.tt |tpage --pre_chomp --post_chomp
\left[\begin{matrix}x & y & z\\1 & 2 & 3\end{matrix}\right]
$
或者如果您愿意,您可以输入指令来设置变量并按^ D:
$ rlwrap cat - matrix.tt |tpage --pre_chomp --post_chomp
[%
ncols=4
elems=[4,5,6,7,"x","y","z","t"]
%]
\left[\begin{matrix}4 & 5 & 6 & 7\\x & y & z & t\end{matrix}\right]
$
rlwrap
保存您输入的行,然后按up
键使其可用。如果您不需要,可以删除rlwrap
。
该方法适用于任何可以处理stdin
的程序,因为shell支持这种重定向。我希望它非常便携。
答案 2 :(得分:0)
tpage
的命令行参数不会被评估为Perl代码,因此您只能获取字符串值。如果您想支持任意Perl代码,则必须破解tpage
源代码。
在源代码中找到以下行:
my %ttopts = $config->varlist('^template_(?!directive_)', 1);
在下一行中,添加以下代码:
foreach my $var (keys %{ $ttopts{variables} }) {
$ttopts{variables}{$var} = eval $ttopts{variables}{$var};
die $@ if $@;
}
这将循环遍历--define
的所有参数并在其上调用eval
,将它们从字符串转换为Perl代码。
当你运行它时,请确保引用你的参数以保护它们不被shell扩展:
$ ./tpage --define 'array=["foo","bar"]' --define 'hash={baz=>"qux"}' foo.tt
$VAR1 = [
'foo',
'bar'
];
$VAR1 = {
'baz' => 'qux'
};
$ cat foo.tt
[% USE Dumper %]
[% Dumper.dump(array) %]
[% Dumper.dump(hash) %]
要传递文字字符串,您必须使用q{}
或qq{}
引用它,因为AppConfig会删除常规引号(tpage
在后台使用AppConfig来读取命令行参数)。例如:
$ ./tpage --define 'string=q{foo}' foo.tt
$VAR1 = 'foo';
$ cat foo.tt
[% USE Dumper %]
[% Dumper.dump(string) %]
请注意,尽管Template Toolkit支持几乎任何Perl类型的变量,但我的tpage
修改版本并不适用。数字,字符串,数组和散列都应该起作用;子程序不是。