该问题是指 texlive 2019 中 luatex 1.10.0 之前的 LuaTeX 引擎。
使用 texlive 2019 中的 luatex 1.10.1 及更高版本时,\string
-primitive 可以按预期工作。
在哪里可以找到\string
LuaTeX 中 -primitive 的精确文档?
我问这个问题是因为我在用 LuaTeX 编译下面的示例时遇到了一些意外的行为(至少对我来说)。
使用普通 TeX 时,\string<control sequence token>
将提供一系列 catcode 为 12(other) 的显式字符标记,表示所讨论的控制序列标记的名称。例外:数字/字符代码为 32(空格)的字符的 catcode 将是 10(空格),即,它们将是显式空格字符标记。(名称包含空格的控制序列标记可以是控制符号标记\
(控制空格),也可以构造为 cia \csname..\endcsname
。)
如果整数参数的值\escapechar
在 0..255 范围内,则 catcode 为 12(other) 的显式字符标记(其 charcode 等于 的值)\escapechar
将位于该显式字符标记序列之前。例外:如果 的值为\escapechar
32,则前一个显式字符标记的 catcode 将为 10(空格),即,在这种情况下,前一个显式字符标记将是一个显式空格字符标记。
\escapechar
似乎在 XeTeX 中,-range的上限\string
也将传递前面的明确字符标记不是 255 而是 1114111。
\escapechar
但是使用 LuaTeX 时,当值从 1114112 到 1114239(=1114111+128)时,会出现一种意外行为,而\escapechar
当值从 1114240 到 2097151 时,会出现其他类型的意外行为:
(当然下面的例子需要用LuaTeX进行编译。)
\def\grab#1#2#3{1:#1;2:#2;3:#3;}
\def\grabteststring#1{\begingroup\escapechar=#1 \expandafter\endgroup\expandafter\grab\string\XXX AA}%
1. \grabteststring{-7} % Expected behavior occurred: No escapechar attached.
2. \grabteststring{0} % Expected behavior occurred: Visible escapechar attached.
3. \grabteststring{66} % Expected behavior occurred: Visible escapechar attached.
4. \grabteststring{1114111} % Expected behavior occurred: Invisible escapechar attached.
5. \grabteststring{1114112} % Unexpected behavior occurred: Visible escapechar attached.
% (I would have expected: No escapechar attached)
6. \grabteststring{1114239} % Unexpected behavior occurred: Visible escapechar attached.
% (I would have expected: No escapechar attached)
7. \grabteststring{1114240} % Unexpected behavior occurred:
% - .log file: !String contains an invalid utf-8 sequence
% - Two of the X seem silently gobbled.
% (I would have expected: No escapechar attached)
8. \grabteststring{2097151} % Unexpected behavior occurred:
% Seems the \string-primitive delivers the phrase:
% warning (print): bad raw byte to print (c=983939), skipped
% (I would have expected: No escapechar attached)
9. \grabteststring{2097152} % Expected behavior occurred: No escapechar attached.
\bye
以下是生成的.pdf 文件的截图:
以下是 .log 文件:
This is LuaTeX, Version 1.0.0 (MiKTeX 2.9.6210 64-bit) (format=luatex 2017.3.1) 22 JUN 2018 01:05
restricted system commands enabled.
**test.tex
(./test.tex
! String contains an invalid utf-8 sequence.
€grabteststring ...expandafter grab string XXX
AA
l.28 7. \grabteststring{1114240}
% Unexpected behavior occurred:
A funny symbol that I can't read has just been (re)read.
Just continue, I'll change it to 0xFFFD.
[1{XXXXXXXXXXXXX/MiKTeX/2.9/pdftex/config/pdftex.map}
Missing character: There is no ô¿¿ (U+10FFFF) in font cmr10!
Missing character: There is no � (U+FFFD) in font cmr10!
])<XXXXXXXXXXXXX/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmr10.pfb>
Output written on test.pdf (1 page, 18202 bytes).
PDF statistics: 10 PDF objects out of 1000 (max. 8388607)
0 named destinations out of 1000 (max. 131072)
1 words of extra memory for PDF output out of 10000 (max. 100000000)
换句话说:
无论是使用 XeTeX 还是使用普通 TeX,\string
当“字符串化”控制序列标记时,-primitive 都会生成一个前置转义字符标记,当且仅当整数参数的值\escapechar
在输入编码的范围内时,即,对于 8 位编码,在 0(dec)..255(dec) = 0(hex)..FF(hex) 内,对于 UTF-8 编码,在 0(dec)..1114111(dec) = 0(hex)..10FFFF(hex) 内,并且当且仅当整数参数的值\escapechar
不在输入编码的范围内时,-primitive 才会默默地不生成任何前置转义字符标记。因此,对于 XeTeX 和普通 TeX,-primitive 的行为对于可以分配给-integer-parameter\string
的每个值都是明确定义的。\escapechar
直觉上,我期望 LuaTeX 的行为也一样,因为我找不到任何用户手册指出 LuaTeX 中 -primitive 的行为与其他 TeX 引擎中 -primitive\string
的行为存在很大差异。但 LuaTeX 中 -primitive 的行为与大于 uft8 输入编码范围上限的值不同。\string
\sting
\escapechar
因此问题是:
LuaTeX- 原语的确切行为
\string
与什么\escapechar
值有关?这是 LuaTeX 的一个错误吗?