4

Context

I would like to add automatically numbered highlighted comments in text.

Attempt

Following this answer I wrote the following

\documentclass{article}
\usepackage{color}
\usepackage{soul}

\newcounter{mycounter} \newcommand\showmycounter{\stepcounter{mycounter}\themycounter}

\definecolor{aquamarine}{rgb}{0.5, 1.0, 0.83} \newcommand{\my}[1]{\sethlcolor{aquamarine} \protect\hl{Comment \showmycounter: #1} \sethlcolor{yellow}}

\begin{document} some text \my{my first comment}\ some more text \my{my second comment}

\end{document}

which unfortunately for some strange reason increments the counter in steps of five.

enter image description here

Question

Could you please tell me how to get a unit increment on this counter?

PS: I am a bit of a newbie at latex programming. Let me apologise in advance if this question is dumb.

chris
  • 144
  • Don't put the \stepcounter inside the argument of \hl, so change the definition of \my to \newcommand\my[1]{\stepcounter{mycounter}\sethlcolor{aquamarine}\protect\hl{Comment \themycounter: #1}\sethlcolor{yellow}} Do you intend to use this in a moving argument (so \caption, \section, etc.)? – Skillmon Sep 08 '20 at 13:16
  • Which typo? :-) – Skillmon Sep 08 '20 at 13:20
  • Using \DeclareRobustCommand instead of \newcommand defines \my to be \protect\my␣ and \my␣ is then what you want. – Skillmon Sep 08 '20 at 13:28
  • Because there are situations in which you don't want the macro to be protected, also \DeclareRobustCommand doesn't check whether the macro is defined or not and silently redefines it in case it is already defined. – Skillmon Sep 08 '20 at 13:31

2 Answers2

4

The processing of \hl requires multiple passes over its argument in order to do measurements. You discovered that there are five passes and each one increments the counter. Note that \stepcounter acts globally.

You can avoid plunging into the innards of soul with some more work.

\documentclass{article}
\usepackage{color}
\usepackage{soul}

\definecolor{aquamarine}{rgb}{0.5, 1.0, 0.83}

\newif\ifstep \newcommand{\stepcounteronce}[1]{% \ifstep \global\stepfalse \stepcounter{#1}% \fi }

\newcounter{mycounter} \newcommand\showmycounter{\stepcounteronce{mycounter}\themycounter} \newcommand{\my}[1]{{% an additional group to do \sethlcolor locally \global\steptrue \sethlcolor{aquamarine}% \hl{Comment \showmycounter: #1}% }}

\begin{document}

some text \my{my first comment}

some more text \my{my second comment}

This is again \hl{yellow}

\end{document}

By adding \global\steptrue you start the machinery that allows \stepcounteronce to do \stepcounter only the first time.

Note the additional group, which allows to avoid explicitly redeclaring \sethlcolor.

enter image description here

egreg
  • 1,121,712
3

Providing my comment as an answer: You shouldn't put \stepcounter inside of the argument of \hl. Instead increment the counter before it and only put \themycounter inside \hl:

\documentclass{article}
\usepackage{color}
\usepackage{soul}

\newcounter{mycounter}

\definecolor{aquamarine}{rgb}{0.5, 1.0, 0.83} \DeclareRobustCommand{\my}[1] {% \sethlcolor{aquamarine}\stepcounter{mycounter}% \protect\hl{Comment \themycounter: #1} \sethlcolor{yellow}% }

\begin{document} some text \my{my first comment}\ some more text \my{my second comment}

\end{document}

enter image description here

Skillmon
  • 60,462