newcommand 不能与 \fi 一起使用

newcommand 不能与 \fi 一起使用

我尝试了该命令\newcommand{\fistudenti}{\fi} ,但它似乎只在某些情况下正常工作。下面是它工作和不工作的两个例子:

作品:

\documentclass[0pt]{book}
\usepackage[english]{babel}
\def\PentruStudenti{1}
\newcommand{\fistudenti}{\fi} 
\begin{document}              
\if\PentruStudenti1
show
\fistudenti
\end{document}   

但如果我把\PentruStudenti{0}它放进去就不起作用了:

\documentclass[0pt]{book}
\usepackage[english]{babel}
\def\PentruStudenti{0}
\newcommand{\fistudenti}{\fi} 
\begin{document}              
\if\PentruStudenti1
show
\fistudenti
\end{document}   

我哪里做错了?

答案1

条件原语 \if..\else并且\fi需要直接对 TeX 可见,不能隐藏在宏中。如果 TeX 发现一个错误\if..子句,它会查看所有后续标记,直到找到一个等于\else\fi 没有扩展宏。如果发现另一个\if..条件,它会增加内部计数器,并\fi在查找外部条件之前查找此条件。

如果你有一个像这样的宏\newcommand{\fistudenti}{\fi}\fi隐藏了,并且找不到。同样适用\if..错误的条款。两者都适用于真的子句,因为那里的宏被正常扩展。

要使宏正常工作,您需要改用\let\fistudenti\fi,这将使\fistudenti标记与 相同。这也是定义 now 条件的\fi方式。它定义的和宏只需包含或。\newif\xxxtrue\xxxfalse\let\ifxxx\iftrue\let\ifxxx\iffalse

如需进一步了解,请查看问答什么是 \if?

答案2

其他答案已经解释了为什么你的方法\fistudenti不起作用。我想添加一种不同的方法来解决你的问题。

看来,您的\PentruStudenti用于界定有条件包含在您的文档中的部分,这取决于此宏的含义。

尽管

\if\PentruStudenti1
  <material for the students>
\fi

有效,您可以通过不同的方法获得更好的服务。

\newif

定义一个条件:

\newif\ifstudentsversion
%\studentsversiontrue    % new conditionals start false

...


\ifstudentsversion
  <material for the students>
\else
  <optional material not for the students>
\fi

然后,您可以取消注释该\studentsversiontrue行以获得与 相同的结果\def\PentruStudenti{1}

带参数的宏

\newif\ifstudentsversion
%\studentsversiontrue    % new conditionals start false
\makeatletter
\newcommand{\studentsversion}{%
  \ifstudentsversion
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}

...

\studentsversion{<material for the students>}
                {<material for the teacher>}

再次取消注释该\studentsversiontrue行将在打印第一个参数和第二个参数之间切换。

请注意,此方法可以与其他方法一起使用。具体使用哪种方法可能取决于材料的大小。

注释字符

使用好的编辑器,选择一个区域并在行首添加一些字符并不困难;在这个应用程序中,我选择在“仅限学生”部分前面加上前缀^^A

\documentclass{article}

\newcommand{\showstudents}{\catcode`\^^A=9 }
\newcommand{\hidestudents}{\catcode`\^^A=14 }
\hidestudents % default

\begin{document}
\showstudents

This material is seen by everybody.

^^A This material, instead,
^^A is seen only when so
^^A decided.

And this material always shows.
\end{document}

如果该\showstudents行被注释掉,则该^^A组合将被视为注释字符,与 完全相同%。如果没有注释,^^A将被忽略。

答案3

TeXBook 解释了这种情况。

条件。当\if... 被展开时,TeX 会尽可能地向前读取以确定条件是真还是假;如果条件为假,它会向前跳转(跟踪\if...\fi嵌套)直到找到\else\or\fi来结束跳过的文本。

因此,在第一个例子中,测试为真,因此它扩展了该部分。在第二个例子中,测试为假;并且 TeX 搜索\fi

相关内容