我正在编写一个小包,其中包含我打算经常使用的宏。在这些宏中,我具有\mailto
以下定义:
\@ifpackageloaded{hyperref}{%
\def\mailto#1{%
\href{mailto:#1}{\nolinkurl{#1}}%
}%
}{%
\def\maitlo#1{%
\url{#1}%
}%
}
我想要做的是重新定义@
和.
激活字符,这样就[email protected]
变成了xxx<at>yyy<dot>zzz
。我尝试了以下方法:
\def\mailto#1{%
\begingroup
\catcode`@=13
\catcode`.=13
\def@{$\langle$at$\rangle$}
\def.{$\langle$dot$\rangle$}
\url{#1}
\endgroup
}
但我得到了:
! Undefined control sequence.
\mailto ...e `@=\active \catcode `.=\active \def@
{$\langle $at$\rangle $} \...
l.XXX \mailto{[email protected]}
为什么?
答案1
您的代码存在一些问题。TeX 读取参数时,类别代码会固定,因此读取任何更改过的代码都很棘手。这既适用于\def.
inside的使用\def\mailto
,也适用于在更改类别代码之前获取参数的方式\mailto
。这可能会导致您出现类似
\begingroup
\catcode`\@=\active
\catcode`\.=\active
\gdef\mailto{%
\begingroup
\catcode`\@=\active
\catcode`\.=\active
\gdef@{$\langle$at$\rangle$}%
\gdef.{$\langle$dot$\rangle$}%
\mailtoaux
}
\gdef\mailtoaux#1{%
\endgroup
#1%
}
\endgroup
请注意,我已经拆分了用于的组\mailto
,以便它在我抓取参数之前开始,并在我抓取参数之后结束。
但是,这不适用于 URL,因为url
包会逐字读取。无论如何,我会避免使用主动字符(实际上不需要),而是使用搜索和替换。我会使用类似
\newcommand*{\mynil}{\mynil}
\newcommand*{\mailto}[1]{%
\mailtoauxi#1@\mynil@\stop
}
\def\mailtoauxi#1@#2@#3\stop{%
\ifx\mynil#2%
\ERROR
\else
\mailtoauxii#1<at>#2.\mynil.\stop
\fi
}
\makeatletter
\def\mailtoauxii#1.#2.#3\stop{%
\ifx\mynil#2%
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\url{#1}}%
{\mailtoauxii#1<dot>#2.#3\stop}%
}
\makeatother
正如我所说的,\url
故意逐字打印,因此要获得所需的数学模式替换将需要做更多的工作!