如何将类别 6 的显式字符标记/任意标记序列的参数加倍?(不是 \edef..{\unexpanded{..}}-thingie)

如何将类别 6 的显式字符标记/任意标记序列的参数加倍?(不是 \edef..{\unexpanded{..}}-thingie)

假设定义了一个宏\foo
\def\foo{\bar\space A hash {in {braces: \string##}\string##}}

扩展控制字标记/宏标记\foo可得到:
\bar\spaceA1110h11a11s11h1110{1i11n1110{1b11r11a11c11e11s11:1210\string#6}2\string#6}2

假定其中出现的控制序列标记均不是\outer

如何进行后处理以使每个哈希/类别 6/参数的每个显式字符标记加倍以获得?
\bar\spaceA1110h11a11s11h1110{1i11n1110{1b11r11a11c11e11s11:1210\string#6#6}2\string#6#6}2

反过来,这可以用作另一个宏的⟨替换文本⟩(的组成部分),该宏将通过\def并且我不喜欢更改为通过定义\edef\AnotherMacro{\unexpanded{..}}/我不喜欢更改为,\edef\AnotherMacro{\the\tokenregister}因为执行\def并且需要更改的代码来自不是我的宏包,我不知道用户是否依赖于不被更改/不被修补的东西。

(不幸的是,在许多 pgfkeys 宏的替换文本中,使用了类似的东西\edef\macro{\unexpanded{#1}}来允许哈希作为参数 表示的参数的组成部分#1。例如,在像和\def\macro{#1}这样的处理程序的底层例程中似乎就是这种情况。如果这在最新的 pgfkeys 中已经得到纠正:我的一位同事仍然使用 TeX Live 2018,直到退休才会更新。).store in.search also

我知道\meaning\write\scantokens\detokenize双哈希,但使用这些,您会丢失有关字符标记类别的信息。 如果在 11 和其他字符之间翻转字符的类别代码,您也不知道哪些字符属于哪些控制序列的名称。 如果\escapechar发生变化或不为正,您甚至根本不知道哪些字符属于控制序列的名称。

答案1

中有一些函数etl可以搜索和替换宏参数标记。但它还有其他一些缺点(请参阅其文档,主要是关于一些不允许的内部标记、它将第 1 类和第 2 类标记规范化为{},以及某些标记无法以可扩展的方式相互区分)。

尽管如此,以下代码通过直接调用一个函数实现了哈希倍增,然后在一些伪设置宏中使用它作为 -internal 的示例pgfkeys。我删除了\bar,这样我就可以排版内容而无需进一步更改。

\documentclass{article}

\usepackage{etl}

\def\foo{\space A hash {in {braces: \string##}\string##}}

\ExplSyntaxOn
\cs_new:Npn \cattleya_double_hashes:n #1
  { \etl_token_replace_all_deep:nNn {#1} ## { #### } }
\cs_new_eq:NN \doublehashes \cattleya_double_hashes:n
\ExplSyntaxOff

% the other definition you don't have control over
\NewDocumentCommand\mysetupmacro{m}
  {\def\macro{Stuff and #1 and stuff}}
\newcommand*\macro{} % initial value

\expanded{\noexpand\mysetupmacro{\expandafter\doublehashes\expandafter{\foo}}}

\begin{document}
\texttt{\meaning\macro}

\macro
\end{document}

在此处输入图片描述

答案2

我不确定这个令牌循环是否满足您的要求:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{tokcycle,lmodern}
\tokcycleenvironment\showcats
 {\ifcatSIX\addcytoks{\thistok{##1}{6}}\else\addcytoks{\catcomp{##1}}\fi}
 {\addcytoks{\thistok{\{}{1}}\processtoks{##1}\addcytoks{\thistok{\}}{2}}}
 {\addcytoks{\catcomp{##1}}\tctestifx{\par##1}{\addcytoks{\par}}{}}
 {\ifimplicittok\addcytoks{\catcomp{##1}}\else
  \addcytoks{\thistok{\textvisiblespace}{\number\catcode`##1}}\fi}
\newcommand\thistok[2]{#1$_{#2}$\,\allowbreak}
\makeatletter
\newcommand\catcomp[1]{%
  \tctestifx{\implicitsixtok#1}{\expandafter\string#1$_{6}}{%
  \string#1$_{%
  \tctestifcatnx #1\relax{0}{%
  \tctestifcatnx #1${3}{%
  \tctestifcatnx #1&{4}{%
  \tctestifcatnx #1^{7}{%
  \tctestifcatnx #1_{8}{%
  \tctestifcatnx #1\@sptoken{10}{%
  \tctestifcatnx #1a{11}{%
  \tctestifcatnx #11{12}{%
  \tctestifcatnx #1~{13}{%
  *%
  }}}}}}}}}}%
  }$\,\allowbreak%
}
\makeatother
\begin{document}

\let\foo\relax

\showcats\def\foo{\bar\space A hash {in {braces: \string##}\string##}}\endshowcats

\hrulefill

\def\foo{\bar\space A hash {in {braces: \string##}\string##}}

\detokenize\expandafter{\foo}

\expandafter\showcats\foo\endshowcats

\hrulefill

\newcommand\addhash{\cytoks\expandafter{\the\cytoks####}}

\resettokcycle
\Characterdirective{\ifcatSIX\addhash\addhash\else\addcytoks{#1}\fi}
\expandafter\tokcyclexpress\expandafter{\foo}
\expandafter\def\expandafter\food\expandafter{\the\cytoks}

\detokenize\expandafter{\food}

\expandafter\showcats\food\endshowcats
\end{document}

在此处输入图片描述

在第一个输出块中,如果在发生之前进行处理,则可以识别双重哈希值\def,但这不是您所需要的。

在第二个块中,如果\def首先出现,则根据的规则,双重哈希将丢失\def

在第 3 个块中,通过在预定义上操作给定的标记循环来恢复双重哈希,以使用循环标记 \foo创建。我展示了去标记化,以及它的标记/分类代码细分。\food\def\food

我希望这可能正是您所要求的。

相关内容