解释

解释

我正在使用 thmtools 包来创建我的定理环境,并且我希望有一个依赖于定理开始的 headpunct:如果它以枚举开始(即,如果它以代码开始\begin{enumerate})那么我想使用一个点.作为 headpunct,否则我想使用破折号---作为 headpunct。

我可以定义一个命令\dashorpoint,使用并根据该命令检查下一个字符\@ifnextchar,从而得到正确的结果。但是,我无法使用此命令来解决我的问题,因为在 thmtools 中使用时,它不会抓取定理主体的第一个字符。

这个问题有简单的解决方案吗(无需定义额外的定理样式)?


下面的图片也许可以解释我的问题。

在此处输入图片描述

我曾经thmtools创建过这些环境,但理想情况下,我希望使用一种能够自动给出正确输出的单一定理风格。


这里我有一个简单的例子:我想为两种情况定义一个定理样式,并且我想摆脱现在手动添加的 ~ 符号。

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

\declaretheoremstyle[
  notefont=\bfseries,
  notebraces={}{},
  headformat=\NUMBER\NOTE\ ,
  headpunct=---,
]{dash}
\declaretheoremstyle[
  notefont=\bfseries,
  notebraces={}{},
  headformat=\NUMBER\NOTE,
  headpunct=.
]{point}
\declaretheorem[style=dash, name={}]{f}
\declaretheorem[style=point, name={}]{g}

\begin{document}
\begin{f} [Theorem]
\begin{enumerate}
    \item bla blabla blablabla
    \item bla blabla blablabla
\end{enumerate}
\end{f}

\bigskip
\begin{g} [Theorem] ~
\begin{enumerate}
    \item bla blabla blablabla
    \item bla blabla blablabla
\end{enumerate}
\end{g}
\end{document}

答案1

这是一个可能的解决方案。我正在使用thmtools' postheadhook键和enumitembefore*钥匙,以及\everypar,测试定理开头是否有列表环境并采取相应措施。这可能看起来有点复杂,但我认为没有一种简单可靠的方法可以做到这一点,而且我认为一旦你理解了它,它就没那么糟糕了。

\documentclass{article}

\usepackage{amsthm,thmtools}
\newif\ifthmstart
\declaretheoremstyle[headpunct=,postheadspace=0pt,bodyfont=\itshape]{dashordot}
\newcommand*\dashordot{~---~}
\newcommand*\dashordothook{%
  \thmstarttrue
  \everypar\expandafter{\the\everypar\textbf{\dashordot}\thmstartfalse}%
}

\usepackage{enumitem}
\AtBeginDocument{\setlist{before*={\ifthmstart\let\dashordot.\noindent\fi}}}

\declaretheorem[style=dashordot,postheadhook=\dashordothook]{theorem}

\begin{document}

\begin{theorem}
    \begin{enumerate}[label={\roman*)},font=\normalfont]
    \item This statement is true;
    \item and so is this one!
    \end{enumerate}
\end{theorem}

\begin{theorem}
    The following statements are equivalent:
    \begin{enumerate}[label={\roman*)},font=\normalfont]
    \item first statement;
    \item second statement.
    \end{enumerate}
\end{theorem}

\end{document}

输出


解释

无法将headpunct键与类似的东西一起使用\@ifnextchar,因为定理头实际上是在框内创建的。通常将这个框的插入延迟到第一个段落的开始,以确保环境开头的\everypar空格不产生任何作用。但是,如果定理以列表环境开头,则实际上只有在遇到该列表中的第一个时才会插入它。这很有用,因为这意味着我们可以将是否插入 a或 a的决定推迟到第一个段落的开始或这个列表环境的开始。\par\item.---

所以我正在做的事情如下:

  • 我将其定义\dashordot~---~,因此它会默认插入一个破折号。
  • 我正在清除postheadpunct并设置postheadspace0pt因为我们将手动插入这些。
  • 我正在使用键在定理环境开始时postheadhook将条件设置为真,并将和添加到。\ifthmstart\textbf{\dashordot}\thmstartfalse\everypar

    的内容\everypar通常插入在每个段落的开头,但在这种情况下只会插入一次,因为定理环境已经设置\everypar为之后会自行清除的内容。参见例如这个答案了解其\everypar工作原理。

  • 如果定理不是以列表开头,\textbf{\dashordot}则将插入到定理的开头,并且\ifthmstart也将设置回 false(这样定理中后面出现的列表环境不会受到影响)。
  • 如果定理确实以列表开头,则不会发生这种情况,因此\ifthmstart在这种情况下在该列表的开头仍然为真,并且定理头尚未插入(\item将会这样做)。
  • 我正在before*使用enumitem检查是否\ifthmstart为真。如果为真,它将重新定义\dashordot.并使用 开始一个段落\noindent

    这会影响所有enumitem知道的列表环境,我这样做是\AtBeginDocument因为它应该在声明所有列表环境之后应用,因为有些可能会使用键before,这会覆盖它(before*另一方面,只是添加一些内容before,所以这是安全的)。

  • 这会导致定理头和\textbf{\dashordot}被立即打印出来,并\ifthmstart重新设置为 false。因为我们现在已经开始了一个段落,这也会导致列表出现在定理环境的第一行下方。

相关内容