各种引擎中的 ^^ 符号

各种引擎中的 ^^ 符号

基本上,^^^...符号在 LuaTeX 和 XeTeX 中究竟是如何运作的?

在 8 位 TeX 引擎中(至少是最近的 TeX、eTeX、pdfTeX),两个连续相同的 catcode 7 字符(通常为^),后跟两个小写的十六进制数字,在标记步骤之前转换为相应的字节。也就是说,^^6f完全等同于o:例如,\sh^^6fw ^^6f将导致 TeX 显示the letter o

还有一种表示法是两个^(相同的 catcode 7 个字符),后跟任意 ascii 字符(但不是两个小写的十六进制数字),用在字符代码中减去或加上 64 得到的字符替换,剩余的是 ASCII 字符(范围为 0 到 128)。

支持 Unicode 的引擎(我想到的是 LuaTeX 和 XeTeX,也许还有其他不太知名的引擎)也为十六进制表示为 4 或 5 位数字的字符提供 和^^^^xxxx^^^^^xxxxx但这似乎在各个引擎中并不以相同的方式实现。

例如,LuaTeX 和 XeTeX 似乎都接受 4、5 或 6 个插入符号后跟相同数量的十六进制数字的表示法,但 XeTeX 也接受 3,而 LuaTeX 则不接受。使用 pdfTeX、LuaTeX 和 XeTeX 编译以下内容会产生不同的结果。

\catcode0=12
\newlinechar=10
\def\loopshow#1{\message{\meaning #1^^J}\loopshow}
\loopshow \/
  ^^56
  ^^^056
  ^^^^0056
  ^^^^^00056
  ^^^^^^000056
  ^^^^^^^0000056
{\end\iffalse}
\fi}
\bye

关于 XeTeX 的一个奇怪的事实(一个错误?)是

\show ^^^^^^010101

显示the character displaywidth

我的目标(可能有更好的方法)是提供一种方法来测试传递给定的标记列表是否\scantokens安全。为此,我的计划是\detokenized一次一个字符地检查标记列表,应用 TeX 的标记化规则(但不需要完全标记化),并检测 begin-group 和 end-group 标记以及无效字符。

答案1

首先,我想定义一些符号和函数,以便更容易地形式化答案。

符号:

  • x:小写十六进制数字:09af
  • N:不是小写的十六进制数字
  • c:字符代码小于 128 的七位字母
  • ^:catcode 为 7 的上标字符。字符代码无关紧要,但如果连续使用,则字符必须具有相同的字符代码。

功能:

  • hextochar字符串) 返回一个字符,其字符代码由字符串参数给出字符串解释为十六进制数。
  • charcode克里斯) 返回字符参数的字符代码克里斯
  • numtochar數量) 返回一个字符,其字符代码由数值参数给出數量

针对引擎的给定转换规则将从上到下进行尝试,直到第一条规则可以应用。

TeX、eTeX、pdfTeX(“TeXbook”、“第 8 章:您输入的字符”):

  • ^^xxhextocharxx
  • ^^c⇒ 如果charcode( c) < 64 则numtochar( c+64 ) 否则numtochar( c-64 )

LuaTeX(功能process_sup_marktextoken.w):

  • ^^^^^^xxxxxxhextocharxxxxxx

    • 备注:xxxxxx不受限制,但值≥0x110100会引起麻烦。
    • 0 到0x10ffff:正常 Unicode 范围内的字符。
    • 0x1100000x1100ff:以字节(最后 8 位)显示的特殊字符,它们不会以 UTF-8 显示。
  • ^^^^xxxxhextocharxxxx

  • ^^xxhextocharxx

  • ^^c⇒ 如果charcode( c) < 64 则numtochar( c+64 ) 否则numtochar( c-64 )

XeTeX(xetex.ch@<如果这个 |sup_mark| 开始一个扩展字符...@>):

  • ^^^^^^xxxxxxhextochar( xxxxxx)
    仅当xxxxxx0x10ffff
  • ^^^^^xxxxxhextocharxxxxx
  • ^^^^xxxxhextocharxxxx
  • ^^^xxxhextocharxxx
  • ^^xxhextocharxx
  • ^^c⇒ 如果charcode( c) < 64 则numtochar( c+64 ) 否则numtochar( c-64 )

但是 XeTeX 的实现与 TeX 不兼容。例如,如果 catcode 为 7 的上标字符也是十六进制数,则 XeTeX 的行为会出乎意料:

\documentclass{minimal}
\begin{document}
\begingroup
  \catcode`\4=7 % superscript
  [$ 4444{a} $]
\endgroup
\end{document}

对于 TeX/e-TeX/pdfTeX 和 LuaTeX,两个上标字符44后面跟着两个44十六进制数字,结果为字母 D(字符代码 0x44,十进制 68),{a}随后在数学模式下给出变量“a”。LuaTeX 看不到四个上标字符,因为它们后面没有四个十六进制数字。

XeTeX 首先看到四个上标字符。但它们后面没有四个十六进制数字。它切换到大小写^^c,其中两个上标字符后面跟着一个非十六进制字符。结果是“t”(0x74 = 0x34('4')+ 64)。然后,第四个“4”被视为上标,它会产生以下结果{a}。但c实际上是“4”,一个十六进制数字。XeTeX 应该应用大小写^^xx。因此,我认为这种行为是一个错误。

(编辑:更正下一段,65536 是正确的,而 256 是错误的——我查看了网络更改文件中错误的部分。)

的问题\show确实是一个错误。 字符被打印出来,调用过程print并将其字符代码作为参数。 如果此代码小于biggest_char,则打印字符,否则将代码解释为字符串 id,并打印带有 id 的字符串(过程print)。 的定义biggest_char

@d biggest_char=65536 {the largest allowed character number;
   must be |<=max_quarterword|}

≤ U+FFFF 的字符显示正确,超出的字符受影响,超出的字符除外。这可用于调试字符串池 ⌣:

\catcode`\{=1
\catcode`\}=2
\catcode`\#=6
\catcode`\^=7
\catcode9=10
\def\msg#{\immediate\write16}

% #1: string index
% #2: string value
\def\StringPrintEntry#1#2{%
  \msg{[#1: #2]}%
}
% #1: string index
% #2: messge
\def\StringError#1#2{%
  \msg{! [#1] #2}%
}
\def\StringPrintCount#1{%
  \msg{==> #1 strings available.}%
}
% #1: start index (zero based, including)
% #2: number of entries
\def\StringList#1#2{%
  \begingroup
    \countdef\i=11 % string index
    \countdef\m=12 % limit for string index
    \countdef\u=13 % char index
    \chardef\1=1 %
    \i=#1\relax
    \m=#2\relax
    \advance\m\i
    \u=\i
    \advance\u "10000\relax
    \StringProcess
  \endgroup
}
\def\StringProcess{
  \ifnum\i<\m
    \ifnum\u<"110000 %
      \lccode`0=\u
      \lowercase{%
        \edef\x{%
          {\the\i}%
          {\expandafter\StringStripPrefix\meaning 0}%
        }%
      }%
      \expandafter\StringProcessEntry\x
      \advance\i\1
      \advance\u\1
    \else
      \let\StringProcess\relax
      \expandafter\StringError\expandafter
      {\the\i}%
      {Index is too large.}%
    \fi
  \else
    \let\StringProcess\relax
  \fi
  \StringProcess
}
\def\StringProcessEntry#1#2{%
  \def\s{#2}%
  \ifx\s\StringInvalid
    \ifnum\i=5 % magic
      \StringPrintEntry{#1}{#2}%
    \else
      \let\StringProcess\relax
      \StringError{#1}{End of strings reached.}%
    \fi
  \else
    \StringPrintEntry{#1}{#2}%
  \fi
}
\def\StringStripPrefix#1 #2 {}
\def\StringInvalid{???}
\def\StringCount{%
  \begingroup
    \countdef\c=14 %
    \c=0 %
    \def\StringPrintEntry##1##2{%
      \advance\c\1
      \xdef\StringResult{\the\c}%
    }%
    \def\StringError##1##2{}%
    \StringList{0}{"10FFFF}
  \endgroup
  \StringPrintCount{\StringResult}%
}

\StringList{0}{40}

\StringCount

\csname @@end\endcsname\end

结果:

This is XeTeX, Version 3.1415926-2.4-0.9998 (MiKTeX 2.9) (INITEX)
(C:\Users\one\test\test-xetex-strings.tex
[0: .4]
[1: .9998]
[2: buffer size]
[3: pool size]
[4: number of strings]
[5: ???]
[6: m2d5c2l5x2v5i]
[7: End of file on the terminal!]
[8: ! ]
[9: (That makes 100 errors; please try again.)]
[10: ? ]
[11: Type <return> to proceed, S to scroll future error messages,]
[12: R to run without stopping, Q to run quietly,]
[13: I to insert something, ]
[14: E to edit your file,]
[15: 1 or ... or 9 to ignore the next 1 to 9 tokens of input,]
[16: H for help, X to quit.]
[17: OK, entering ]
[18: batchmode]
[19: nonstopmode]
[20: scrollmode]
[21: ...]
[22: insert>]
[23: I have just deleted some text, as you asked.]
[24: You can now delete more, or insert, or whatever.]
[25: Sorry, I don't know how to help in this situation.]
[26: Maybe you should try asking a human?]
[27: Sorry, I already gave what help I could...]
[28: An error might have occurred before I noticed any problems.]
[29: ``If all else fails, read the instructions.'']
[30:  (]
[31: Emergency stop]
[32: TeX capacity exceeded, sorry []
[33: If you really absolutely need more capacity,]
[34: you can ask a wizard to enlarge me.]
[35: This can't happen (]
[36: I'm broken. Please show this to someone who can fix can fix]
[37: I can't go on meeting you like this]
[38: One of your faux pas seems to have wounded me deeply...]
[39: in fact, I'm barely conscious. Please fix it and try again.]
==> 1381 strings available.
 )
No pages of output.
Transcript written on test-xetex-strings.log.

相关内容