我想要\def
一个宏,其名称代表任意字符串数据,包括\
、{
和}
字符。我最初的方法是使用\textbackslash
和\{
来测试是否可以做到这一点。但它们不能在 中使用,如下所示。有什么替代方法吗?是否有可以在 中使用的和的\csname...\endcsname
替代方案?\textbackslash
\{
\csname...\endcsname
\textbackslash
只是临时将和重新定义\{
为是没有什么好处的\empty
。生成的宏名称对于字符串来说必须text\{moretext
与对于字符串 来说不同textmoretext
。无论使用什么宏,都必须有意义地表示某个特定字符出现在字符串/宏名称中的该位置这一事实,以避免与如此生成的其他宏名称发生冲突。
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (MiKTeX 2.9 64-bit)
**\relax
entering extended mode
LaTeX2e <2015/01/01>
Babel <3.9l> and hyphenation patterns for 69 languages loaded.
*\expandafter\def\csname some text \textbackslash some more text\endcsname{}
! Missing \endcsname inserted.
<to be read again>
\global
<*> ...ndafter\def\csname some text \textbackslash
some more text\endcsname{}
?
*\expandafter\def\csname some text \{ some more text\endcsname{}
! Missing \endcsname inserted.
<to be read again>
\protect
<*> \expandafter\def\csname some text \{
some more text\endcsname{}
?
*
答案1
如果你不打算\csname...\endcsname
在另一个命令的参数中使用它时使用不匹配的括号,则可以直接使用{
and }
。对于反斜杠,只需使用\string
;唯一的问题是说服 TeX 不要吞噬模拟控制序列后的空格:
\expandafter\def\csname some text\string\some\space more} text\endcsname{}
可以。如果要安全起见,请使用\@charlb
左括号和\@charrb
右括号并定义
\makeatletter
\begingroup\escapechar=-1
\xdef\@charbs{\string\\}
\endgroup
\makeatother
如果你不想要@
命令,只需定义等效命令:
\makeatletter
\let\charlb=\@charlb
\let\charrb=\@charrb
\begingroup\escapechar=-1
\xdef\@charbs{\string\\}
\endgroup
\let\charbs=\@charbs
\makeatother
然后
\expandafter\def\csname some text\charbs some more\charrb\space text\endcsname{}
会和以前一样。
答案2
\makeatletter
\expandafter\def\csname xx\expandafter\@gobble\string\{yy\endcsname{}
\expandafter\show\csname xx\expandafter\@gobble\string\{yy\endcsname
答案3
e-TeX\detokenize
有助于将任意参数转换为可以在内部安全使用的东西\csname
:
\expandafter\def\csname\detokenize{some text \foo{hello} \bar some more text}\endcsname{}