# Remove extra curly braces for def'ed argument

I am trying to combine the answers of Remove extra curly braces and \def'ed plain-text argument behaves differently from plain text, and I am failing. Here's an 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}


For the larger picture, this is what I am getting at:

\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}

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


This code behaves well until I load cleveref (uncomment %1). You will see why after uncommenting %2: \df@label, set by amsmath's \label@in@display, has an extra layer of {...}.

cleveref, on the other hand, seems to be the one introducing this:

\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}}}%


And it seems to depend on it, as you can see when you try to xpatch it out (uncomment %3). So instead of that, I tried to remove the curly braces as before (comment %2, uncomment %4), to no avail.

• You're are loading 4 packages that change the way \label works usually -- there must be interferences ;-) – user31729 May 12 '17 at 8:03
• @ChristianHupfer I am not surprised, but this doesn't mean I don't want to be able to manage these interferences ;) – bers May 12 '17 at 8:11

I think the problem with your code isn't the definition of \dosomething but your test cases. Let's have a look at how the expansion goes in your test cases:

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}


Here you can see that the \expandafters are not properly applied, as one goes into the parameter of \seqsplit which probably is not what you intended. It still seems to work accidentally because of how \seqsplit works internally.

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}


Again, here \expandafters find its way into \seqsplit's parameter.

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


The same problem here, which prevents the \@firstofone trick to apply.

On the other hand, if you put expandafters in the right dose, the result is correct with all of your three \kong macros:

\expandafter\dosomething\expandafter{\kong}

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

\expandafter\dosomething\expandafter{\konggg}


• "I think the problem with your code isn't the definition of \dosomething but your test cases" - exactly, I should have mentioned that! – bers Dec 6 '18 at 9:13

The workaround is simpler.

First of all, don't add big code in \patchcmd, it becomes difficult to maintain. Second, using a macro allows us to define a slicker behavior.

So I change #1 in the code for \showlabelsetlabel with \massage@label{#1}.

This is defined to do \massage@@label#1\@nil, which will remove an outer pair of braces from the argument, by rule: braces are removed from a delimited argument so long as this doesn't leave unmatched braces.

\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}

$$\label{eqn:Loooooooooooooooooooooooooooooooooooooooooong} X = Y$$

\end{document}