删除 def 参数的多余花括号

删除 def 参数的多余花括号

我正在尝试结合以下答案删除多余的花括号\def 的纯文本参数的行为与纯文本不同,我失败了。这是 MWE:

\documentclass{article}
\makeatletter
\usepackage{seqsplit}
\newcommand{\dosomething}[1]{\expandafter\seqsplit\expandafter{\@firstofone#1}}

\begin{document}
    \def\kong{looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong}
    \def\kongg{\kong}
    \def\konggg{{looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong}}

    % works
    \dosomething{looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong}

    % works, too
    \expandafter\dosomething{\expandafter\kong}

    % works with extra {...}
    \dosomething{{looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong}}

    % works with extra {...}, too
    \expandafter\expandafter\expandafter\dosomething{\expandafter\expandafter\expandafter\kongg}

    % does not work
    \expandafter\expandafter\expandafter\dosomething{\expandafter\expandafter\expandafter\konggg}
\end{document}

从更大的角度来看,我想说的是:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{amsmath,hyperref}

%1 \usepackage{cleveref}

\usepackage{showlabels,xpatch,seqsplit}
\makeatletter
\patchcmd{\SL@margintext}{\{\SL@prlabelname{#1}\}}{#1}{}{err}
\patchcmd{\maketag@@@}{{\df@label}}{{\expandafter\df@label}}{}{err}

\patchcmd{\showlabelsetlabel}{#1}{\raisebox{0pt}[0pt][0pt]{\parbox{1.5\marginparwidth}{\scriptsize\vspace*{-0.5\baselineskip}\seqsplit{#1}}}}{}{err}

%2 \renewcommand{\showlabelsetlabel}[1]{\meaning\df@label}

%4 \newcommand{\dosomethingelse}[1]{\expandafter\seqsplit\expandafter{\@firstofone#1}}
%4 \patchcmd{\showlabelsetlabel}{\seqsplit}{\dosomethingelse}{}{err}

\begin{document}

    %3 \patchcmd{\label@in@display@noarg}{{{#1}}}{{#1}}{}{err}

    \section{A}
    \label{sec:Loooooooooooooooooooooooooooooooooooooooooong}

    \begin{equation}
    \label{eqn:Loooooooooooooooooooooooooooooooooooooooooong}
        X = Y
    \end{equation}
\end{document}

cleveref在我加载(取消注释)之前,此代码运行良好%1。您将看到为什么在取消注释%2:之后,由's\df@label设置,多了一层。amsmath\label@in@display{...}

cleveref另一方面,似乎是引入了这一点:

\def\label@in@display@noarg#1{\cref@old@label@in@display{{#1}}}%
\def\label@in@display@optarg[#1]#2{%
  \cref@old@label@in@display{[#1]{#2}}}%

而且它似乎依赖于它,正如您在尝试将xpatch其删除(取消注释%3)时所看到的那样。因此,我尝试像以前一样删除花括号(评论 %2,取消注释%4),但无济于事。

答案1

我认为您的代码的问题不在于定义,\dosomething而在于您的测试用例。让我们看看您的测试用例中的扩展情况:

  1. \dosomething{looong}
    \expandafter\seqsplit\expandafter{\@firstofone looong}
    \seqsplit{looong}
    
  2. \expandafter\dosomething{\expandafter\kong}
    \dosomething{\expandafter\kong}
    \expandafter\seqsplit\expandafter{\@firstofone\expandafter\kong}
    \seqsplit{\expandafter\kong}
    

    在这里你可以看到 s\expandafter没有被正确应用,因为有人进入了 参数,\seqsplit这可能不是你想要的。由于内部的工作方式,它似乎仍然意外地起作用\seqsplit

  3. \dosomething{{looong}}
    \expandafter\seqsplit\expandafter{\@firstofone{looong}}
    \seqsplit{looong}
    
  4. \expandafter\expandafter\expandafter\dosomething{\expandafter\expandafter\expandafter\kongg}
    \expandafter\dosomething{\expandafter\expandafter\expandafter\kongg}
    \dosomething{\expandafter\expandafter\expandafter\kongg}
    \expandafter\seqsplit\expandafter{\@firstofone\expandafter\expandafter\expandafter\kongg}
    \seqsplit{\expandafter\expandafter\expandafter\kongg}
    

    再次,这里s 找到了进入s 参数的\expandafter方法。\seqsplit

  5. \expandafter\expandafter\expandafter\dosomething{\expandafter\expandafter\expandafter\konggg}
    \expandafter\dosomething{\expandafter\expandafter\expandafter\konggg}
    \dosomething{\expandafter\expandafter\expandafter\konggg}
    

    这里存在同样的问题,导致该\@firstofone技巧无法应用。

另一方面,如果您expandafter以正确的剂量输入,则所有三个\kong宏的结果都是正确的:

\expandafter\dosomething\expandafter{\kong}

\expandafter\expandafter\expandafter\dosomething\expandafter\expandafter\expandafter{\kongg}

\expandafter\dosomething\expandafter{\konggg}

在此处输入图片描述

答案2

解决方法更简单。

首先,不要在 中添加大代码\patchcmd,否则维护起来会很困难。其次,使用宏可以让我们定义更巧妙的行为。

因此我修改了#1代码。\showlabelsetlabel\massage@label{#1}

它被定义为执行\massage@@label#1\@nil,它将从参数中删除外面的一对括号,根据规则:只要不留下不匹配的括号,就会从分隔参数中删除括号。

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{amsmath,hyperref}

\usepackage{cleveref}

\usepackage{showlabels,xpatch,seqsplit}

\makeatletter
\patchcmd{\SL@margintext}
  {\{\SL@prlabelname{#1}\}}
  {#1}
  {}{err}

\patchcmd{\showlabelsetlabel}
  {#1}
  {\massage@label{#1}}
  {}{err}

\newcommand{\massage@label}[1]{\expandafter\massage@@label#1\@nil}
\def\massage@@label#1\@nil{%
  \raisebox{0pt}[0pt][0pt]{%
    \parbox{1.5\marginparwidth}{%
      \scriptsize\vspace*{-0.5\baselineskip}%
      \expandafter\seqsplit\expandafter{#1}
    }%
  }%
}

\begin{document}

    \section{A}
    \label{sec:Loooooooooooooooooooooooooooooooooooooooooong}

    \begin{equation}
    \label{eqn:Loooooooooooooooooooooooooooooooooooooooooong}
        X = Y
    \end{equation}

\end{document}

在此处输入图片描述

相关内容