假设您有一个 LaTeX 源文件,可以编译两类文档:主要会议论文及其扩展的长版本。在里面,您可以使用它\ifthenese
来生成两个版本。示例:
\RequirePackage{ifthen}
\documentclass{article}
\newboolean{techrep}
\setboolean{techrep}{false}
\begin{document}
\ifthenelse{\boolean{techrep}}{Stuff for the TR}{Stuff for the main paper}
\end{document}
是否可以通过某些脚本(sed
,,,,...)从这样的源中生成主要会议论文的源 LaTeX 文件?elisp
例如awk
:m4
\RequirePackage{ifthen}
\documentclass{article}
\newboolean{techrep}
\setboolean{techrep}{false}
\begin{document}
Stuff for the main paper
\end{document}
你可以假设每次出现 时都会\ifthenelse
开始\ifthenelse{\boolean{techrep}}
(即,该宏仅用于单一目的),这些出现可以嵌套多达两层,并且该命令的两个参数可以是任意大小:空、一个单词、几个单词或多行,包括空行。该命令\ifthenelse{...}{...}{...}
本身可以在一行中的任何位置开始,并在同一行或不同行中的任何位置结束。你可以假设所有括号{
}
都正确嵌套,这种嵌套可以在 LaTeX 源代码的任何位置(包括 的两个分支\ifthenelse
)任意深度,所有注释%...
都已被清空,既没有\include
s 也\input
没有 s ,并且行尾标记遵循 UNIX 约定。
理想情况下,如果给出了错误的参数数量,你的脚本应该会抛出一个错误\ifthenelse
,例如
\ifthenelse{\boolean{techrep}}{A}%
More text
答案1
Vim 中的正则表达式,在其他程序中可能类似:
:%s/\\ifthenelse{[^}]*}{\([^}]*\)}{\([^}]*\)}/\1
这样将保留第一个分支;如果要保留第二个分支,请更改\1
为\2
。
答案2
按照 PhelypeOleinik 的想法,但不必注释所有行,也许 perl 脚本srcredact
(TeXLive 2019 的一部分)可以提供帮助。这是我修改的示例文件(MdAyq6-doc.tex
):
%<*ALL>
\documentclass{article}
\begin{document}
Common text
%</ALL>
%<*techrep>
Stuff for the TR
%</techrep>
%<*maindoc>
Stuff for the main paper
%</maindoc>
%<*ALL>
\end{document}
%</ALL>
现在从命令行:
[pablo@worktex forum] $ srcredact -l MdAyq6-doc.tex
ALL
maindoc
techrep
[pablo@worktex forum] $ srcredact -e techrep MdAyq6-doc.tex
\documentclass{article}
\begin{document}
Common text
Stuff for the TR
\end{document}
[pablo@worktex forum] $ srcredact -e maindoc MdAyq6-doc.tex
\documentclass{article}
\begin{document}
Common text
Stuff for the main paper
\end{document}
[pablo@worktex forum] $ srcredact -e ALL MdAyq6-doc.tex
\documentclass{article}
\begin{document}
Common text
\end{document}
这里我们在屏幕上看到了输出,如果我们想生成输出文件,只需> file.tex
在行尾添加即可。如下所示:
$ srcredact -e techrep MdAyq6-doc.tex > techrep.tex
并且文件techrep.tex
将被创建。
\documentclass{article}
\begin{document}
Common text
Stuff for the TR
\end{document}
它不如 docstript 那么强大,但是功能却很强大。
编辑
如果想法是删除使用常用表达,这并不容易,里面的转义括号很乱,但是,可以使用Perl
:)。假设输入文件的语法有效,rmifthen.pl
则可以使用以下脚本:
#!/usr/bin/env perl
use v5.26;
use autodie;
use File::Basename;
use open ':locale';
## Args
@ARGV == 1 or die "Use: $0 <file (La)TeX to be processed>\n";
my $input_file = shift;
-f $input_file or die "ERROR: Can't find [$input_file]\n";
## Extension
my @SuffixList = ('.tex', '', '.ltx');
my ($name, $path, $ext) = fileparse($input_file, @SuffixList);
$ext = '.tex' if not $ext;
## Read file
open my $TEXINPUT, '<', $input_file;
my $ltxfile;
{
local $/;
$ltxfile = <$TEXINPUT>;
}
close $TEXINPUT;
## Change escaped braces to a character that is not in the text
$ltxfile =~ s/\\[{]/«/g;
$ltxfile =~ s/\\[}]/»/g;
## Two groups of captures: the complete ifthenelse, and the true ifthenelse.
my $ifthenelse = qr/
(
\\ifthenelse (?&condicion_rx)\s*
(?<expVerdadero> (?&expVerdadero_rx)\s*)
(?&expFalsa_rx)
)
(?(DEFINE)
(?<condicion_rx> (?&texto_rx))
(?<expVerdadero_rx> (?&texto_rx))
(?<expFalsa_rx> (?&texto_rx))
(?<texto_rx> ( [{] (?: [^{}]++ | (?-1) )*+ [}] ) )
)
/sx;
## We look for ifthenelse throughout the document
my @posiciones;
# Every time we find an ifthenelse mark, we keep the initial, final
# position of the whole mark, And the text of the true clause
while ($ltxfile =~ /$ifthenelse/g) {
push @posiciones, [ $-[1], $+[1], $+{expVerdadero} ];
}
## We replace the whole ifthenelse brand, with the true expression, except the braces
for my $pos_ref (reverse @posiciones) {
substr($ltxfile, $pos_ref->[0], $pos_ref->[1] - $pos_ref->[0])
= substr $pos_ref->[2], 1, -2;
}
## We recovered the escaped braces.
$ltxfile =~ s/«/\\{/g;
$ltxfile =~ s/»/\\}/g;
## Write file
open my $SALIDA, '>', "$name-out$ext";
print $SALIDA $ltxfile;
close $SALIDA;
__END__
使用此示例文件:
\RequirePackage{ifthen}
\newboolean{techrep}
\setboolean{techrep}{false}
\begin{document}
\ifthenelse{\boolean{techrep}}{Este es texto
con el que {deseo quedarme} incluidas las llaves \{ que no están
escapadas dentro de el, pero sin las llaves exteriores
}{Este es texto NO lo deseo, también {puede llevar llaves} \}
que no están escapadas} %
TEXTO TEXTO
TEXTO TEXTO \ifthenelse{\boolean{techrep}}{Otro texto
con el que \{deseo quedarme\} incluidas las llaves \{ \}
que no están escapadas
}{Este es texto {NO lo deseo}, también puede llevar llaves \{
que no están \} escapadas}
TEXTO TEXTO TEXTO
\end{document}
跑步:
perl rmifthen.pl file.tex
我们得到:
\RequirePackage{ifthen}
\newboolean{techrep}
\setboolean{techrep}{false}
\begin{document}
Este es texto
con el que {deseo quedarme} incluidas las llaves \{ que no están
escapadas dentro de el, pero sin las llaves exteriores %
TEXTO TEXTO
TEXTO TEXTO Otro texto
con el que \{deseo quedarme\} incluidas las llaves \{ \}
que no están escapadas
TEXTO TEXTO TEXTO
\end{document}
使用 MWE 后,输出结果就是您所提议的。我认为这比您想要的要多。
您好!祝您下次会议顺利!