使用 thmtools 的 postheadhook 时需要额外的空间

使用 thmtools 的 postheadhook 时需要额外的空间

这个问题与我的上一个问题如何在页边栏填写定理的名称、编号和注释。

经过几个小时的反复试验,我得出了以下解决方案:

\documentclass[fontsize=11pt, paper=a4, DIV=classic]{scrbook}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{amsthm}
\usepackage{thmtools}
\usepackage{ragged2e}
\usepackage{changepage}
\usepackage{blindtext}

\KOMAoption{mpinclude}{true}
\recalctypearea
\setlength{\marginparsep}{2em}
\setlength{\marginparwidth}{10em}

\makeatletter

\newcommand{\RaggedOuter}%
{%
  \if@twoside%
    \checkoddpage%
    \ifoddpage%
      \RaggedRight%
    \else%
      \RaggedLeft%
    \fi%
  \else%
    \RaggedRight%
  \fi%
}

\newcommand{\cl@ThmMarginCaption}%
{
  \leavevmode%
  \marginpar%
  {%
    \RaggedOuter%
    \hbadness=10000%
    \the\thm@headfont\thmt@thmname~\thechapter.\arabic{\thmt@envname}\\%
    \the\thm@notefont\thmt@optarg%
  }%
}

\declaretheoremstyle%
[%
  spaceabove={\parskip},%
  spacebelow=0pt,%
  headindent=0pt,%
  postheadspace=0pt,%
  headformat={},%
  headpunct={},%
  headfont=\sffamily\bfseries\small,%
  notefont=\rmfamily\mdseries\small,%
  bodyfont=\normalfont,%
  preheadhook={},%
  postheadhook={\cl@ThmMarginCaption},%
]%
{thmmcaption}

\makeatother

\declaretheorem[name=Definition, numberwithin=chapter, style=thmmcaption]{definition}
\declaretheorem[name=Satz,       numberwithin=chapter, style=thmmcaption]{theorem}


\begin{document}

\chapter{Theorems with margin captions}

\blindtext

\begin{definition}[Kellerautomat (KA)\\ pushdown automaton (PDA)]
Eine ganz wichtige Definition, die natürlich länger als eine Zeile sein sollte, um sehen zu können, ob alles funktioniert wie gewünscht.
\end{definition}

\blindtext

\clearpage

\blindtext

\begin{theorem}[Satz von Radó]
Die Radó-Funktion ist nicht berechenbar.
\end{theorem}

\blindtext

\end{document}

这接近预期结果,但是在定理主体的开头存在不必要的空间。

定理主体开头的额外空间

删除该命令后,该空格会消失\leavevmode,但边注会附加到上一段的最后一行。

这种行为并不太令人惊讶,因为手册在解释中指出postheadhook“请注意,所有后端似乎都会延迟排版实际的头部,因此此处的代码应该进入水平模式以确保它位于头部之后,但如果您的正文以另一个列表开始,这将改变间距/换行行为。”

但是,这个大约0.3em的空格是什么原因造成的,怎样才能消除它呢?

(我会保留我的上一个问题因为在边距栏中放置定理名称、编号和注释的方法可能完全不同。)

答案1

%需要用A来结束\begin{theorem}[Satz von Radó]%。我意识到最好通过代码忽略该空格,而不是手动将其删除。请参阅附录对于这种可能性:

\documentclass[fontsize=11pt, paper=a4, DIV=classic]{scrbook}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{amsthm}
\usepackage{thmtools}
\usepackage{ragged2e}
\usepackage{changepage}
\usepackage{blindtext}

\KOMAoption{mpinclude}{true}
\recalctypearea
\setlength{\marginparsep}{2em}
\setlength{\marginparwidth}{10em}

\makeatletter

\newcommand{\RaggedOuter}%
{%
  \if@twoside%
    \checkoddpage%
    \ifoddpage%
      \RaggedRight%
    \else%
      \RaggedLeft%
    \fi%
  \else%
    \RaggedRight%
  \fi%
}

\newcommand{\cl@ThmMarginCaption}%
{%
  \leavevmode%
  \marginpar%
  {%
    \RaggedOuter%
    \hbadness=10000%
    \the\thm@headfont\thmt@thmname~\thechapter.\arabic{\thmt@envname}\\%
    \the\thm@notefont\thmt@optarg%
  }%
}

\declaretheoremstyle%
[%
  spaceabove={\parskip},%
  spacebelow=0pt,%
  headindent=0pt,%
  postheadspace=0pt,%
  headformat={},%
  headpunct={},%
  headfont=\sffamily\bfseries\small,%
  notefont=\rmfamily\mdseries\small,%
  bodyfont=\normalfont,%
  preheadhook={},%
  postheadhook={\cl@ThmMarginCaption},%
]%
{thmmcaption}

\makeatother

\declaretheorem[name=Definition, numberwithin=chapter, style=thmmcaption]{definition}
\declaretheorem[name=Satz,       numberwithin=chapter, style=thmmcaption]{theorem}


\begin{document}

\chapter{Theorems with margin captions}

\blindtext

\begin{definition}[Kellerautomat (KA)\\ pushdown automaton (PDA)]
Eine ganz wichtige Definition, die natürlich länger als eine Zeile sein sollte, um sehen zu können, ob alles funktioniert wie gewünscht.
\end{definition}

\blindtext

\clearpage

\blindtext

\begin{theorem}[Satz von Radó]%
Die Radó-Funktion ist nicht berechenbar.
\end{theorem}

\blindtext

\end{document}

在此处输入图片描述


附录

根据 OP 关于如何一次重新定义环境以插入适当的 的评论\ignorespaces,我决定通过引入辅助宏(需要 )来实现该方法的自动化\makeatletter。已编辑以处理空白可选参数。

\newcommand\Declaretheorem[2][]{%
  \ifx\relax#1\relax\declaretheorem{#2}\else\declaretheorem[#1]{#2}\fi%
  \expandafter\let\csname cl@orig@#2\expandafter\endcsname\csname#2\endcsname%
  \expandafter\let\csname cl@orig@end#2\expandafter\endcsname\csname end#2\endcsname%
  \renewenvironment{#2}[1][]{\csname cl@orig@#2\endcsname[##1]\ignorespaces}%
    {\csname cl@orig@end#2\endcsname}%
}

然后,如果我将声明从

\declaretheorem[name=Satz,       numberwithin=chapter, style=thmmcaption]{theorem}

\Declaretheorem[name=Satz,       numberwithin=chapter, style=thmmcaption]{theorem}

一切都自动进行,无需人工干预。此单字母修复应适用于所有已声明的定理。

相关内容