与我之前的问题略有相关(在 Windows 上使用当前 TeXlive 输出 PerlTex), 我已经设法使用 PerlTeX(准确地说,使用选项 --latex=lualatex)生成 .pdf 文件。
充分利用这个奇妙的工具的下一步是能够将它与我已经在使用的其他工具一起使用并自动创建文档。
正如 PerlTeX 文档第 8 页所述,我正在使用以下选项编译文档:
--latex=lualatex --makesty
这样,文件 noperltex.sty 就创建好了。然后,注释掉 \usepackage{perltex} 并添加 \usepackage{noperltex} 后,该文档可以仅使用 lualatex 进行编译,而不需要 perltex 进行编译。如果我需要编译文档两次,但首先使用 perltex,然后仅使用 lualatex,有没有办法,如何有条件地做到这一点?
如果可以的话,如果有涉及 arara 的解决方案并且能够自动编译就太好了。
我已经为 arara 创建了一条规则以与 perltex 协同工作(这是我的第一次尝试,基于 biber 规则和 pythontex 规则,所以非常基础),如果是 arara 解决方案,请考虑下一个代码:
perltex.yaml
!config
# perltex rule for arara
# author: Tomas Krulis based on Uwe Ziegenhagen
# requires arara 4.0+
identifier: perltex
name: perltex
commands:
- name: PerlTeX for advanced string manipulation
command: >
@{
return getCommand('perltex', options, getBasename(file));
}
arguments:
- identifier: options
flag: >
@{
if (isList(parameters.options)) {
return parameters.options;
}
else {
throwError('I was expecting a list of options.');
}
}
为了进行测试,请考虑下一个 MWE:
% arara: perltex: { options: [ '--latex=lualatex', '--makesty' ] }
% arara: lualatex
\documentclass[11pt]{article}
\usepackage{fontspec}
\usepackage{xcolor}
\usepackage[optional]{perltex}
%\usepackage{noperltex}
\ifperl
\perlnewcommand{\reversewords}[1]{join " ", reverse split " ", $_[0]}
\perlnewcommand{\hilbertmatrix}[1]{
my $result = '
\[
\renewcommand{\arraystretch}{1.3}
';
$result .= '\begin{array}{' . 'c' x $_[0] . "}\n";
foreach $j (0 .. $_[0]-1) {
my @row;
foreach $i (0 .. $_[0]-1) {
push @row, ($i+$j) ? (sprintf '\frac{1}{%d}', $i+$j+1) : '1';
}
$result .= join (' & ', @row) . " \\\\\n";
}
$result .= '\end{array}
\]';
return $result;
}
\else
\newcommand{\reversewords}[1]{\color{red} #1}
\newcommand{\hilbertmatrix}[1]{\color{red} #1}
\fi
\begin{document}
\reversewords{Try doing this without Perl!}
\clearpage
\hilbertmatrix{20}
\end{document}
请注意,该文档可以“正常工作”,但这要归功于条件 \ifperl,它只是将任何 perlcommand 参数设置为红色文本。所需的行为是使用 perltex 和 \usepackage{perltex} 进行编译,然后有条件地切换到 \usepackage{noperltex},当文档仅使用 lualatex 进行编译时;因此 \ifperl 的 \else 部分不会被触发。
非常感谢您针对这个可能有些奇怪的问题提出见解。
编辑:根据 Fischer 女士的建议更新了 MWE,以使用条件 \IfFileExists 进行测试。使用 arara,在步骤 2 中,在“仅”luaLaTeX 编译中,我仍然在使用 \perlnewcommand 时收到“未定义的控制序列”错误;这让我认为 \usepackage{noperltex} 仍然未被拾取。
更有趣的是,如果我仅使用 PerlTeX 按照 MWE 进行编译,我会得到同样的错误。我在项目文件夹中已经有 noperltex.sty,其中包含代码,(我认为)它不涉及表单中 \perlnewcommands 的定义,可以由 lualatex 处理。
看起来 noperltex 是在 perltex 编译开始时创建的,这会阻止触发 \IfFileExists 的 else 部分。这是您遇到的错误吗?还是故意的?
编辑的MWE:
% arara: perltex: { options: [ '--latex=lualatex', '--makesty', '--nosafe' ] }
% arara: lualatex: { shell: yes }
\documentclass[11pt]{article}
\usepackage{fontspec}
\usepackage{xcolor}
\IfFileExists{noperltex.sty}{%
\usepackage{noperltex}%
}%
{\usepackage[optional]{perltex}}
\perlnewcommand{\reversewords}[1]{join " ", reverse split " ", $_[0]}
\perlnewcommand{\hilbertmatrix}[1]{
my $result = '
\[
\renewcommand{\arraystretch}{1.3}
';
$result .= '\begin{array}{' . 'c' x $_[0] . "}\n";
foreach $j (0 .. $_[0]-1) {
my @row;
foreach $i (0 .. $_[0]-1) {
push @row, ($i+$j) ? (sprintf '\frac{1}{%d}', $i+$j+1) : '1';
}
$result .= join (' & ', @row) . " \\\\\n";
}
$result .= '\end{array}
\]';
return $result;
}
\begin{document}
\reversewords{Try doing this without Perl!}
\clearpage
\hilbertmatrix{20}
\end{document}
答案1
既然您正在使用arara
(谢谢!),那么以下方法怎么样:
让我们创建一个名为的新规则
writeconfig.yaml
,顾名思义,该规则根据提供的文本创建一个配置文件:!config identifier: writeconfig name: WriteConfig authors: - Paulo Cereda commands: - name: Writing the configuration file command: > @{ writeToFile(toFile(input), text + '\n', append); return true; } arguments: - identifier: input flag: > @{ return parameters.input; } required: true - identifier: append flag: > @{ return isTrue(parameters.append); } default: false - identifier: text flag: > @{ return parameters.text; } required: true
该规则至少需要两个参数,即:
input
(必填):我们的配置文件的名称。text
(必填):需要写入的文本。append
(可选):一个标志,指示是否应附加或覆盖内容(默认行为是覆盖内容,因为我们想利用这个细节)。
在修订版 2 之前,
arara
4.0 在处理布尔值作为命令的返回类型时有一个错误(如问题中所示)#128)。请确保arara
使用 TeX 发行版管理器至少更新到修订版 2,这样上述规则才会具有预期的行为。您可以在运行该工具时通过查看标题来检查修订版:arara 4.0 (revision 2)
更改您的文档并替换以下几行:
\usepackage[optional]{perltex} % for PerlTeX \usepackage{noperltex} % for LuaLaTeX
通过这个:
\input{config.cfg}
现在让我们创建新的指令:
% arara: writeconfig: { input: 'config.cfg', text: '\usepackage[optional]{perltex}' } % arara: perltex: { options: [ '--latex=lualatex', '--makesty' ] } % arara: writeconfig: { input: 'config.cfg', text: '\usepackage{noperltex}' } % arara: lualatex
玩得开心:
$ arara mwe.tex
__ _ _ __ __ _ _ __ __ _
/ _` | '__/ _` | '__/ _` |
| (_| | | | (_| | | | (_| |
\__,_|_| \__,_|_| \__,_|
Processing 'mwe.tex' (size: 1003 bytes, last modified: 09/10/2019
11:03:14), please wait.
(WriteConfig) Writing the configuration file ............ SUCCESS
(perltex) PerlTeX for advanced string manipulation ...... SUCCESS
(WriteConfig) Writing the configuration file ............ SUCCESS
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
Total: 2.60 seconds
希望能帮助到你!:)
编辑:我的建议是将writeconfig.yaml
和都保留perltex.yaml
在项目目录中。然后创建一个名为的文件arararc.yaml
(它是该文件的四个可能名称之一,我通常更喜欢这个)并将其添加到其中:
!config
paths:
- '.'
意思是先在当前项目目录下搜索规则,然后尝试arara
从这个层级运行。