带有换行或运行选项的部分(使用 lualatex、KOMA-Script、xparse)

带有换行或运行选项的部分(使用 lualatex、KOMA-Script、xparse)

我正在更新subsubsection命令,以便我可以将以下文本放在同一行(默认),或者留下一些空格,并!传递一个标记。看来,对于subsubsection[]!的组合*!它可以编译但不会产生所需的结果。

我已经成功创建了接受多个令牌的命令(在同一个 MWE 中测试)xparse,但不确定这是否是问题所在。

这已在 Overleaf 上的 TeX Live 2020 上进行了测试。我尝试了luaexecdirectlualuadirect

问题:有人能发现我的尝试/方法中的缺陷吗?我的解决方案使用 LuaLaTeX。重建命令并从 Lua 打印它感觉有点不合时宜——有没有一种规范的方法可以以类似的方式“增强”命令(即添加标记参数!或者说其他可选参数)。subsubsection 命令是否需要可扩展?

\documentclass{scrartcl}

\usepackage{xparse}
\usepackage{luacode}

\RedeclareSectionCommand[afterskip=-4ex]{subsubsection}

\begin{luacode*}
    _xTrue = '\\BooleanTrue '
    _xFalse = '\\BooleanFalse '
    _xNoValue = '-NoValue-'

    function makesubsubsection(s, o, m)
        texio.write_nl('>>>>> Arguments are: '..s..', '..o..', '..m)
        local cmd = '\\oldsubsubsection'
        if s == _xTrue then
            cmd = cmd .. '*'
        end
        if o ~= _xNoValue then
            cmd = cmd..'['..o..']'
        end
        tex.print(cmd..'{'..m..'}')
    end
\end{luacode*}

\let\oldsubsubsection\subsubsection
\RenewExpandableDocumentCommand{\subsubsection}{ s t! o m }{% does this need to be expandable?
    \IfBooleanT{#2}{\RedeclareSectionCommand[afterskip=12pt]{subsubsection}}{}
    \directlua{makesubsubsection(\luastringN{#1},\luastringN{#3},\luastringN{#4})}
    \IfBooleanT{#2}{\RedeclareSectionCommand[afterskip=-4ex]{subsubsection}}{}%
}


% \NewDocumentCommand{\TestTokArg}{ s  t! }{%
%   Test:\IfBooleanT{#1}{Star}\IfBooleanT{#2}{Excl}% testing token arg
% }

\begin{document}

% \TestTokArg \TestTokArg* \TestTokArg! \TestTokArg*!  % testing token arg

\tableofcontents 

\subsubsection{in ToC, in Line} text  %% works

\subsubsection[short1]{in ToC, in Line} text  %% works

\subsubsection!{in ToC, not in Line} text   %% works

\subsubsection![short2]{in ToC, not in Line} text  %% does not work

\subsubsection*{no ToC, in Line} text   %% works

\subsubsection*!{no Toc, not in line} text  %% does not work

\end{document}

在此处输入图片描述

为了排除故障,我打印出我的 lua 函数接收的参数,但在日志中,它只显示前三个调用subsubsection

>>>>> Arguments are: \BooleanFalse , -NoValue-, in ToC, in Line
>>>>> Arguments are: \BooleanFalse , short1, in ToC, in Line
>>>>> Arguments are: \BooleanFalse , -NoValue-, in ToC, not in Line

答案1

首先让我们不使用 Lua 来重写这个,以避免两种语言的交互分散对实际问题的注意力:

\documentclass{scrartcl}

\usepackage{xparse}

\RedeclareSectionCommand[afterskip=-4ex]{subsubsection}

\let\oldsubsubsection\subsubsection

\RenewDocumentCommand{\subsubsection}{ s t! o m }{%
    \IfBooleanT{#2}{\RedeclareSectionCommand[afterskip=12pt]{subsubsection}}%
    \expanded{% \expanded ensures that we get one pass of expansion first which we use to build the right command. We can put \noexpand and/or \unexpanded around everything that should be preserved.
        \noexpand \oldsubsubsection
            \IfBooleanT {#1}{*}%
            \IfValueT {#3} {\unexpanded{[#3]}}%
            \unexpanded{{#4}}%
    }%
    \IfBooleanT{#2}{\RedeclareSectionCommand[afterskip=-4ex]{subsubsection}}%
}

\begin{document}

\tableofcontents 

\subsubsection{in ToC, in Line} text  %% works

\subsubsection[short1]{in ToC, in Line} text  %% works

\subsubsection!{in ToC, not in Line} text   %% works

\subsubsection![short2]{in ToC, not in Line} text  %% does not work

\subsubsection*{no ToC, in Line} text   %% works

\subsubsection*!{no Toc, not in line} text  %% does not work

\end{document}

这仍然会失败,所以 Lua 不可能是导致该问题的原因。

每次调用\subsubsection !已使用过一次。每当!使用时,您的代码都会调用\RedeclareSectionCommand,这将覆盖您指定的部分命令的当前定义(在您的例子中\subsubsection)。因此,它会覆盖您对此命令的重新定义,从而导致问题,因为之后\subsubsection不再知道您的附加参数。

为了解决这个问题,您可以避免\RedeclareSectionCommand并直接更改参数控制afterskipafterskipforsubsubsection存储在中\scr@subsubsection@afterskip

所以你得到

\documentclass{scrartcl}

\usepackage{xparse}

\let\oldsubsubsection\subsubsection

\makeatletter
\RenewDocumentCommand \subsubsection { s t! o m }{%
    \edef \scr@subsubsection@afterskip {%
        \IfBooleanTF {#2} {12pt} {-4pt}%
    }%
    \expanded{%
        \noexpand \oldsubsubsection
            \IfBooleanT {#1} {*}%
            \IfValueT {#3} {\unexpanded{[#3]}}% edit forgot {#3}
            \unexpanded{{#4}}%
    }%
}
\makeatother

\begin{document}

\tableofcontents 

\subsubsection{in ToC, in Line} text  %% works

\subsubsection[short1]{in ToC, in Line} text  %% works

\subsubsection!{in ToC, not in Line} text   %% works

\subsubsection![short2]{in ToC, not in Line} text  %% works

\subsubsection*{no ToC, in Line} text   %% works

\subsubsection*!{no Toc, not in line} text  %% works

\end{document}

相关内容