有人能解释一下吗?我有一个有趣的问题,涉及“这里没有结束的行”错误。
编辑:变量。我没有想到要包含这个,因为我认为只有一种方法可以声明变量。
\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