使用 \ifx 测试参数值

使用 \ifx 测试参数值

假设我想重新定义,\@seccntformat以便每当打印部分计数器时,它都以 为前缀Section,但其他计数器不应更改。

这是我的失败的尝试:

\documentclass{article}

\makeatletter
\def\mytest{section}%
\def\myarg#1{#1}
\def\@seccntformat#1{%
  \ifx\myarg#1\mytest{Section}\fi%
  \csname the#1\endcsname\quad}
\makeatother

\begin{document}
\section{Foo}  % Should be printed as "Section 1  Foo"
\subsection{Bar}  % Should be printed as "1.1  Bar"
\end{document}

由于某种原因,当时我无法获取\myarg#1\mytest比较相等。这是我第一次使用,所以我希望我遗漏了一些琐碎的事情。#1section\ifx

我将非常感激有关如何调试此类宏的一些提示。有没有办法查看每个中间扩展步骤并观察\ifx实际接收的参数?

答案1

条件\ifx不进行扩展,而是比较接下来的两个标记。因此,在您的测试中,它\myarg与中的第一个标记进行比较#1

因此测试将始终为错误,因为它#1是部分级计数器的名称。

\expandafter在之前添加\ifx没有帮助,甚至在周围添加括号#1

\expandafter\ifx\myarg{#1}\mytest

会成为

\ifx section\mytest

s与相比,它返回​​ false e

您可以使用\pdfstrcmp(或者更好的是,\pdf@strcmp使用pdftexcmds包):

\def\@seccntformat#1{%
  \ifnum\pdf@strcmp{#1}{section}=\z@
    Section % a space is wanted
  \fi
  \csname the#1\endcsname\quad}

完整示例:

\documentclass{article}
\usepackage{pdftexcmds}

\makeatletter
\def\@seccntformat#1{%
  \ifnum\pdf@strcmp{#1}{section}=\z@
    Section %
  \fi
  \csname the#1\endcsname\quad}
\makeatother

\begin{document}
\section{Foo}  % Should be printed as "Section 1  Foo"
\subsection{Bar}  % Should be printed as "1.1  Bar"
\end{document}

在此处输入图片描述

请注意,尝试\ifx以以下方式进行比较

\def\section@argument{section}
\def\@seccntformat#1{%
  \def\@argument{#1}%
  \ifx\@argument\section@argument
    Section %
  \fi
  \csname the#1\endcsname\quad}

也行不通。这是因为\@seccntformat通过了\edef(格式为\protected@edef),所以我们会得到一个错误

Undefined control sequence

\@argument\noexpand在 前面添加\@argument不会有帮助,因为 期间条件被扩展了\edef。这反而会起作用

\def\section@argument{section}
\def\@seccntformat#1{%
  \unexpanded{%
    \def\@argument{#1}%
    \ifx\@argument\section@argument
      Section %
    \fi
  }
  \csname the#1\endcsname\quad
}

因为在 期间 的参数\unexpanded不会改变\edef,所以它将在之后涉及排版时进行处理。

请注意,是必需的,因为我们必须在执行宏时获取或的\protected@edef展开。一种免费解决方案是可能的,方法是将部分隐藏在宏中:\thesection\thesubsection\@seccntformat\unexpanded

\def\section@argument{section}
\def\check@section#1{%
   \def\@argument{#1}%
   \ifx\@argument\section@argument
     Section %
   \fi
}
\def\@seccntformat#1{%
  \noexpand\check@section{#1}%
  \csname the#1\endcsname\quad}

相关内容