当我的宏在某些位置使用时出现“Extra \else”错误

当我的宏在某些位置使用时出现“Extra \else”错误

我正在编写一个群论文档,其中需要多次提及数学集合。我有一个工作宏,它扩展\fn f:D->Rf:\set D \mapsto \set R,并且我已替换\in,使得x \in Z扩展为x \oldin \set Z(\oldin 已由 \let 改为 \in)。

现在,我正在努力弄清 的定义\set。目的是轻松捕捉“我的”集合(例如 D(域)和 R(范围))与“标准”集合(例如 Z(整数)和 R(实数))之间的差异。(请注意,“R”出现在两个上下文中。)

为了做到这一点(作为一个完全的 TeX 新手),我想我可以使用\set D\set R来作为我想要的集合名称,\mathcal并将\set ZZ\set RR用作\mathbb

这有效:

\documentclass{minimal}
\usepackage{amsmath}
\usepackage{amssymb}

\def\set#1#2{\ifx#1#2\mathbb #1\else\mathcal #1 #2\fi}

\begin{document}
\begin{align}
A \mapsto \set A BB \mapsto \set BB\\
C \mapsto \set C\\
DD \mapsto \set DD\\
\end{align}

\(\set Z\)
\(\set YY\)
\end{document}

并产生:

工作样本

(这个想法是,在 的情况下\set RR,#1 和 #2 都是 'R',因此扩展为 ,\mathbb R而在 的情况下\set R,#1 将是 'R',但 #2 将是下一个标记( \set 不应该对其执行任何操作)因此扩展为\mathcal R并“重新发出”#2。)

但当我尝试时:

\(\set Z \set ZZ\)

我收到以下错误:

! Extra \else.
\set #1#2->\ifx #1#2\mathbb #1\else
                                    \mathcal #1 #2\fi
l.17 \(\set Z \set Z
                    Z\)    

如果我完全以错误的方式进行操作,请告诉我更好的解决方案(我想学习 TeX 的“正确”方法),但无论如何,我仍然想了解我在这里做错了什么以及如何解决它。


编辑以添加上下文

我正在研究一篇关于群论的文章,​​并将我的个人总结/笔记保存在 emacs org-mode 文件中以供以后参考。我的文件中的摘录曾经如下所示:

* Group Theory
  ** Functions
    - A function \(f:\mathcal{D}\mapsto\mathcal{R}\) maps /every/ \(x\in\mathcal{D}\) to /exactly one/ \(y\in\mathcal{R}\).

尽管它可以很好地呈现为 PDF,但对于我来说,以纯文本形式阅读却很困难。它现在看起来像这样:

* Group Theory
  ** Functions
    - A function \(\fn f:D->R\) maps /every/ \(x \in D\) to /exactly one/ \(y \in R\).

答案1

您不应通过将以下标记作为参数吞掉来删除它。\futurelet而是使用 ,并且只有当它们相同时才删除该标记。有一个非常方便的 LaTeX 包裹它,称为\@ifnextchar

\documentclass{article}
\usepackage{amsmath,amssymb}

\makeatletter
\def\set#1{%
  \@ifnextchar{#1}{\mathbb{#1}\@gobble}{\mathcal{#1}}%
}
\makeatother

\begin{document}
\(\set Z \set ZZ\)
\end{document}

在此处输入图片描述

答案2

你的错误是

#2\fi}

#2是什么时候\set

... \set\fi...

因此下次调用时\set #1 事情\fi就会变糟。

在执行真或假分支之前,最好将扩展\fi(为无),如果这样做,则重新插入后的标记#2将是来自原始源的标记。

这就是您通常会在发布的示例\expandafter中看到的原因。\if...

下面的代码可以满足您的要求,但您不应该使用它,因为它会给出一个严重的错误,\set R}因为}会阻止它拾取第二个参数,并且它破坏了 latex 语法,没有命令应该有可变数量的强制参数。\set RR, \set R最好用和的\seta R, \setb R简单定义标记为和\seta\setb\mathbb\mathcal

\documentclass{minimal}
\usepackage{amsmath}
\usepackage{amssymb}

\makeatletter

\def\set#1#2{%
\ifx#1#2\mathbb{#1}\expandafter\@gobble\else
\mathcal{#1}\expandafter\@firstofone\fi
{#2}}
\makeatother

\begin{document}
\begin{align}
A \mapsto \set A BB \mapsto \set BB\\
C \mapsto \set C\\
DD \mapsto \set DD\\
\end{align}

\(\set Z\)
\(\set YY\)
\end{document}

答案3

如果您希望您的定义起作用,请添加一个空参数:

%\documentclass{article}
\documentclass{minimal}
\usepackage{amsmath}
\usepackage{amssymb}

\def\set#1#2{\ifx#1#2\mathbb #1\else\mathcal #1 #2\fi}

\begin{document}
\begin{align}
A \mapsto \set A BB \mapsto \set BB\\
C \mapsto \set C\\
DD \mapsto \set DD\\
\end{align}

\(\set Z\)
\(\set YY\)

$\set Z{} \set ZZ$
\end{document}

您在另一个答案中找到了更好的解决方案。

相关内容