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 Sep 23 '16 at 16:05
  • @Johannes_B Post edited. – Holt Sep 23 '16 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) – David Carlisle Sep 23 '16 at 16:30
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 Sep 26 '16 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.