thmtools icon indicating copy to clipboard operation
thmtools copied to clipboard

really before head hook (margin notes enhancement)

Open GMS103 opened this issue 1 year ago • 9 comments

In order to be able to put \todo (from todonotes) at the same level as the head of a theorem, it seems to me that preheadhook cannot be used.

So I am doing the following hack (modifying amsthm.sty):

\dth@everypar={%
  \@minipagefalse \global\@newlistfalse
  \@noparitemfalse
  \if@inlabel
    \global\@inlabelfalse
    \begingroup \setbox\z@\lastbox
     \ifvoid\z@ \kern-\itemindent \fi
    \endgroup
    \myheadbefore % <--- addition
    \unhbox\@labels
  \fi
  \if@nobreak \@nobreakfalse \clubpenalty\@M
  \else \clubpenalty\@clubpenalty \everypar{}%
  \fi
}%

which allows me to do for instance

\def\myheadbefore{\todo{Important}}

(of course the definition has to be changed before every theorem environment, but that is another question).

I was wondering if you could integrate this idea in your package.

GMS103 avatar Dec 28 '23 13:12 GMS103

Could you provide a complete latex example showing what you'd like to get?

muzimuzhi avatar Dec 28 '23 13:12 muzimuzhi

You can use the posthead hook and locally force \reversemarginpar to make the todonote appear on the left.

\documentclass{article}
\usepackage{amsthm,thmtools,todonotes}

\declaretheorem{theorem}

\addtotheorempostheadhook[theorem]{\reversemarginpar\todo{Important}}

\begin{document}

\begin{theorem}
Some text
\end{theorem}

\end{document}

mbertucci47 avatar Dec 28 '23 14:12 mbertucci47

Here is an example.

% !TEX program = pdflatexmk
\documentclass{article}
\usepackage{todonotes} 
\reversemarginpar

\usepackage{amsthm,thmtools}
\makeatletter
\dth@everypar={%
  \@minipagefalse \global\@newlistfalse
  \@noparitemfalse
  \if@inlabel
    \global\@inlabelfalse
    \begingroup \setbox\z@\lastbox
     \ifvoid\z@ \kern-\itemindent \fi
    \endgroup
    \myheadbefore 
    \unhbox\@labels
  \fi
  \if@nobreak \@nobreakfalse \clubpenalty\@M
  \else \clubpenalty\@clubpenalty \everypar{}%
  \fi
}
\makeatother
\declaretheorem{theorem}

\begin{document}

Blah blah blah.

\def\myheadbefore{\todo[noline]{Important}}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

Blah blah blah.

\def\myheadbefore{}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

Blah blah blah.

\def\myheadbefore{\todo[noline,backgroundcolor=green]{Useful}}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

\end{document}

thmtools_todonotes.pdf

GMS103 avatar Dec 28 '23 15:12 GMS103

Try this.

\documentclass{article}
\usepackage{todonotes} 
\reversemarginpar

\usepackage{amsthm,thmtools}

\declaretheorem{theorem}

\addtotheorempostheadhook[theorem]{\myheadbefore}

\begin{document}

Blah blah blah.

\def\myheadbefore{\todo[noline]{Important}}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

Blah blah blah.

\def\myheadbefore{}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

Blah blah blah.

\def\myheadbefore{\todo[noline,backgroundcolor=green]{Useful}}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

\end{document}

mbertucci47 avatar Dec 28 '23 15:12 mbertucci47

@mbertucci47: I had already tried something like that. But I cannot get it to work when postheadspace=\newline:

% !TEX program = pdflatexmk
\documentclass{article}
\usepackage{todonotes} 
\reversemarginpar

\usepackage{amsthm,thmtools}
\declaretheoremstyle[
    postheadspace=\newline,
    postheadhook={\myheadbefore},
    ]
    {mytheostyle}
\declaretheorem[style=mytheostyle]{theorem}

\begin{document}

Blah blah blah.

\def\myheadbefore{\todo[noline]{Important}}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

Blah blah blah.

\def\myheadbefore{}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

Blah blah blah.

\def\myheadbefore{\todo[noline,backgroundcolor=green]{Useful}}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

\end{document}

GMS103 avatar Dec 28 '23 15:12 GMS103

@GMS103 Yes that is more difficult. If you know the theorem will always add a new line, you can manually adjust your \todo like in this TeX.sx post.

mbertucci47 avatar Dec 28 '23 15:12 mbertucci47

I also tried that (with -\baselineskip), but the height of the line after the head is unknown beforehand.

In any case, I was asking for a general mechanism to get something "really before the head".

GMS103 avatar Dec 28 '23 15:12 GMS103

Try preheadhook={\AddToHookNext{para/begin}{\myheadbefore}}, which makes use of LaTeX paragraph hooks introduced in LaTeX 2021-06-01 and documented in texdoc ltpara-doc.

It seems postheadhook is usable too.

I can see no lines connecting todos to the placements where \todo were inserted. Is this expected behavior?

\documentclass{article}
\usepackage{todonotes}
\reversemarginpar

\usepackage{amsthm,thmtools}

\declaretheoremstyle[
    postheadspace=\newline,
    preheadhook={\AddToHookNext{para/begin}{\myheadbefore}},
  ]{mytheostyle}
\declaretheorem[style=mytheostyle]{theorem}

\begin{document}

Blah blah blah.

\def\myheadbefore{\todo[noline]{Important}}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

Blah blah blah.

\def\myheadbefore{}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

Blah blah blah.

\def\myheadbefore{\todo[noline,backgroundcolor=green]{Useful}}

\begin{theorem}[Euclid]
  For every prime $p$, there is a prime $p'>p$.
\end{theorem}

\end{document}

image

BTW I'm going to edit https://github.com/muzimuzhi/thmtools/issues/60#issuecomment-1871252419 to add two missing % in \dth@everypar={...}. They were there in original snippet in https://github.com/muzimuzhi/thmtools/issues/60#issue-2058426613, but somehow got lost in following full example and caused paragraph indent.

muzimuzhi avatar Dec 30 '23 11:12 muzimuzhi

@muzimuzhi I think the lack of lines is expected from the noline option passed to \todo. Also, good idea using the par hooks!

mbertucci47 avatar Jan 07 '24 00:01 mbertucci47