2

I have a little environment to enumerate question statements. Sometimes, I want the label to not be a number but some string instead. In that case, I do not want the counter to be incremented.

% question environment
\newcounter{QuestionCounter}
\stepcounter{QuestionCounter}
\newenvironment{question}[1][\arabic{QuestionCounter}] {
  \vspace*{0.5\baselineskip}
  \noindent\textbf{Question #1. }\ignorespaces
  \ifdefstrequal{#1}{\value{QuestionCounter}}
  {\stepcounter{QuestionCounter}}
  {}}{}

The concerning if-statement here being,

\ifdefstrequal{#1}{\value{QuestionCounter}}
{\stepcounter{QuestionCounter}}
{}

How can I compare the value (expansion?) of the argument #1 and the value of the counter \value{QuestionCounter}? I have tried \ifdefstrequal{\value{#1}}{\value{QuestionCounter}} because I thought \ifdefstrequal first two arguments need to be macros.

Thanks!

scribe
  • 269
  • 1
  • 10

1 Answers1

2

No, it's incorrect usage. And you'd need to do test with full expansion.

I'd do it in a different way: if the optional argument is missing (or empty), the counter is stepped and used for numbering the question.

\documentclass{article}

\newcounter{QuestionCounter} \newenvironment{question}[1][] {% \par\addvspace{0.5\baselineskip}% \if\relax\detokenize{#1}\relax \stepcounter{QuestionCounter}% \thisquestion{\arabic{QuestionCounter}}% \else \thisquestion{#1}% \fi }{% \par\addvspace{0.5\baselineskip}% } \newcommand{\thisquestion}[1]{% \noindent\textbf{Question #1. }\ignorespaces }

\begin{document}

\begin{question} Is this a numbered question? \end{question}

\begin{question}[foo] Is this a numbered question? \end{question}

\begin{question} Is this a numbered question? \end{question}

\end{document}

enter image description here

egreg
  • 1,121,712
  • Mind explaining how \if\relax\detokenize{#1}\relax checks for a lack of optional argument? – scribe Sep 01 '20 at 17:42
  • 1
    @scribe See https://tex.stackexchange.com/a/33826/4427 The default value for the optional argument is empty; if no optional argument is specified, \detokenize{#1} returns nothing and the test \if\relax\relax returns true. Otherwise \detokenize{#1} will deliver something that cannot start with \relax, so the test \if\relax<something> returns false and the rest of the string disappears as part of the “true text”. – egreg Sep 01 '20 at 17:47