假设令牌;
\macro{1612512}2{1612612}2{1⟨arbitrary non-outer brace balanced tokens⟩}2
- 的第一个参数
\macro
保存 TeX 引擎内部字符编码方案的可能代码点范围内的 TeX-⟨number⟩-quantity,它表示要创建的明确类别 1 字符标记的字符代码; - 的第二个参数
\macro
保存 TeX 引擎内部字符编码方案的可能代码点范围内的 TeX-⟨number⟩-quantity,它表示要创建的明确类别 2 字符标记的字符代码; - 的第三个参数
\macro
保存任意数量的非外括号平衡标记,这些标记将放置在显式类别 1 字符标记和显式类别 2 字符标记之间。
如何\macro
在 Knuth 的 TeX 中定义可扩展的宏\expanded
—不可用,在某个阶段进行扩展?
A1⟨arbitrary non-outer brace balanced tokens⟩B2
如何为不可用的\macro
(较旧的)utf-8 引擎定义可扩展的宏,其中扩展在某个阶段实现?\expanded
A1⟨arbitrary non-outer brace balanced tokens⟩B2
使用\expanded
/expl3 你可以做某事
\ExplSyntaxOn
\cs_new:Npn \macro #1#2#3
{
\tex_expanded:D { \char_generate:nn {#1}{1}
\exp_not:n {#3}
\char_generate:nn {#2}{2}
}
}
\ExplSyntaxOff
如果可扩展性不是问题,那么可以做某事
\ExplSyntaxOn
\newtoks\scratch
\cs_new:Npn \macro #1#2#3
{
\scratch={#3}
\exp_after:wN \def
\exp_after:wN \test
\exp_after:wN {
\exp:w
\exp_after:wN \exp_after:wN \exp_after:wN
\exp_after:wN
\exp_after:wN \exp_after:wN \exp_after:wN
\exp_end:
\exp_after:wN \exp_after:wN \exp_after:wN
\exp_after:wN
\char_generate:nn {#1}{1}
\the \exp_after:wN \exp_after:wN \exp_after:wN \scratch \char_generate:nn {#2}{2}
}
}
\ExplSyntaxOff
这是学术兴趣。我尝试学习 TeX 的工作原理,以便更好地了解你能做什么和不能做什么。以及如何做。我认为这种方法比一开始就尝试编写文档并在临近截止日期时一直陷入困境要好。
我知道 expl3 是 LaTeX,但我使用的唯一真正的 expl3 是,\char_generate:nn
并且根据 source3.pdf,它也可以与传统 LaTeX(8 位引擎)完全兼容,这意味着也可以使用纯文本实现仅提供类别 1/2 的显式字符标记的精简版本。例如,可以为每个代码点定义一个宏,该宏通过两个扩展步骤(\romannumeral
-expansion 和 brace-hacking)提供相关的字符标记。
答案1
没有理由这样做,但如果你定义 256*256 个辅助函数,你可以这样做
\def\macro#1#2{%
\csname x\number#1x\number#2\endcsname
}
% then lots of definitions like
{\catcode65=1\relax \catcode66=2\relax
\expandafter
\gdef\csname x65x66\endcsname#1{A#1B}
}
\immediate\write20
\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\expandafter
{%
\macro{65}{66}{some \relax \alpha tokens}%
}
\bye
答案2
什么时候大卫·卡莱尔指出正确的方向我意识到可以使用 (256·2)+3 辅助宏而不是 256 2:
\newcount\scratch
\long\def\gobble#1{}%
\chardef\nomoreromannumeral=0 %
\long\def\PlaceCategoryTwoTokenBehindArgument#1#2{%
\endgroup
%---------------------------------------------------------
\expandafter\def
\csname PlaceACategoryOneToken\number\scratch\endcsname{%
\expandafter\expandafter\expandafter\nomoreromannumeral
\expandafter\expandafter\expandafter#1%
}%
%---------------------------------------------------------
\long\expandafter\def
\csname PlaceACategoryTwoToken\number\scratch BehindArgument\endcsname##1{%
\expandafter\gobble\string#2%
}%
}%
% Character with code-point number 0 = Character ^^@ cannot
% be lowercased,see TeXbook, so needs treatment outside
% lowercase loop:
%---------------------------------------------------------
\catcode0=1\relax
\expandafter\def
\csname PlaceACategoryOneToken0\endcsname{%
\expandafter\expandafter\expandafter\nomoreromannumeral
\expandafter\expandafter\expandafter^^@\expandafter\gobble\string}%
}%
%---------------------------------------------------------
\catcode0=2\relax
\long\expandafter\def
\csname PlaceACategoryTwoToken0BehindArgument\endcsname#1{%
\expandafter\gobble\string{#1^^@%
}%
%---------------------------------------------------------
\catcode0=9\relax
\catcode`\X=1\relax
\catcode`\Y=2\relax
\scratch=0\relax
\loop
\ifnum\scratch<255 %
\advance\scratch by 1 %
%---------------------------------------------------------
\begingroup
\lccode`\X=\scratch\relax
\lccode`\Y=\scratch\relax
\lowercase{\PlaceCategoryTwoTokenBehindArgument{X\expandafter\gobble\string}}{{##1Y}}%
%---------------------------------------------------------
\repeat
\catcode`\X=11\relax
\catcode`\Y=11\relax
\long\def\PlaceCategoryTwoTokenBehindArgument#1#2{%
\csname PlaceACategoryTwoToken\number#2BehindArgument\endcsname{#1}%
}%
\def\PlaceCategoryOneToken#1{%
\csname PlaceACategoryOneToken\number#1\endcsname
}%
\long\def\macro#1#2#3{%
\romannumeral\PlaceCategoryTwoTokenBehindArgument{\PlaceCategoryOneToken{#1}#3}{#2}%
}%
% A test:
\newtoks\testtoks
\testtoks\expandafter\expandafter\expandafter{%
\macro{65}{66}{\fi#\endcsname\iffalse ##\UndeFInED\egroup\par\csname\if\bgroup}%
}%
\edef\test{\the\testtoks}%
\show\test
\bye
编辑:
后约瑟夫·赖特在聊天中提出挑战后,我意识到可以使用 256+5 个辅助宏来完成:
\newcount\scratch
\long\def\gobble#1{}%
\long\def\fot#1#2{#1}%
\long\def\sot#1#2{#2}%
\chardef\nomoreromannumeral=0 %
\chardef\MyOne=1 %
% Character with code-point number 0 = Character ^^@ cannot
% be lowercased,see TeXbook, so needs treatment outside
% lowercase loop:
%---------------------------------------------------------
\begingroup
\catcode`\^^@=1\relax
\def\fot{\expandafter\expandafter\expandafter^^@\expandafter\gobble\string}}%
\catcode`\^^@=2\relax
\def\sot{\expandafter\gobble\string{^^@}%
\edef\fot{%
\endgroup
\long\noexpand\expandafter\def
\noexpand\csname PlaceACategoryOneOrTwoToken0BehindArgument\noexpand\endcsname##1##2{%
\noexpand\ifnum##1=\nomoreromannumeral
\noexpand\expandafter\noexpand\fot\noexpand\else\noexpand\expandafter\noexpand\sot\noexpand\fi
{%
\noexpand\expandafter\noexpand\gobble\noexpand\string{##2\sot
}{%
\noexpand\expandafter\noexpand\expandafter\noexpand\expandafter\nomoreromannumeral
\noexpand\expandafter\noexpand\expandafter\noexpand\expandafter\fot
\noexpand\expandafter\noexpand\gobble\noexpand\string}%
}%
}%
}%
\fot
%---------------------------------------------------------
\long\def\PlaceCategoryOneOrTwoTokenBehindArgument#1#2{%
\long\expandafter\def
\csname PlaceACategoryOneOrTwoToken\the\scratch BehindArgument\endcsname##1##2{%
\ifnum##1=\nomoreromannumeral\expandafter\fot\else\expandafter\sot\fi
{%
\expandafter\gobble\string#1%
}{%
\expandafter\expandafter\expandafter\nomoreromannumeral
\expandafter\expandafter\expandafter#2%
}%
}%
}%
%---------------------------------------------------------
\catcode`\X=1\relax
\catcode`\Y=2\relax
\scratch=0\relax
\loop
\ifnum\scratch<255 %
\advance\scratch by 1 %
%---------------------------------------------------------
\begingroup
\lccode`\X=\scratch\relax
\lccode`\Y=\scratch\relax
\lowercase{%
\endgroup
\PlaceCategoryOneOrTwoTokenBehindArgument{{##2Y}{X\expandafter\gobble\string}}%
}%
%---------------------------------------------------------
\repeat
\catcode`\X=11\relax
\catcode`\Y=11\relax
\long\def\PlaceCategoryOneOrTwoTokenBehindArgument#1{%
\csname PlaceACategoryOneOrTwoToken\number#1BehindArgument\endcsname
}%
\long\def\macro#1#2#3{%
\romannumeral\PlaceCategoryOneOrTwoTokenBehindArgument{#2}{\nomoreromannumeral}{%
\PlaceCategoryOneOrTwoTokenBehindArgument{#1}{\MyOne}{}#3%
}%
}%
% A test:
\newtoks\testtoks
\testtoks\expandafter\expandafter\expandafter{%
\macro{65}{66}{\fi#\endcsname\iffalse ##\UndeFInED\egroup\par\csname\if\bgroup}%
}%
\edef\test{\the\testtoks}%
\show\test
\bye
现在我感兴趣的是是否存在一个可扩展的变体,它也可以在你没有的 utf8 引擎上使用\expanded
。(unicode 中的 1,114,112 个代码点需要很多辅助宏......)