自动删除 \ifthenelse

自动删除 \ifthenelse

假设您有一个 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例如awkm4

\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)任意深度,所有注释%...都已被清空,既没有\includes 也\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 后,输出结果就是您所提议的。我认为这比您想要的要多。

您好!祝您下次会议顺利!

相关内容