将 todonotes 与 mdframed 结合使用,突出显示段落并撰写笔记

将 todonotes 与 mdframed 结合使用,突出显示段落并撰写笔记

我正在尝试结合todonotes使用mdframed以创建一个统一的命令,允许同时编写待办事项和突出显示段落。语法是\todo[<todo-options>]{<todonote>}<paragraph>,其中基本上所有参数都是可选的(因此可以使用\todo{<todonote>}\todo<paragraph>或两者一起使用)。

我认为我已经使用下面的代码完成了大部分工作,但存在两个问题:

  1. 当同时使用\todomdframed环境时,会出现一个空行,我需要手动用 '删除' \vspace{-1\baselineskip}。这会产生不良副作用,即这两个行号重叠。我该如何避免出现这个空行?

  2. 由于这个问题,的定义\todo感觉效率低下,因为我需要两个环境实例mdframed,一个有\vspace{},一个没有。

我的解决方案如何改进?

\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}

在此处输入图片描述

答案1

我不太清楚为什么会出现换行符。这肯定是 todonotes 和 lineno 包之间不兼容造成的。您用来\vspace修复此问题的 hack 可能和其他方法一样好。

修复不正确的行号的一种方法是“手动”减少 lineno 包使用的计数器。您可以更有效地编写代码,以避免环境notes出现两次:

\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}%
    }
}%

虽然我并不认为这是一个优雅的解决方案,但它似乎解决了你的问题:

在此处输入图片描述

请注意,我使用了\IfNoValueF而不是\IfNoValueTF,因为您只关心有值的情况,而我使用了\internallinenumbers而不是环境,因为无需在您的notes环境中启动第二个环境。\ifLineNumbers对于您的 MWE 来说,这是多余的,因为它只是 lineno 包用来查看行号是否打开的开关,但如果您打算打开和关闭行号,您可能需要它。最后,正如您所猜测的,runninglinenumber是 lineno 用于运行行号的计数器。

相关内容