2

I want to write a command that may takes 0 or 1 arguments, and use it in \section, e.g.:

\documentclass{article}

\usepackage{hyperref}
\usepackage{color}
\usepackage{ulem}

\makeatletter

\def\mycmd{\@ifnextchar[{\@with}{\@with[0]}}
\def\@with[#1]#2{{\color{red}\texorpdfstring{\sout{#2}}{#2}}}

\makeatother

\begin{document}

% This works:
\mycmd{Test 0}
\mycmd[1]{Test 1}

% This does not compile:
\section{\mycmd{Test 0}}
\section{\mycmd[1]{Test 1}}

\end{document}

As you can see, the initial command \mycmd uses \ifnextchar and falls back to \@with and I think this is what causes the problem. It tried using \texorpdfstring but I did not manage to get it working.

The exact error I get is:

! Argument of \@sect has an extra }.

<inserted text>

\par

l.21 \section{\mycmd{Test 0}}

Edit: The final goal is to implement a system of versioning so that \rem{} is colored or removed depending on another variable and having multiple level of version (\rem[0]{}, \rem[1]{}). I already have lots of files with the \rem{} working but I would like to add the extra arguments without having to replace everything with \rem[0].

3
  • I think it would be better if you state your goal, instead of asking for help to implement something very very strange. There is another way to the wanted result.
    – Johannes_B
    Commented Sep 23, 2016 at 16:05
  • @Johannes_B Post edited.
    – Holt
    Commented Sep 23, 2016 at 16:12
  • you get no error if you define the command using standard constructs \newcommand\mycmd[2][0]{{\color{red}\texorpdfstring{\sout{#2}}{#2}}} but that may not be what you want (hyperref warns a bit) Commented Sep 23, 2016 at 16:30

2 Answers 2

2

You need the optional argument test to be protected, but the \texorpdfstring to be seen before protection so

enter image description here

\documentclass{article}

\usepackage{hyperref}
\usepackage{color}
\usepackage{ulem}


\def\mycmd#1#{\mycmdy{#1}}
\def\mycmdy#1#2{\texorpdfstring{\mycmdx#1{#2}}{#2}}
\newcommand\mycmdx[2][0]{\textcolor{red}{\sout{#2}}}

\makeatother

\begin{document}

% This works:
\mycmd{Test 0}
\mycmd[1]{Test 1}

% This does not compile:
\section{\mycmd{Test 0}}
\section{\mycmd[1]{Test 1}}

\end{document}
1
  • Thanks for your answer, I never know when to use \def or \newcommand... By using a single \newcommand macro, I managed to have everything working without \texorpdfstring (typically, calling directly \mycmdx in your snippet). Do you think this may cause a problem later?
    – Holt
    Commented Sep 26, 2016 at 5:58
0

And here an alternate syntax that you might like

\documentclass{scrartcl}

\usepackage{xcolor}
\usepackage{ulem}

\usepackage{hyperref}

\def\setremnone#1{\long\expandafter\def\csname rem#1\endcsname##1{}}
\def\setremcolor#1#2{\long\expandafter\def\csname rem#1\endcsname##1{\texorpdfstring{\textcolor{#2}{\sout{##1}}}{##1}}}
\def\rem#1#{\csname rem\if\relax\detokenize{#1}\relax0\else#1\fi\endcsname}

\setremcolor1{red}
\setremcolor0{blue}

\begin{document}

\rem{Test 0}
\rem1{Test 1}

\section{\rem{Test 0}}
\section{\rem1{Test 1}}

\setremnone0
\setremcolor1{orange}

\rem{Test 0}
\rem1{Test 1}

\end{document}

so \rem0{content} just gobbles the content and \rem1{whatever} colors whatever in red; or whatever you decide with \setremcolor and \setremnone.

You must log in to answer this question.

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