以下是出现“ ”错误的示例! Improper alphabetic constant
:
%% this is ok
\newcount\mychar
\mychar=\number`a\relax
\showthe a % shows You can't use `the letter a' after \the
\showthe\mychar % shows 97
%% this is not ok
\let\Char=a
\showthe\Char % shows You can't use `the letter a' after \the
\mychar=\number`\Char\relax % here error comes
\showthe\mychar
设置计数器应该扩展到不可扩展的令牌(在本例中是\relax
)。问题:为什么\Char
不扩展?
答案1
\Char
不会展开,因为它不是可扩展的标记。与\def\Char{a}
哪个不同扩展定义a
\let
一个本质上是 a
并且好像a
它不会扩大。
在经典 TeX 中获取此信息的唯一方法是\meaning\Char
采用
the letter a
将其按空格分割,如果前两个单词是字母,则the letter
取其应有的字母a
,然后使用`a
您使用的语法。
查看bm
执行以下任一操作的软件包的源代码很多这个的:-)
工作示例(纯 TeX)
\newcount\mychar
\def\zz#1{%
% catcode 11 (letter)
\ifcat a#1%
\expandafter\zza\meaning#1 \relax
\else
%other cases here
-1
\fi}
\def\zza#1 #2 #3 #4\relax{`#3 }
\let\Char=a
\mychar=\zz{a}
\immediate\write20{a=\the\mychar}
\mychar=\zz{\Char}
\immediate\write20{\Char=\the\mychar}
\bye
产生一个日志
a=97
\Char =97
显示宏接受显式或隐式的字符标记。
答案2
这里有一个实现l3regex
;数字存储在其中\l_linuxss_code_int
以供稍后使用。
可以通过对搜索正则表达式进行操作来扩展测试;这个表达式可以捕获the letter
或the character
。
\documentclass{article}
\usepackage{xparse,l3regex}
\ExplSyntaxOn
\NewDocumentCommand{\getlettercode}{m}
{
\linuxss_getlettercode:N #1
\int_to_arabic:n { \l_linuxss_code_int } % just for testing
}
\int_new:N \l_linuxss_code_int
\tl_new:N \l_linuxss_meaning_tl
\regex_const:Nn \c_linuxss_search_regex { \A the \s (letter|character) \s }
\cs_new_protected:Npn \linuxss_getlettercode:N #1
{
\tl_set:Nx \l_linuxss_meaning_tl { \token_to_meaning:N #1 }
\regex_match:NVTF \c_linuxss_search_regex \l_linuxss_meaning_tl
{
\regex_replace_once:NnN \c_linuxss_search_regex { } \l_linuxss_meaning_tl
\int_set:Nx \l_linuxss_code_int { ` \l_linuxss_meaning_tl }
}
{
\int_set:Nn \l_linuxss_code_int { -1 }
}
}
\cs_generate_variant:Nn \regex_match:NnTF { NV }
\cs_generate_variant:Nn \int_set:Nn { Nx }
\ExplSyntaxOff
\begin{document}
\let\Chara=a
$\getlettercode{\Chara}=\number`a$
\let\Charz=z
$\getlettercode{\Charz}=\number`z$
\let\Charpipe=|
$\getlettercode{\Charpipe}=\number`|$
$\getlettercode{\let}=-1$
\end{document}