如何正确使用 if 控制序列

如何正确使用 if 控制序列

我不明白为什么这段代码没有产生我在输出中描述的内容。

\documentclass{article}

\newcommand{\defaultvalue}{\textit{initialvalue}} %indentation pour les (sous)-questions non-numérotées
\newcommand{\mycounter}{\defaultvalue}
\newcommand{\inmain}{1}

\newcommand{\question}[2][\defaultvalue]{ %Question
        \textbf{Question #1 :} #2
    \ifx\inmain1 \renewcommand{\mycounter}{#1} \fi
}

\begin{document}                                
            mycounter has value \mycounter \\           
            \question[1.a)]{
            \textit{inmain} has value \inmain, therefore I would expect \textit{mycounter} to take value \textit{1.a)} after this.\\
            }
            However, \textit{mycounter} still has value \mycounter
\end{document}

在此处输入图片描述

这段代码被缩小了,以便只暴露我面临的问题。但是,为了预测替代建议,这里是它的底部,以防万一它有用。我正在尝试重写一个非常灵活的手动计数系统,以满足这里不相关的需求。我有一个\question命令和一个\subquestion调用的命令\question(这在我想重新设计某些东西时很有用)。这些命令有可选参数,可以启用手动编号,我希望子问题可以选择性地携带主问题的编号。因为\subquestion调用\question,我需要一个控制序列\question来确保在\subquestion调用时计数器不会改变\question。但它不起作用。

答案1

你有:

\ifx\inmain1 \renewcommand{\mycounter}{#1} \fi

\ifx触发token的扩展。\ifx仅比较token的含义。

\show\inmain收益\inmain具有以下含义:

> \inmain=\long macro:
->1.

\show1 收益1具有以下含义:

> the character 1.

含义是不是平等的...

顺便说一句:在将数字字符标记1为类别代码 12(其他)的显式字符标记后,(La)TeX 的读取装置处于状态 M(行中间)。因此,后面的空格字符1被标记为显式空格标记。(类别代码 10(空格)和字符代码 32 的显式字符标记。32 是 (La)TeX 内部字符编码方案中空格字符的代码点编号,在传统 TeX 引擎中为 ASCII,在基于 XeTeX 或 LuaTeX 的 TeX 引擎中为 UTF-8。)

如果条件为真,则后面的显式空格标记1将作为“真”分支的第一个标记传递。在水平模式/非受限水平模式下,它会产生水平粘连,这可能是不受欢迎的。

这同样适用于右花括号后面/之前的空格字符,\fi只是生成的显式空格标记将作为“真”分支的最后一个标记传递。

因此,真正的分支由一个显式空间标记、一个\renewcommand赋值和另一个显式空间标记组成。在水平模式/非受限水平模式下,两个显式空间标记都会产生水平粘合。

如果你想比较两个数字/两个 TeX-⟨数字⟩-我建议使用的数量\ifnum

\documentclass{article}

\newcommand{\defaultvalue}{\textit{initialvalue}} %indentation pour les (sous)-questions non-numérotées
\newcommand{\mycounter}{\defaultvalue}
\newcommand{\inmain}{1}

\newcommand{\question}[2][\defaultvalue]{%
  \textbf{Question #1 :} #2%
  \ifnum\inmain=1 %
    \renewcommand{\mycounter}{#1}%
  \fi
}

\begin{document}                                

mycounter has value \mycounter\\           
\question[1.a)]{%
  \textit{inmain} has value \inmain, therefore I 
   expect \textit{mycounter} to take value
   \textit{1.a)} after this.\\
}%
And voil\`a: \textit{mycounter} has value \mycounter.
\end{document}

在此处输入图片描述

使用\ifnum\inmain=1 %两个 TeX-⟨数字⟩-数量进行比较。当收集 TeX 的第一个标记时-⟨数字⟩-数量,以及收集更多 TeX 标记时-⟨数字⟩-数量最终会变成来自集合 {1,2,3,4,5,6,7,8,9,0} 的字符标记序列,扩展不会被抑制。因此,\inmain当 LaTeX 开始收集\ifnum的第一个 TeX-⟨数字⟩-数量。这将产生显式 catcode-12(other)-character-token 1,它将被用作集合 {1,2,3,4,5,6,7,8,9,0} 中字符标记序列的第一个元素。然后=找到 (explicit character-token of catcode 12(other)),这将终止收集属于该序列的更多数字的过程。不会=被丢弃。然后 LaTeX 开始收集 的\ifnum第二个 TeX-⟨数字⟩-数量。因此,后面的空格字符1也被标记为显式空格标记。但字符标记再次1被视为元素/属于集合 {1,2,3,4,5,6,7,8,9,0} 中的字符标记序列的第一个元素。因此,空格标记被视为终止收集属于该序列的更多数字的过程的事物。与
其他终止搜索更多 TeX- 数字的标记不同,⟨数字⟩-由集合 {1,2,3,4,5,6,7,8,9,0} 中的字符标记序列形成的数量,例如,=终止数字序列的显式空格标记将被默默丢弃/从标记流中删除。

\if关于原语和\ifcat工作原理的评论:

\if比较字符标记的字符代码。\if在进行比较之前,会触发可扩展标记的扩展。非隐式字符标记的不可扩展控制序列将被视为具有相同的字符代码,该字符代码与字符标记可能具有的所有字符代码不同。

\ifcat比较字符标记的类别代码。\ifcat在进行比较之前,会触发可扩展标记的扩展。非隐式字符标记的不可扩展控制序列将被视为具有相同的类别代码,该类别代码与字符标记可能具有的所有类别代码不同。

答案2

你的代码很奇怪,我没有太多时间详细解释。\ifx\inmain1如果你以前这样做过,那么结果会是真的\let\ifmain1,但事实并非如此(可能也不可取)。\ifx不会扩展后面的内容。你可以使用它\ifnum进行整数比较;\ifnum在查找 〈number〉 时扩展宏(参见 TeX 语法)。

由于您要打印 的值\inmain,因此我将首先在此处使用此技巧。请注意代码中的虚假空格,但请注意,\ifnum\inmain=1下面后面的空格是故意的并且很有用:根据 TeX 语法,它终止 〈number〉1。它不会出现在输出中。这是很好的做法,但您需要了解原因。

\documentclass{article}

\newcommand{\defaultvalue}{\textit{initialvalue}}
\newcommand{\mycounter}{\defaultvalue}
\newcommand{\inmain}{1}

\newcommand{\question}[2][\defaultvalue]{% Question
 \textbf{Question #1 :}~#2%
    \ifnum\inmain=1 \renewcommand{\mycounter}{#1}\fi
}

\begin{document}

mycounter has value \mycounter \\
\question[1.a)]{%
  \textit{inmain} has value \inmain, therefore I would expect
  \textit{mycounter} to take value \textit{1.a)} after this.\\
}
Indeed, \textit{mycounter} has value \mycounter.

\end{document}

在此处输入图片描述

更惯用的方法可能是用来\newif\ifinmain声明\inmaintrue\inmainfalse设置标志,并且\ifinmain ... \else ...\fi使用它(可选\else)。此外,你滥用了术语“计数器”(我的意思是,你的\mycounter宏不是 LaTeX 计数器),并且行

\newcommand{\mycounter}{\defaultvalue}

可能不会做你想要的(它将控制序列标记存储\defaultvalue为宏的替换文本\mycounter\mycounter不是此时展开)。如果你定义\defaultvalue为数字,你可能想要这样的东西:

\newcommand{\defaultvalue}{3}
\edef\mycounter{\defaultvalue}

如果您确实想要在的替换文本中格式化命令\defaultvalue,则可以使用:

\makeatletter
\newcommand{\defaultvalue}{\textit{3}}
\protected@edef\mycounter{\defaultvalue}
\makeatother

整理最后的建议得出:

\documentclass{article}

\makeatletter
\newcommand{\defaultvalue}{\textit{3}}
\protected@edef\mycounter{\defaultvalue}
\newif\ifinmain
\inmaintrue

\newcommand{\question}[2][\defaultvalue]{% Question
 \textbf{Question #1 :}~#2%
    \ifinmain\renewcommand{\mycounter}{#1}\fi
}
\makeatother

\begin{document}

mycounter has value \mycounter \\
\question[1.a)]{%
  \texttt{\textbackslash ifinmain} is \texttt{\textbackslash iftrue}, therefore
  \textit{mycounter} will take value \textit{1.a)} after this.\\
}
Indeed, \textit{mycounter} has value \mycounter.

\end{document}

在此处输入图片描述

但我再说一遍,这一切看起来有点奇怪。也许有更好的方法可以满足您的需要,也许是使用enumitem。我担心这是一个 XY 问题。

相关内容