奇怪的行为:在同一环境中运行两次相同的命令与在两个环境中分别运行一次的行为不同

奇怪的行为:在同一环境中运行两次相同的命令与在两个环境中分别运行一次的行为不同

编辑前言:很惊讶这个问题没有被否决,因为这个问题写得真的很糟糕......这是我在编码了一整天后,在凌晨 2 点不假思索地发布的帖子的结果......对不起大家。

我已经确定了错误的性质,尽管我不知道为什么空白环境有帮助,所以我完全重写了这个问题,以便它很清楚,包括一个有用的 MWE。

问题

似乎 \begin 环境将逻辑检查重置为 false?

观察下面的代码:

\documentclass[]{article}

\newif\iffooLogic
\fooLogicfalse

\newcommand{\fooCommand}{
%Don't include \fooLogicfalse here to make the problem
\iffooLogic
    {The First Is True!}
\else
    {The First is False!}
\fi

%Set \fooLogic to true for next line
\fooLogictrue

\iffooLogic
    {The Second is True!}
\else
    {The Second is False!}
\fi
% No reset of \fooLogic to false to create problem.
}

\newenvironment{testOne}{•}{•}
\newenvironment{testTwo}{•}{•}

\begin{document}


First let's do two in the same environment:

\begin{testOne}
\fooCommand 

\fooCommand
\end{testOne}


Now, nested empty environments

\begin{testOne}
%First
    \begin{testTwo}
    \fooCommand 
    \end{testTwo}

%Second
    \begin{testTwo}
    \fooCommand
    \end{testTwo}

\end{testOne}

\end{document}

输出:

First let’s do two in the same environment:
The First is False!
The Second is True!
The First Is True!
The Second is True!
Now, nested empty environments
The First is False!
The Second is True!
The First is False!
The Second is True!

请注意(因为我从未将 \fooLoggic 重置为 false)第一个环境将第一个环境返回为 false,而将所有其他环境返回为 true。

但是,当我嵌套一个空环境时(如第二个环境示例),它会分别执行一次 false 和一次 true。因此,退出空环境似乎会重置 \fooLogic 检查。

  1. 这是因为命令 \fooCommand 中的逻辑设置上缺少 \global 命令吗?

  2. 这仅仅是重置它们的环境,还是因为我退出了任何类型的 shell(环境、命令、for 循环等),导致该值在没有 \global 的情况下被重置?

希望这更具可读性/合理性。睡眠很有帮助。

答案1

  1. .tex 输入文件中被标记为字符标记的内容后面的空格被标记为空格标记,从而在 pdf 文件中产生(通常是不需要的)水平空格。

  2. \newcommand{foo}...不行。一定得\newcommand{\foo}...

  3. \newenvironment{foo} ...粗略地说,定义命令\foo\endfoo并且\begin{..}- \end{..}- 机制在本地范围/组内执行这些命令。因此\newenvironment{foo}{..}{..}...\newcommand\foo{...会产生已定义的错误\foo

  4. fooCount未定义。

  5. \input(FILE)应该是这样的\input{FILE}。(La)TeX 通常使用花括号而不是圆括号来表示宏参数。

  6. 如果您的输入文件使用,\ifthenelse那么应该加载提供该命令的包。

  7. 如果一个文件被加载多次\input,那么它不应该包含,\newcommand因为在第二次加载时这会引发有关所讨论的控制序列已被定义的错误。

说了这些之后,下面的代码可能在一定程度上能够满足您的要求:

\documentclass{article}

% Here comes David Kastrup's \replicate macro, see
% <http://www.gust.org.pl/projects/pearls/2005p/david-kastrup/bachotex2005-david-kastrup-pearl3.pdf>
\newcommand\recur[1]{\csname rn#1\recur}%
\newcommand\rnm[1]{\endcsname{#1}#1}\newcommand\rn[1]{}
\newcommand\replicate[1]{\csname rn\expandafter\recur
\romannumeral\number\number#1 000\endcsname\endcsname}


%Let's create file.tex that executes 500 \goo{5}:
\begin{filecontents*}{file.tex}
%% Let's do 500 `\goo{5}`:
\replicate{500}{\goo{5}}%
\endinput
\end{filecontents*}

\usepackage{ifthen}

\newcounter{fooCount}

\newcommand{\goo}[1]{%
  \ifthenelse{#1 = 5}{%
    \stepcounter{fooCount}% Keep track of how many times #1 is 5
    %SomeCode
  }{}%
}%

\newenvironment{foo2}{%
  (This has some code that will hide some output, but not
   suppress it from running in the code)%
  \ignorespaces
}{\ignorespacesafterend}%

\newcommand{\foo}{%
  \input{file.tex}% FILE has a bunch of "\stepcounter{fooCount}"
  \arabic{fooCount}%
  \setcounter{fooCount}{0}%
}%

\newenvironment{foo3}{\ignorespaces}{\ignorespacesafterend}

\begin{document}

\begin{foo2}
\foo
\foo
\end{foo2}

\begin{foo2}
\begin{foo3}
\foo
\end{foo3}
\begin{foo3}
\foo
\end{foo3}
\end{foo2}

\end{document}

顺便一提:

许多 LaTeX 文档需要编译多次(至少两次)直到\tableofcontents和所有引用和超链接(就\label{..}\ref{..}\pageref{..}而言)起作用。如果您希望随机创建文档文本的部分,您需要确保随机数仅在第一次编译期间完成,然后保留以供后续编译

否则你可能会得到一个永无止境的故事:

  1. (La)TeX-run 产生(另一个)随机结果。
  2. 其他随机化结果产生其他文本。
  3. 其他文本产生其他分页。
  4. 其他分页方式产生其他页码。
  5. 其他页码需要另一次 (La)TeX 运行才能获得\tableofcontents并匹配\label\ref您回到 1。

相关内容