如何在命令中使用 \catcode?

如何在命令中使用 \catcode?

我想对角色进行@如下定义:

\def @#1#2{\catcode`#1=13\def #1{#2}}

这样当我输入 时@xy x,TeX 就会排版y。但是,当我运行这个时,我收到一个错误。

我看过其他答案这里这里询问有关更改命令中的 catcode 的问题。但是,给出的所有答案都不能以我想要的方式解决问题——它们只是将\catcode宏移出。还有解决方案

\catcode`@=13
\def @#1{\catcode`#1=13\def}
@xx{y} x

其结果相同y。但是,出于我自己的目的,我想用最少的字符 (3) 实现上述目标:@xy。我尝试使用\expandafter,但无济于事。这可能吗?

答案1

你必须使用\lowercase技巧:

\def @#1#2{\catcode`#1=13 \bgroup \lccode`\~=`#1\lowercase{\egroup \def~}{#2}}

% test:
@ABA

~在所有格式中默认处于活动状态,并将活动\lowercase更改~为您想要的活动字符。

答案2

wipet 的答案是获得你建议的语法的方法,但如果你改为使用双字符,那么@xxy ... x你可以避免在字符激活之前访问定义的字符的问题,所以使用更简单的定义。这是在xii.tex使用A而不是@但是例如AZZFLaLP相当于您的建议 @Z{LaL}但是Z使用被定义为双倍。@ZZ{LaL}

\let~\catcode~`76~`A13~`F1~`j00~`P2jdefA71F~`7113jdefPALLF
PA''FwPA;;FPAZZFLaLPA//71F71iPAHHFLPAzzFenPASSFthP;A$$FevP
A@@FfPARR717273F737271P;ADDFRgniPAWW71FPATTFvePA**FstRsamP
AGGFRruoPAqq71.72.F717271PAYY7172F727171PA??Fi*LmPA&&71jfi
Fjfi71PAVVFjbigskipRPWGAUU71727374 75,76Fjpar71727375Djifx
:76jelse&U76jfiPLAKK7172F71l7271PAXX71FVLnOSeL71SLRyadR@oL
RrhC?yLRurtKFeLPFovPgaTLtReRomL;PABB71 72,73:Fjif.73.jelse
B73:jfiXF71PU71 72,73:PWs;AMM71F71diPAJJFRdriPAQQFRsreLPAI
I71Fo71dPA!!FRgiePBt'el@ lTLqdrYmu.Q.,Ke;vz vzLqpip.Q.,tz;
;Lql.IrsZ.eap,qn.i. i.eLlMaesLdRcna,;!;h htLqm.MRasZ.ilk,%
s$;z zLqs'.ansZ.Ymi,/sx ;LYegseZRyal,@i;@ TLRlogdLrDsW,@;G
LcYlaDLbJsW,SWXJW ree @rzchLhzsW,;WERcesInW qt.'oL.Rtrul;e
doTsW,Wk;Rri@stW aHAHHFndZPpqar.tridgeLinZpe.LtYer.W,:jbye

或者,如果您更喜欢\使用转义字符而不是j

\catcode`\@13
\def\dodef#1#2{\def#1{#2}}
\def@#1{\catcode`#1=13 \dodef}

@xxy   abc x

@ww{hello}  hmmm what

\bye

在此处输入图片描述

\dodef这里只是括号是可选的,你可以使用@xxy而不是@xx{y}xii版本直接使用\def,所以你需要@xx{y},但你可以使用参数,这样例如@xx#1{(#1)} xq会扩展为(q)

答案3

您显示的代码假定@首先处于活动状态,因此\catcode`@=\active需要在某处进行声明。

你的

\def @#1#2{\catcode`#1=13\def #1{#2}}
@xy x

尝试?TeX 会抱怨缺少控制序列,因为的替换文本中的控制序列或活动字符@,并x使用其类别代码进行标记任务\catcode已完成。

您可以使用\lowercasewipet 所示的技巧,或者采用不同的方法expl3(可以与纯 TeX 一起使用,但只能在启用 e-TeX 扩展的情况下使用)。

\input expl3-generic

\ExplSyntaxOn

% first a generic function
\cs_new_protected:Nn \bshepard_catcode_def:nnn
 {% #1 = character to be made active
  % #2 = argument list, may be empty
  % #3 = replacement text
  \cs_new:cn { __bshepard_catcode_def_#1:#2 } { #3 }
  \char_set_active_eq:nc { `#1 } { __bshepard_catcode_def_#1:#2 }
  \char_set_catcode_active:n { `#1 }
 }

%initialize @
\bshepard_catcode_def:nnn { @ } { nn } { \bshepard_catcode_def:nnn { #1 } { } { #2 } }

\ExplSyntaxOff

@xy x

\show x

\bye

控制台将显示

> x=\long macro:
->y.
l.22 \show x

发生了什么?通用函数有三个参数:要激活的字符、其激活值将查找的参数的规范以及替换文本。

这将根据角色定义一个内部函数,并将活动角色含义设置为等同于该内部函数,然后激活该角色。

线路

\bshepard_catcode_def:nnn { @ } { nn } { \bshepard_catcode_def:nnn { #1 } { } { #2 } }

激活@并告诉 TeX 它的含义是寻找两个参数(其中第一个必须是一个字符)并将通用函数应用于这个字符。

相关内容