muzimuzhi / thmtools

New home for LaTeX package bundle thmtools
LaTeX Project Public License v1.3c
16 stars 3 forks source link

really before head hook (margin notes enhancement) #60

Open GMS103 opened 6 months ago

GMS103 commented 6 months ago

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.

muzimuzhi commented 6 months ago

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

mbertucci47 commented 6 months ago

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}
GMS103 commented 6 months ago

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

mbertucci47 commented 6 months ago

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}
GMS103 commented 6 months ago

@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}
mbertucci47 commented 6 months ago

@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.

GMS103 commented 6 months ago

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".

muzimuzhi commented 6 months ago

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.

mbertucci47 commented 6 months ago

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