Friday, September 14, 2007

Todo notes in Latex

An updated version of the code below can be found at http://midtiby.blogspot.com/2008/05/updated-todonotes-package.html.

This is a description of how to place todo notes in your latex document, and how to collect the content of these in a structure like a table of contents (eg. a list of things todo)




A year and a half ago, when I wrote my bachelor report, I had a need to mark needed changes in the margin of a latex document. I wanted to place a note in the margin with a command like

\todo{Something that has to be done}

The solution was to use the marginpar command, in the definition below

\newcommand{\todo}[1]{\marginpar{#1}}

Later this approach was improved by generating a list of these todo items. The behavior of \todo was now to print something in the margin and add an item in the todolist.

\newcommand{\todo}[1]{
\addcontentsline{tdo}{todo}{\protect{#1}}
\marginpar{#1}
}

Additionally I defined a command to generate the list of todos.

\makeatletter \newcommand \listoftodos{\section*{Todo list} \@starttoc{tdo}}
\newcommand\l@todo[2]
{\par\noindent \textit{#2}, \parbox{10cm}{#1}\par} \makeatother

Now the list of todo's could be inserted by using the command

\listoftodos

For some time ago, I began reading about the portable graphics format (PGF) and wanted to tinker a bit with it. PGF is a great tool for generating graphics for latex documents (you can find a lot of examples at www.fauskes.net/pgftikzexamples/.) Especially the possibility of overlaying your existing text with graphics were interesting.

One of the results is this improved todo note code for latex.

\newcommand{\todo}[1]{
% Add to todo list
\addcontentsline{tdo}{todo}{\protect{#1}}
%
\begin{tikzpicture}[remember picture, baseline=-0.75ex]
\node [coordinate] (inText) {};
\end{tikzpicture}
%
% Make the margin par
\marginpar{
\begin{tikzpicture}[remember picture]
\definecolor{orange}{rgb}{1,0.5,0}

\draw node[draw=black, fill=orange, text width = 3cm] (inNote)
{#1};
\end{tikzpicture}
}
%
\begin{tikzpicture}[remember picture, overlay]
\draw[draw = orange, thick]
([yshift=-0.2cm] inText)
-| ([xshift=-0.2cm] inNote.west)
-| (inNote.west);
\end{tikzpicture}
%
}

Currently there are a minor glitch of the code, at the location of the \todo command latex inserts a large amount of space, which I would like to avoid.

I use this piece of code myself, but if any of you would like to use it you should be welcome. Comments or ideas for improving the code are of cause welcome

Henrik

25 comments:

Henrik Skov Midtiby said...

The minor glitch with the extra space has been solved by Kjell Magne Fauske. The problem was that latex treats newlines as spaces. The solution was to comment out the last part of all code lines.

The code now looks like:
% Command for inserting a todo item
\newcommand{\todo}[1]{%
% Add to todo list
\addcontentsline{tdo}{todo}{\protect{#1}}%
%
\begin{tikzpicture}[remember picture, baseline=-0.75ex]%
\node [coordinate] (inText) {};
\end{tikzpicture}%
%
% Make the margin par
\marginpar{%
\begin{tikzpicture}[remember picture]%
\definecolor{orange}{rgb}{1,0.5,0}
\draw node[draw=black, fill=orange, text width = 3cm] (inNote)
{#1};%
\end{tikzpicture}%
}%
%
\begin{tikzpicture}[remember picture, overlay]%
\draw[draw = orange, thick]
([yshift=-0.2cm] inText)
-| ([xshift=-0.2cm] inNote.west)
-| (inNote.west);
\end{tikzpicture}%
%
}%

Olivier Verdier said...

This trick is so cool! Thanks a lot! :-)

sivaram said...

Ok, I'm thinking of a work flow here. If I were to fix each of the todo, what's the easiest way to make the todos go away as and when I fix things?

sivaram

Henrik Skov Midtiby said...

#sivaram

I may have misunderstood your problem. My own workflow when using these todo notes are

1. Add a todo note when I notice something which needs attention (add \todo{description}
2. When I don't know what to do, I'll take a look on the list of todos and select one to fix.
3. When the issue is fixed I remove the \todo{description} from the source code.

If you want to export a document without todonotes, you can redifine the todo command as a command with no effect.
\renewcommand{\todo}{}

I hope that this was usefull.

Best
Henrik

Unknown said...

Hello,
Thank for this great piece of code!
A question though: it looks not so good in a double sided document.
Is there a way to fix this?

Also is there a way to have the note width automatically set to the marginpar width?

Best regards,
Mat

Kjell Magne Fauske said...

I have updated the "Todo notes" example in the gallery at fauskes.net. It now supports double sided documents. I have also included an example that shows how to adjust the note width to the margin width.

Unknown said...

Nice tool! However, the fact that PDFTeX is required is a limitation for me since I use DVI that allows me to jump from my editor directly into the associated position of the DVI file and back to the editor. In pdf, this does not seem possible so far.

The problem is, that in DVI everything looks kind of wrong placed. Thanks for your comment!

Henrik Skov Midtiby said...

# Jakob

Hi, I can reproduce the behavior you describe. For some (for me unknown) reason the text content of the margin node is placed differently when you produce pdf or dvi files.

To get something useable you can use the code given below, it seems to work the "right way" independent of the end format (dvi or pdf).

Best
Henrik

====== begin "test.tex" ========
\documentclass{article}

\usepackage{todonotes}

\begin{document}

\section{Testing}

\todo{Hello, this is a very long text, that wraps over several lines \ldots}%
Some text in the main part \ldots
Some text in the main part \ldots
Some text in the main part \ldots
Some text in the main part \ldots
Some text in the main part \ldots
Some text in the main part \ldots
Some text in the main part \ldots
Some text in the main part \ldots

\end{document}
====== end "test.tex" ========

====== begin "todonotes.sty" ========
% Part: Identification
\ProvidesPackage{todonotes}

% Part: Initial code
\RequirePackage{xkeyval}
\newcommand{\@backgroundcolor}{orange}
\newcommand{\@bordercolor}{black}

% Part: The declaration of options
\define@boolkey{todonotes.sty}%
[todo]{disable}{}
\define@key{todonotes.sty}%
{color}{\renewcommand{\@backgroundcolor}{#1}}
\define@key{todonotes.sty}%
{bordercolor}{\renewcommand{\@bordercolor}{#1}}
\ProcessOptionsX

% Part: The package loading part
\RequirePackage{tikz}

% Part: The main code part
\iftododisable
\newcommand{\listoftodos}{}
\newcommand{\todo}{}
\else
\newcommand{\listoftodos}
{\section*{Todo list} \@starttoc{tdo}}
\newcommand{\l@todo}
{\@dottedtocline{1}{0em}{2.3em}}

\tikzstyle{notestyle} = [draw=\@bordercolor,
fill=\@backgroundcolor, text width = 3cm]
\tikzstyle{notestyleleft} = [notestyle]
\tikzstyle{connectstyle} = [draw = \@backgroundcolor, thick]

\newcommand{\todo}[1]{%
% Add to todo list
\addcontentsline{tdo}{todo}{\protect{#1}}%
%
% Remember where we are
\begin{tikzpicture}[remember picture, baseline=-0.75ex]%
\node [coordinate] (inText) {};%
\end{tikzpicture}%
%
% Make the margin par
\marginpar{% Draw note in right margin
\tikz[remember picture] \draw node[notestyle] {}; \\ %
#1 %
\tikz[remember picture] \draw node[notestyle] (inNote) {};%
\begin{tikzpicture}[remember picture, overlay]%
\draw[connectstyle]
([yshift=-0.2cm] inText)
-| ([xshift=-0.2cm] inNote.west)
-| (inNote.west);
\end{tikzpicture}%
}%
}%
\fi
====== end "todonotes.sty" ========

Anonymous said...

Hello,

if i use the 'todonotes.sty', i have the following result:
Please look here: http://www.need4.de/download/todonotes.jpg

On the right side is missing text.
How can i solve this.
Can i set the textwide manually ?

Changes in 'fill=\@backgroundcolor, text width=3cm]' only affects the orange bars.

Maybe this is a problem of my marginsettings, but the sidelayout is fixed and i can't change that.

Joachim

Henrik Skov Midtiby said...

# need4

In the version of the package that you used, it wasn't possible to set the width of the todo note.

After your request I have update the todonotes package with some new options, including the possibility of setting the width of the todo notes.

The updated version can be found at
http://midtiby.blogspot.com/2008/05/updated-todonotes-package.html

Best
Henrik

Anonymous said...

# henrik

Hello,

OK, the new version is mutch better but at even numered sides there is also a cut on the text.
Please look here: http://www.need4.de/download/todonotes2.jpg

On the right side it looks OK with setting: \newcommand{\@textwidth}{2cm}

Joachim

Kjell Magne Fauske said...

# need4

Not sure if this helps, but I noticed in the source code that todonotes.sty does not use the correct syntax for placing notes in the left margin (i.e)

\marginpar[left text]{right text}

I have fixed this in the version available here:
todonotes.sty.

(part of the Todo notes example)

- Kjell Magne Fauske

Anonymous said...

# Kjell

No that doesn't work with my tex-file.
It looks like this: http://www.need4.de/download/todonotes3.jpg

There are douple entries ... and not the right position.

i think henrik is on the right way but here is to solve the left margin problem.

Joachim

Henrik Skov Midtiby said...

# need4

Can you try to set the marginparwidth to 2 cm.

\setlength{\marginparwidth}{2cm}

It might be the problem with your document.

Best Henrik

Anonymous said...

# henrik

thanks, that fixed my problem.

Joachim

Unknown said...

First of all: excellent job - thank you very much!

Just one little remark - would it not be useful to write:

\newcommand{\@textwidth}{.95\marginparwidth}%


instead of:

\newcommand{\@textwidth}{3cm}

?

That would allow to tune the note width accordingly to the other margins settings imposed by user or other packages (for instance the geometry package).

Henrik Skov Midtiby said...

# Marek Bury

Hi

There is an updated version of the todonotes macros / package at http://midtiby.blogspot.com/2008/07/todonotes-version-2008-07-28.html

In that version it is possible to send options to the package when it is loaded. For instance you might want to use
\usepackage[textwidth=0.95\marginparwidth]{todonotes}

Best
Henrik

Unknown said...

Hi Henrik,

though I've only been using your package for a month now, I've grown really fond of it. Thanks.

But since the release of the latest version I can not use it anymore with the documentclass cc. A minmal example would look like


\documentclass[noccpublish, draft]{cc}

\usepackage{todonotes}

\begin{document}
\todo{all you can leave behind}
\end{document}


MikTeX 2.7 quits with a rather mysterious error message:


ERROR: Undefined control sequence.

--- TeX said ---
argument ...ame }}[]}\fi \@tempa }\dth@everypar
={\@minipagefalse \global ...
l.5096 }{}


In the log-file, this appears just after

("C:\Program Files\MiKTeX 2.7\tex\generic\oberdiek\atbegshi.sty"
Package: atbegshi 2008/07/31 v1.9 At begin shipout hook (HO)
)
\Hy@abspage=\count113
\c@Item=\count114


I am not sure, but I guess, atbeshi.sty was loaded as part of hyperref.sty. Perhaps somebody with another (exotic) documentclass ahs encountered similar problems. (Everything works just fine, if I go with the plain article class. Unfortunately, that is not an option in this case.)

Do you have any idea, how I could fix this?

Unknown said...

After some experimentation I can add some additional information on the previous problem. The cc-class can also be loaded as package cc-cls. Then the same problem/error only appears, when cc-cls is loaded before todonotes. When I load them the other way round, my minimal example (and also my larger document) compile perfectly well!

Concerning the interaction with other packages, the cc-class mentions in its documentation only that "hyperref must be loaded after cc-cls".

So I'm a little bit confused now, assuming that hyperref gets loaded, when todonotes gets loaded, the situation where my code compiles well is just the opposite from what is required by the cc-class documentation.

On the other hand, I don't know anything about the order that LaTeX loads packages that are required by other packages. But perhaps this additional data helps in solving the problem.

Greets,
Konstantin

Henrik Skov Midtiby said...

Hi Konstantin

For finding the part of the todonotes code that is the issue, I would minimize the todonotes.sty file as much as possible while the error still occured. Unfortunately this takes a lot of time ... (remove lines one by one, compile and check if the problem persists)

An other approach is to test various things that might trigger problems, in this case the loading order of the hyperref package and the cc-cls package. Is the error message the same when the following document is compiled?


\documentclass[noccpublish, draft]{cc}
\usepackage{hyperref}
\begin{document}
all you can leave behind
\end{document}


It'll probably take some days before I have more time to examine the problem properly. But if you find a "cure" let me know.

Best
Henrik

Unknown said...

Hi Henrik,

thanks for the quick reply.

Indeed, your example gives the same error message, so it's probably a problem of the cc-cls and the hyperref package. So, I'll try a fix on that end, too.

One thing leaves me a little puzzled. When I compiled with an older version of todonotes just before christmas, the error did not occur then. So, I hope, there might be a fix from this side, too.

I'll let you know, when I figured out something.

Regards,
Konstantin

Unknown said...
This comment has been removed by a blog administrator.
Сергей Лазарев said...
This comment has been removed by a blog administrator.
tina tin said...
This comment has been removed by a blog administrator.
Unknown said...
This comment has been removed by a blog administrator.