6

I am trying to combine todonotes with mdframed to create a unifying command that allows to write todos and and highlight paragraphs at the same time. The syntax is \todo[<todo-options>]{<todonote>}<paragraph>, where essentially all arguments are optional (so one could use \todo{<todonote>}, \todo<paragraph> or both together).

I think I have done most of it with the code below, but two issues:

  1. When both \todo and the mdframed environment are used, there is an empty line, that I need to manually 'remove' with \vspace{-1\baselineskip}. This has the unwanted side-effect that these two linenumbers are overlapping. How can I avoid this empty line?

  2. Because of this issue, the definition of \todo feels inefficient because I need two instances of the mdframed environment, one with the the \vspace{} and one without.

How can my solution be improved?

\documentclass{scrartcl}
\usepackage{xparse}
\usepackage{todonotes}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{lineno}

\newmdenv[leftmargin=\dimexpr-0.5em-3pt, innerleftmargin=0.5em,
          rightmargin=\dimexpr-0.5em-3pt, innerrightmargin=0.5em,
          linewidth=3pt,linecolor=red, topline=false, bottomline=false,
          innertopmargin=0pt,innerbottommargin=0pt,skipbelow=0pt,skipabove=0pt,%
         ]{notex}

\newenvironment{note}%
 {\vskip\dimexpr\dp\strutbox-\prevdepth\relax\notex\strut\ignorespaces}%
 {\xdef\notetpd{\the\prevdepth}\endnotex\vskip-\notetpd\relax}

\let\oldtodo\todo

\makeatletter%
\DeclareDocumentCommand{\todo}{ O{} +g +d<> }{%
    \IfNoValueTF{#2}{\relax}{%
         \oldtodo[caption={#2},size=\footnotesize,#1]{\renewcommand{\baselinestretch}{1}\selectfont\sffamily#2\par}%
    }%
    \IfNoValueTF{#3}{\relax}{%
        \IfNoValueTF{#2}{% when parmark but no todo
            \begin{note}%
                \begin{internallinenumbers}%
                    \indent%
                    #3%
                \end{internallinenumbers}%
            \end{note}%
    }{% when parmark and todo
        \vspace{-1\baselineskip}%
        \begin{note}%
            \begin{internallinenumbers}%
                \indent%
                #3%
            \end{internallinenumbers}%
        \end{note}%
        }%
    }%
}%
\makeatother

\begin{document}

\linenumbers

\todo{Lorem Ipsum is simply dummy text of the printing and
typesetting industry}Lorem Ipsum is simply dummy text of the
printing and typesetting industry. Lorem Ipsum has been the
industry's standard dummy text ever since the 1500s, when an
unknown printer took a galley of type and scrambled it to make a
type specimen book.

Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry's standard dummy text
ever since the 1500s, when an unknown printer took a galley of type
and scrambled it to make a type specimen book.

\todo{Todonote}<Lorem Ipsum is simply dummy text of the printing
and typesetting industry. Lorem Ipsum has been the industry's
standard dummy text ever since the 1500s, when an unknown printer
took a galley of type and scrambled it to make a type specimen
book.>

Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry's standard dummy text
ever since the 1500s, when an unknown printer took a galley of type
and scrambled it to make a type specimen book.

\todo<Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the industry's standard
dummy text ever since the 1500s, when an unknown printer took a
galley of type and scrambled it to make a type specimen book.>

\end{document}

enter image description here

2

I am not entirely sure why the newline appears. It must be an incomparability between the todonotes and lineno packages. Your hack of using \vspace to fix this issue is probably as good as anything.

One way to fix the incorrect line numbering is to "manually" decrement the counter used by the lineno package. You can write your code a little more efficiently to avoid having the notes environment appear twice:

\DeclareDocumentCommand{\todo}{ O{} +g +d<> }{%
    \IfNoValueF{#2}{%
         \oldtodo[caption={#2},size=\footnotesize,#1]{\sffamily#2}%
    }%
    \IfNoValueF{#3}{%
            \IfNoValueF{#2}{ \vspace{-1\baselineskip} }% remove unwanted linebreak
            \begin{note}%
                    \internallinenumbers%
                    \IfNoValueF{#2}{% fix line numbers when todo+note
                       \ifLineNumbers\addtocounter{runninglinenumber}{-1}\fi%
                    }%
                    \indent%
                    #3%
            \end{note}%
    }
}%

Although I don't claim that this is an elegant solution, it seems to fix your problem:

enter image description here

Notice that I have used \IfNoValueF's instead of \IfNoValueTF's because you only care about the cases where there are values and I have used \internallinenumbers rather than the environment as there is no need to start a second environment inside your notes environment. The \ifLineNumbers is overkill for your MWE as it is just the switch that the lineno package uses to see if line numbering is turned on, but if you plan on turning line numbers on and off you probably need this. Finally, as you would guess, runninglinenumber is the counter that lineno uses for the running line numbers.

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.