考虑以下代码。使用xelatex
或lualatex
,它会产生三个相同的结果。但是,使用pdflatex
其中一个会产生错误。
主要的“宏”是一个 Unicode 字符ᵢ
,被定义为 的命令\newunicodechar
。作为比较,给出了另外两个具有类似定义的宏:
\TestA
第一个是直接使用的宏,\expandafter
需要一个才能\@ifnextchar
正常工作。- 第二个是另一个宏
\TestB
,稍后通过\csname...\endcsname
,并根据这个答案,\expandafter
这里需要三个。
使用 Unicode 引擎时,字符版本的行为似乎类似于\TestA
。但是,使用 时pdflatex
,一和三都\expandafter
不起作用。
\documentclass[border=5pt]{standalone}
\usepackage{newunicodechar}
\makeatletter
\newif\if@unisub\@unisubfalse
\newcommand{\@unisubA}{\if@unisub\else\sb\bgroup\fi}
\newcommand{\@unisubB}{\@ifnextchar\@unisubA{\@unisubtrue}{\egroup\@unisubfalse}}
\newunicodechar{ᵢ}{\@unisubA i \expandafter\@unisubB}
\def\testA{\@unisubA i \expandafter\@unisubB}
\def\testB{\@unisubA i \expandafter\expandafter\expandafter\@unisubB}
\makeatother
\begin{document}
$ᵢᵢᵢ$
$\testA \testA \testA$
$\csname testB\endcsname \csname testB\endcsname \csname testB\endcsname$
\end{document}
用 定义的字符的扩展规则是什么\newunicodechar
?
答案1
使用 unicode 引擎,该命令\newunicodechar{<char>}{<replacement>}
本质上
\catcode`<char>=\active
\protected\def<char>{<replacement>}
但可以以间接的方式与其原始类别代码一起<char>
使用。<replacement>
这样<char>
就变成了\protected
宏。
为了pdflatex
事情是不同的。如果n是的十六进制槽<char>
,那么上面的内容本质上与
\DeclareUnicodeCharacter{
n}{<replacement>}
并且\@ifnextchar<char>
会失败,因为<char>
必须是一个多字节字符,任何\expandafter
技巧都是如此。好吧,也许一些巧妙应用\expandafter
技巧可能工作。
您可以检查<char>
并确定它是标准 ASCII 还是以多字节前缀开头。在后一种情况下,您可以抓取指定数量的标记,进行扩展并希望获得最佳效果。