21

I would like to make a \todo command and environment whose behavior changes depending whether I define a command \showtodos. A basic \todo command is simple to write:

\ifthenelse{\isundefined{\showtodos}}{
  \newcommand{\todo}[1]{}
}{
  \newcommand{\todo}[1]{#1}
}

Essentially, I would like to hide the content of the \todo command unless \showtodos is defined. My question is how to write an environment which does the same thing?

2
  • Welcome to TeX.SE! A hint: If you indent lines of code by 4 spaces, they will auto-format nicely. And, by adding backticks, `, around LaTeX commands, they will also be offset visually for readers.
    – Mico
    Dec 11, 2011 at 16:50
  • 4
    There is the todonotes package, which you might find useful. If you load it with the package option disable (\usepackage[disable]{todonotes}), nothing will be displayed. Otherwise, its \todo{Rewrite this chapter} macro works really well.
    – doncherry
    Dec 11, 2011 at 17:05

3 Answers 3

13

There are quite a few packages that do what you want, which have been mentioned in the comments.

However, if you want your own solution, you can use the comment environment from the verbatim package to your advantage.

The solution below defines a todo environment that will only show its contents if \showtodos is defined; otherwise it puts \begin{comment} and \end{comment} around the environment.

\documentclass{article}
\usepackage{verbatim}   % for the comment environment
\usepackage{ifthen}
\usepackage{lipsum}

% if you want to see the todo
\newcommand{\showtodos}{show them}  % comment this line if you don't 
                                    % want to see todo environment

% the todo environment
\newenvironment{todo}%
        {%
            \ifthenelse{\isundefined{\showtodos}}%
                    {\expandafter\comment}%
                    {}%
                    }%
         {%
            \ifthenelse{\isundefined{\showtodos}}%
                    {\expandafter\endcomment}%
                    {}%
          }

\begin{document}

Outside of the the `todo' environment

\begin{todo}
 Here we are in the `todo' environment.
\end{todo}
\end{document}
2
  • 4
    Why is the \expandafter necessary, please?
    – The Vee
    Sep 30, 2015 at 20:25
  • I suspect expandafter is actually unnecessary here (although not very sure if ifthen package does it correctly), it's only necessary if some primitive TeX conditional is used, see tex.stackexchange.com/questions/21262/…
    – user202729
    Jun 9, 2022 at 16:38
5

Here is a basic example using \@ifundefined:

enter image description here

\documentclass{article}
\makeatletter
\newcommand{\todo}{%
  \@ifundefined{showtodo}{\relax}{%
    This is stuff to do.%
  }%
}
\makeatother
\begin{document}
1 \todo \par
2 \newcommand{\showtodo}{} \todo
\end{document}

Here is a basic example using a traditional \newif statement, as an alternative:

\documentclass{article}
\newif\ifshowtodocmd \showtodocmdfalse
\newcommand{\showtodo}{\showtodocmdtrue}
\newcommand{\todo}{%
  \ifshowtodocmd
    This is stuff to do.%
  \fi}
\begin{document}
1 \todo \par
2 \showtodo \todo
\end{document}

The same could be applied to environments. The etoolbox package also provides a very rich set of macros to test for the existence of other macros or other conditioning commands in general.

For reference on command existence, read the TeX FAQ entry on Is this command defined?

1

In the end, you'll have to specify somewhere whether to enable or disable todos anyway, the need for a command like \enabletodos feels a bit artificial to me. You could just use something like

\newcommand\printTodo[1]{I still have to do #1}
\newcommand\todo[1]{\printTodo{#1}}

If you want to disable \todo, just replace the second line with

\newcommand\todo[1]{}

This leaves your "how to print todos" command invariant, and is basically equivalent to not specifying \showtodos. As a bonus, you can re-define the todo command anywhere, so you can easily switch the behavior throughout the document.

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