Ifx 和行尾

Ifx 和行尾

有人能解释一下吗?我有一个有趣的问题,涉及“这里没有结束的行”错误。

编辑:变量。我没有想到要包含这个,因为我认为只有一种方法可以声明变量。

\newcommand{\@emptymacro}{}% Used to test against an empty macro


\newcommand{\@name}{}
\newcommand{\name}[1]{\renewcommand{\bfseries \@name{#1}}}

\newcommand{\@descr}{}
\newcommand{\descr}[1]{\renewcommand{\itshape \@descr{#1}}}


\newcommand{\@note}{}
\newcommand{\note}[1]{\renewcommand\@note{#1}}

我定义了以下命令,它在最常见的用例下有效。

\newcommand{\makenamedentry}{
    \ifx\@name\@emptymacro
    \else
        {\color{black}\sffamily\bfseries \@name}\\ % print the entry name
        \vspace{1.5pt plus 0.5pt minus 0.5pt}
    \fi
    \ifx\@descr\@emptymacro
    \else
        {\@descr} % print description
    \fi

    \ifx\@note\@emptymacro
    \else
        {\@note} % print note
    \fi
}

这是最常见的实现。关键是它被命名了。

\name{My Name}
\descr{My Descr}
\note{My Note}
\makenamedentry

我最近尝试将其用于一个没有名称的一次性案例。它导致了“此处没有行结束”错误。

\name{}
\descr{My Descr}
\note{My Note}
\makenamedentry

经过一些测试,我发现这个没有错误。不幸的是,这对我来说是一个不可接受的解决方案,因为向使用最终产品的人解释起来太复杂了。所以我需要首先弄清楚为什么我会得到这个错误。

% used line, either comment or paragraph
\name{}
\descr{My Descr}
\note{My Note}
\makenamedentry

\\现在我认为这与的第 4 行有关newcommand,因为那是唯一的行尾字符。我不明白的是,为什么它会尝试在没有提供名称的情况下执行。也许 存在\\于正常逻辑结构之外?我不确定。

------------------------------------------------------------------------------------------------------请回答以下这条线----------------------------

我已编辑此帖子以使解决方案更加清晰。

虽然问题是关于 ifx 的,但我遇到问题的原因是我对空性的测试很糟糕。这使我的代码运行了这个\else案例(我把所有的逻辑都颠倒过来了),尽管我认为不是这样。

原因是 \name{} 与 不同\name{null}。我不确定为什么会这样,而且为什么\@emptymacro为 null 而\name{}不是,我也说不清。无论如何,我的解决方案是\@emptymacro按照 的方式构造\@name。为了记录,我几乎将所有内容都写入 .cls 文件中,因此这些命令确实有效。@如果将它们取出, 字符会破坏它们,因为它是保留字符。如果您想自己实现它们,只需将 重命名\@为即可\at

\newcommand{\@emptymacro}{}% Used to test against an empty macro
\newcommand{\emptymacro}[1]{\renewcommand\@emptymacro{#1}}
\emptymacro{}

\newcommand{\@name}{}
\newcommand{\name}[1]{\renewcommand\@name{#1}}

\newcommand{\@note}{}
\newcommand{\note}[1]{\renewcommand\@note{#1}}

\newcommand{\@descr}{}
\newcommand{\descr}[1]{\renewcommand\@descr{#1}}

通过让它们扩展为相同的东西,这使我能够使用 ifx 进行测试(在此处定义https://en.wikibooks.org/wiki/TeX/ifx

答案1

您的代码正在\ifx运行。如果您不提供发生错误的 MWE,我们就无法猜测任何事情。

但您的代码包含许多对 LaTeX 的误解。我将您的结果重写为 TeX 基元,以便更清楚地了解发生了什么。

(1)当 name 非空时,结果为:

\indent NAME\hfil\break
\vadjust{\vskip1.5 pt plus.5pt minus.5pt}\space DESCRIPTION \par

\indent NOTE

\hfil\break结束 NAME 所在的段落的第一行(这大致就是\\宏的扩展)。 段落的第二行以 开始\vadjust(这大致就是\vspace宏的扩展)。\vadjust命令将空格段落第二行之后,表示在描述的第一行和第二行之间。如果描述只有一行长,那么段落后面会有垂直空间。段落在描述末尾结束(TeX 会\par在代码中的空行处插入)。最后,新段落以注释开始。

请注意,如果非零,则 NAME 和 NOTE 之前会有缩进,但 STRACTION 之前不会有缩进。只有一个空格位于 STRACTION 之前(它来自使用\parindent行的末尾)。\vspace

请注意,第二段尚未完成。这意味着如果你输入

\makenamedentry 
something more` 

那么文本something more将被附加到第二段与注释相同的行。

(2)当 NAME 为空时,您将获得:

\indent DESCRIPTION\par

\indent NOTE

简单的两段就到这里。当然,第二段还没有结束。

我想你需要这样的东西:

\newtoks\name \newtoks\descr \newtoks\note
\def\makenamedentry{\par
    {\bf \the\name}\par
    \ifx^\the\name^\else \vskip 1.5pt plus.5pt minus.5pt \fi
    \the\descr\par
    \the\note\par
}

\name{My Name}
\descr{This is a description}
\note{some note}
\makenamedentry

相关内容