如何为现有文本宏添加额外样式?

如何为现有文本宏添加额外样式?

我正在尝试创建一个命令\mymodule_add_text_style:nn,用于向现有文本宏添加额外的样式。从以下 MWE 中可以看到,它可以成功将样式添加\textsc\mytext。但是,如果要向同一宏添加另一种样式,该命令不起作用。为什么会失败以及如何修复?

\documentclass{article}

\usepackage{xcolor}

\def\mytext{My text}

\ExplSyntaxOn

\cs_new:Nn \mymodule_add_text_style:nn
  {
    \tl_gset:cx { #1 } { \exp_not:n { #2 } { \use:c { #1 } } }
  }

\mymodule_add_text_style:nn
  { mytext }
  { \textsc }
% \mymodule_add_text_style:nn
%   { mytext }
%   { \textcolor {red} }

\ExplSyntaxOff

\begin{document}

\mytext{} and more text.

\end{document}

答案1

在这种情况下,你试图x扩展可能无法生存的东西\textsc(但\textcolor如果你想再次添加一些东西)。为了实现你的目标,你需要更好地控制扩展,做确切地\mytext重新定义它时的一次扩展。

但是你的电话应该是这样的

\mymodule_add_text_style:cn
  { mytext }
  { \textsc }

因为您使用的mytext是 csname。此处的函数是 的变体\mymodule_add_text_style:Nn,因此您也可以调用

\mymodule_add_text_style:Nn \mytext { \textsc }

无需使用\exp_not:n或其变体:只需使用变体。不进行x-expansion 更安全。

\documentclass{article}

\usepackage{xcolor}

\newcommand\mytext{My text}

\ExplSyntaxOn

\cs_new_protected:Nn \mymodule_add_text_style:Nn
  {
    \__mymodule_add_text_style:Non #1 { #1 } { #2 }
  }
\cs_generate_variant:Nn \mymodule_add_text_style:Nn { c }
\cs_new_protected:Nn \__mymodule_add_text_style:Nnn
  {
    \tl_gset:Nn #1 { #3 { #2 } }
  }
\cs_generate_variant:Nn \__mymodule_add_text_style:Nnn { No }

\mymodule_add_text_style:cn
  { mytext }
  { \textsc }
\mymodule_add_text_style:cn
  { mytext }
  { \textcolor {red} }

\ExplSyntaxOff

\begin{document}

\show\mytext

\mytext{} and more text.

\end{document}

控制台将显示

> \mytext=macro:
->\textcolor {red}{\textsc {My text}}.

如预期的。

在此处输入图片描述

你看出来其中的窍门了吗?你传递了#1两次,但传递给辅助函数的变体,其中第二个参数被扩展了一次。

还请注意任何执行分配的函数应该是protected

略有不同的提议

由于您使用它\mytext作为标记列表变量(这有点延伸,但也不是那么多),使用V类型会很好:

\cs_new_protected:Nn \mymodule_add_text_style:Nn
  {
    \__mymodule_add_text_style:NVn #1 #1 { #2 }
  }
\cs_generate_variant:Nn \mymodule_add_text_style:Nn { c }
\cs_new_protected:Nn \__mymodule_add_text_style:Nnn
  {
    \tl_gset:Nn #1 { #3 { #2 } }
  }
\cs_generate_variant:Nn \__mymodule_add_text_style:Nnn { NV }

答案2

您可以使用 TeX 基元创建宏,\addstyle \macro {style}无需任何 expl3。它执行相同的工作:

\def\addstyle#1{\expandafter\addstyleA\expandafter{#1}#1}
\def\addstyleA#1#2#3{\def#2{#3{#1}}}

\def\mytext{My text}

\addstyle \mytext {\textsc}
\addstyle \mytext {\textcolor{red}}

\meaning\mytext  % macro:->\textcolor {red}{\textsc {My text}}

\bye

答案3

首次使用后

\textsc {My text}

\textsc使用 LaTeX 机制保护\protect,但不能在\edef或其他扩展上下文(例如x参数)中使用。

在此处输入图片描述

\documentclass{article}

\usepackage{xcolor}

\def\mytext{My text}

\ExplSyntaxOn

\cs_new:Nn \mymodule_add_text_style:Nn
  {
    \tl_set:Nx #1  { \exp_not:n { #2}{\exp_not:o { #1 }}}
  }

\cs_generate_variant:Nn\mymodule_add_text_style:Nn {c}

\mymodule_add_text_style:cn
  { mytext }
  { \textsc }

\show\mytext

\mymodule_add_text_style:cn
  { mytext }
  { \textcolor {red} }

\show\mytext

\ExplSyntaxOff

\begin{document}

\mytext{} and more text.

\end{document}

两人\show表演

> \mytext=macro:
->\textsc {My text}.
l.20 \show\mytext
                 
? 
> \mytext=macro:
->\textcolor {red}{\textsc {My text}}.
l.26 \show\mytext
                 
? 

相关内容