LaTeX 3 / expl3 帮助理解 \cs:w 和扩展顺序

LaTeX 3 / expl3 帮助理解 \cs:w 和扩展顺序

我一直在尝试学习 L3 编程层,同时编写一个简单的包来设置和使用文本“样式”。

背景是我在我的类中添加了键值参数,这些参数应该像这样工作:

\documentclass[
    style/footnote       = {small,sans,FF0000},
    style/chapter-name   = uppercase, % full uppercase
]{desert}

事实是,即使完成了大部分工作,我还是不懂 L3 l3.pdf。以下是我需要帮助的地方:

  1. 我显然使用\cs:w不正确。
  2. 我一直无法理解其中的流程,尤其是什么时候LaTeX 扩展了我应该在何处使用:n:x:v。(我要补充一点,TeX 的错误消息并不是很好。)
  3. 我希望我的宏\txtuppertosc以及 等\txtuppercase能够像 或 一样\LARGE工作\bfseries,以便开关\TxtStyle可以与它们配合使用。有什么办法吗?

更新:David Carlisle 指出我错误地将:N参数包装在 中{}。原始宏位于底部。

更新代码:

\RequirePackage{xparse}
\RequirePackage{l3keys2e}
\RequirePackage{etoolbox}
\ProvidesExplPackage{txtstyles}{2022-02-02}{0.1}{Text styles}
\RequirePackage[
    dvipsnames,svgnames,x11names,
    hyperref
]{xcolor}
\RequirePackage{fontsize}


% build up aliases for style commands
\prop_new:N \g_txtstyle_aliases
\prop_set_from_keyval:Nn \g_txtstyle_aliases
{
    rm=rmfamily, roman=rmfamily,
    upcase=txtuppercase, uppercase=txtuppercase,
    mini=footnotesize, minir=footnotesizer%, ...
}

% --- MAIN MACRO FOR A SINGLE CSV:
% converts a single name, like "LARGE", \bf, or "red" to a command
\cs_new:Npn \convert_cmd:n #1
{
        \cs_if_exist_use:cTF{#1}
        {}  % option 1: a command that starts with \
        {
            % options 2 (named alias) and 3 (color)
            \prop_get:NnNTF \g_txtstyle_aliases {#1}
            {} { \color{#1} }
        }
}

%%% MAIN MACRO FOR DECLARING A STYLE:
% defines a new style as a list of commands (via \convert_cmd)
\NewDocumentCommand{\DeclareTxtStyle}{m >{\SplitList{,}}m}
{
    \cs_gset:cpn{g_txtstyle_#1:} ##1
    { \tl_map_inline:Nn #2 { \convert_cmd:n{###1} } }
}

% Sets the text style (similar to \bfseries, etc.)
\NewDocumentEnvironment{TxtStyle}{m+b}
{
    \cs_if_exist_use:cTF{g_txtstyle_#1:}
    {}
    { \stylemissingerr:n{#1} }  % defined elsewhere
}{}

\NewDocumentCommand{\StyleTxt}{m+m}
{ \begin{TxtStyle}{#1} #2 \end{TxtStyle} }

main.tex

\documentclass{article}
\RequirePackage{txtstyles}

\begin{document}

\DeclareTxtStyle{mystyle}{large,red}
\StyleTxt{mystyle}{This is some text.}

\end{document}

作为参考,原始宏是:

% map an alias to its \command-value (e.g. roman becomes rmseries)
\cs_new:Npn \standardize_alias:n #1
{
    \prop_item:Nn \g_txtstyle_aliases {#1}
}

% converts a single name, like "LARGE", \bf, or "red" to a command
\cs_new:Npn \convert_cmd:n #1
{
    \prop_if_in:NVTF \g_txtstyle_aliases {#1}
    { \cs:w \standardize_alias:n{#1} \cs_end: }  % option 1: common name
    {
        \cs_if_exist_NTF {\cs:w #1 \cs_end:}
        { \cs:w #1 \cs_end: }  % option 2: a command name that starts with \
        { \color{#1} }  % option 3: a color, or fail
    }
}

% just gets the internal command name for a style
\cs_new:Npn \txtstyle_cmd_name:n #1
{ \cs:w g_txtstyle_#1:n \cs_end: }

% defines a new style as a list of commands (via \convert_cmd)
\NewDocumentCommand{\DeclareTxtStyle}{m >{\SplitList{,}}m}
{
    \cs_set:Npn { \txtstyle_cmd_name:n{#1}  } {}
    { \tl_map_inline:Nn {#2} { \convert_cmd:n{##1} } }
}

答案1

您需要注意 expl3 参数类型。N并且V参数应采用单个无括号标记。您几乎永远不需要使用,因为这是应该优先使用的参数类型\cs:w的实现。c

这里我展示了您的中心命令,它接受一个参数,如果参数是命令名,则执行该命令,否则将其解释为颜色。

在此处输入图片描述

\documentclass{article}
\usepackage{color}
\begin{document}

\ExplSyntaxOn
\cs_new:Npn \convert_cmd:n #1
{
        \cs_if_exist_use:cTF{#1}
        {}  % option 2: a command that starts with \
        { \color{#1} }  % option 3: a color, or fail
}


abc ~ {\convert_cmd:n{bfseries} abc} ~
abc ~ {\convert_cmd:n{red} abc}

\ExplSyntaxOff



\end{document}

在你的原文中

  \cs_if_exist:NTF{\cs:w {#1} \cs_end:}

但这是将括号组传递给N参数,并且如果#1是,它会测试是否存在带有名称(包括括号)的bfseries命令。您有意为之,但如上所述,最好只使用参数并传入{bfseries}\cs:w #1 \cs_end:c{#1}

相关内容