2

I came across several similar questions and answers with a similar issue, like https://tex.stackexchange.com/a/20055 and https://tex.stackexchange.com/a/46871, but even after registering my custom command, I still get a similar error. Not using the \soulregister command yields the exact same error.

\newcommand{\code}[1]{\sethlcolor{gray}\hl{\texttt{#1}}}
\soulregister{\code}{1}

This is the error I get:

! Argument of \@textcolor has an extra }.
<inserted text> 
                \par 
l.276 \section{\code{virusscan}}

The latex code in question looks like below. I'm using this inside a memoir document.

\section{\code{virusscan}}

Edit:

Defining the command like this:

\sethlcolor{gray}
\newcommand{\code}[1]{\hl{\texttt{#1}}}
\soulregister{\code}{1}

yields

! Argument of \let has an extra }.
<inserted text> 
                \par 
l.277 \section{\code{virusscan}}

Also \texttt{\hl{#1}} doesn't change anything.


Edit 2:

Here's the minimal non-working example:

\documentclass{memoir}

\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{soul}

\newcommand{\code}[1]{\sethlcolor{gray}\hl{\texttt{#1}}}
\soulregister{\code}{1}

\begin{document}

\section{\code{test}}

\end{document}
0

3 Answers 3

4

You also need to make the command robust, because you're using it in a moving argument.

\documentclass{memoir}

\usepackage{xcolor}
\usepackage{soul}

\DeclareRobustCommand{\code}[1]{{\sethlcolor{gray}\hl{\texttt{#1}}}}
\soulregister{\code}{1}

\begin{document}

\section{\code{test} and \hl{xyz}}

\end{document}

enter image description here

With hyperref the problem is different and it's connected to the bookmarks.

\documentclass{memoir}

\usepackage{xcolor}
\usepackage{soul}
\usepackage{hyperref}

\DeclareRobustCommand{\code}[1]{{\sethlcolor{gray}\hl{\texttt{#1}}}}
\soulregister{\code}{1}

\begin{document}

\section{\texorpdfstring{\code{test}{test}}

\end{document}

Alternatively, use \pdfstringdefDisableCommands:

\documentclass{memoir}

\usepackage{xcolor}
\usepackage{soul}
\usepackage{hyperref}

\DeclareRobustCommand{\code}[1]{{\sethlcolor{gray}\hl{\texttt{#1}}}}
\soulregister{\code}{1}
\makeatletter
\pdfstringdefDisableCommands{\let\code\@firstofone}
\makeatother

\begin{document}

\section{\code{test}}

\end{document}
4
  • For me that results in the same error... Might it have someting to do with me using MiKTeX?
    – BrainStone
    Jul 9, 2018 at 8:53
  • Having the package hyperref active breaks your example for me (I updated my MWE to include the package). Thank you regardless for your effort!
    – BrainStone
    Jul 9, 2018 at 9:09
  • @BrainStone That's a completely different problem, of course. Anyway, I added code for that.
    – egreg
    Jul 9, 2018 at 9:22
  • That worked. Thank you so much for solving two issues at once!
    – BrainStone
    Jul 9, 2018 at 9:32
2

With your MWE I get the the error both when using \soulregister and when not using \soulregister.

I only get it when trying to use the \code-command inside the argument of the \section-command.

I also get a warning by the hyperref-package:

Package hyperref Warning: Token not allowed in a PDF string (PDFDocEncoding):
(hyperref)                removing `\code' on input line 12.

Reason:

The \section command does not just write a nice paragraph heading into the text. It also both places entries into the .aux-file for writing the .toc-file for the table of contents and places entries into the .out-file so that the hyperref package can create a bookmark for the heading of the section. In case of a pagestyle with page-headings it also changes the page-headings.

In order to make sure that the \code-command does not get expanded when the aux-file-entry for the .toc-file and the .toc-file itself is written, have it defined in terms of \DeclareRobustCommand rather than having it defined in terms of \newcommand. In order to make sure that this command does not slip into hyperref-bookmarks, where only plain text should occur, use \texorpdfstring. Either within the definition of \code or when placing \code into the argument of sectioning-commands or captions.

Or for resolving the hyperref-issue, as egreg pointed out, use \pdfstringdefDisableCommands. (Seems he delivered his answer while I wrote mine ;-) .)

\documentclass{memoir}

\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{soul}

\DeclareRobustCommand{\code}[1]{%
  \texorpdfstring{{\sethlcolor{gray}\hl{\texttt{#1}}}}%
                 {#1}%
}
\soulregister{\code}{1}

\begin{document}

%\tableofcontents

\section{\code{test}}

\end{document}

By the way: \code does supply the grey background color not only within the paragraph heading but also within the entry in the table of contents and within the page headings.

If you don't like this but wish to have color only in the paragraph heading, a crude workaround can be checking the meaning of \protect. The LaTeX 2e protection-mechanism for preventing expansion of specific tokens in some situations does redefine that token depending on the situation, whereby situations might be "producing ordinary text on a page", "producing an entry for the .aux-file that is to go into the .toc-file at the end of the LaTeX-run", ...

With the example below, the grey background color is supplied only within the paragraph heading, not in page headings and not in the table of contents:

\documentclass{memoir}

\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{soul}

\makeatletter
\newcommand\code{%
  \ifx\protect\@unexpandable@protect
    \expandafter\codeinmovingarg
  \else
    \expandafter\codeintext
  \fi
}%
\makeatother
\DeclareRobustCommand{\codeinmovingarg}[1]{%
  \texorpdfstring{\texttt}{}{#1}%
}%
\DeclareRobustCommand{\codeintext}[1]{%
  \texorpdfstring{{\sethlcolor{gray}\hl{\texttt{#1}}}}%
                 {#1}%
}%
\soulregister{\code}{1}

\begin{document}

\tableofcontents\cleardoublepage

\section{\code{test}}

\end{document}

By the way again:

Sectioning commands also affect page headings.

Page headings by default are "uppercased" with memoir. In memoir you can enable/disable uppercasing of page headings via \uppercaseheads/\nouppercaseheads.

In case uppercasing of page headings is enabled, your code appearing in the argument of the \section-macro, and thus also appearing in the page-heading, will in the page heading be uppercased as well.

I would not like having code uppercased. If you too don't like this, you can within the argument of \section make your call to the \code-macro an argument of the \NoCaseChange-macro which in turn needs to be \protected:

\documentclass{memoir}

\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{soul}

\DeclareRobustCommand{\code}[1]{%
    \texorpdfstring{{\sethlcolor{gray}\hl{\texttt{#1}}}}%
                   {#1}%
}%
\soulregister{\code}{1}

\begin{document}

\tableofcontents
\cleardoublepage

\section{\protect\NoCaseChange{\code{test}}}

\end{document}
2
  • Thank you for your answer. And yeah egreg was faster, so he'll get the accepted answer. And yes I want the grey box to be in the TOC, page headings, etc. But thanks for pointing it out.
    – BrainStone
    Jul 9, 2018 at 10:07
  • @BrainStone Nonetheless I prefer putting \texorpdfstring into my macro definitions to using \pdfstringdefDisableCommands or having to think about \texorpdfstring whenever using the macro in question as part of the argument of a sectioning command/caption-command. ;-) Jul 9, 2018 at 10:12
0

I am adding an answer here instead of a new question as I had an extremely similar issue with slightly different code, and the answers provided here gave me the required hints to solve it, though in a different way.

Minimal (hopefully¹ not working) example:

\documentclass{article}
\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{soul}

\begin{document}

\begin{table}
        \caption{
                Something {\sethlcolor{blue}\hl{highlighted}} and that's all.
        }
\end{table}

\end{document}

Diagnosis

Even without a list of tables in the document, the caption presumably found its way in the aux file, where something bad happened due to the extra \@textcolor.

Workaround

I could have made it a command, with something similar to what was proposed in other answers.

The simpler way in this case (and probably a good practice anyway) is to add a short caption for the aux file, that does not contain highlight commands, even if it is not displayed anywhere in the final document (I might choose to add a list of tables later anyway):


\begin{table}
        \caption[A table with some highlight in the caption.]{
                Something {\sethlcolor{blue}\hl{highlighted}} and that's all.
        }
\end{table}

¹ Unfortunately, I couldn't reproduce the issue locally, neither with this minimal example nor with the other one, so I am not sure if it correctly highlight the issue. The issue appeared with a different version of TeXLive inside a CI system (based on Debian). The example is still fit to illustrate the issue.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .