在回答 另一个问题\def
,我在尝试使用和的组合时遇到了一些问题\char
。请考虑以下示例:
\documentclass{minimal}
\usepackage{etoolbox}
\usepackage{xstring}
\makeatletter
\def\title@A{a A}
\def\title@B{b B}
\def\gettitle#1{
\IfInteger{#1}{%
\def\@tmp{\char#1}%
\ifcsundef{title@\@tmp}{\@tmp}{\csname title@\@tmp\endcsname}%
}{%
\ifcsundef{title@#1}{#1}{\csname title@#1\endcsname}%
}
}
\begin{document}
\gettitle{65} \gettitle{A}
\gettitle{66} \gettitle{B}
\gettitle{67} \gettitle{C}
\end{document}
输出:
啊啊啊
乙乙
抄送
似乎\@tmp
不会扩展为单个字符,而是扩展为\char 65
,这在中不起作用\csname ... \endcsname
。我以为使用\edef\@tmp{\char#1}
会起作用,但似乎\char
是那些不会扩展的函数之一。
那么最后,是否有可能扩展\@tmp
到A
不是 \char 65
?
答案1
这可以通过以下技巧来实现 \lowercase
:
\documentclass{minimal}
\usepackage{etoolbox}
\usepackage{xstring}
\makeatletter
\begingroup
\catcode0=12 %
\gdef\chrdef#1#2{%
\begingroup
\lccode0=\numexpr(#2)\relax
\lowercase{\endgroup
\def#1{^^@}%
}%
}%
\endgroup
\def\title@A{a A}
\def\title@B{b B}
\def\gettitle#1{
\IfInteger{#1}{%
\chrdef\@tmp{#1}%
\ifcsundef{title@\@tmp}{\@tmp}{\csname title@\@tmp\endcsname}%
}{%
\ifcsundef{title@#1}{#1}{\csname title@#1\endcsname}%
}
}
\begin{document}
\gettitle{65} \gettitle{A}
\gettitle{66} \gettitle{B}
\gettitle{67} \gettitle{C}
\end{document}
\lowercase
(不可扩展命令)将参数字符标记转换为小写字符。这由 配置\lccode
。唯一的例外是零。如果\lccode
某个字符的 为零,则该字符保持不变。因此,示例使用代码为零的字符,可以用^^@
TeX 符号表示为。但是,此字符通常具有无效的类别代码,因此在外部组中将其更改为 12(其他)。由于 的更改\lccode
应在之后恢复,因此宏还使用一个组。
答案2
基\char
元不可扩展。在 XeTeX 和 LuaTeX 中,我们有\Uchar
,即,因此可以生成任何字符。对于只有 256 种可能结果的 pdfTeX,我们可以设置一个查找表。例如
\catcode`\@=11 %
\ifdefined\Uchar
\def\Xchar#1{%
\detokenize\expandafter{\Uchar\numexpr #1\relax}%
}
\else
\catcode`\^^@=12 %
\begingroup
\gdef\Xchar#1{%
\romannumeral-`\0\expandafter\Xchar@aux\expandafter{\numexpr #1\relax}%
}
\gdef\Xchar@aux#1{%
\ifcsname Xchar@\romannumeral #1\endcsname
\csname Xchar@\romannumeral #1\endcsname
\else
\errmessage{Character out of range}%
\fi
}
\count@=-1 %
\lccode`\X=`\X %
\loop
\advance\count@ by 1 %
\ifnum\count@<256 %
\lccode`\^^@ = \count@ %
\lowercase{%
\expandafter\gdef\csname Xchar@\romannumeral\count@\endcsname{^^@}%
}
\repeat
\endgroup
\fi
\catcode`\@=12 %
提供\Xchar
来完成这项工作。可以使用相同想法的更复杂版本来提供不同的类别代码字符,其实现方式如下\char_generate:nn
。expl3
(由于查找表是预先生成的,因此上述内容在使用时是可扩展的。)