我是一名软件包作者,正在为公司编写软件包。我试图提供类似于定理的环境,amsthm
以便于使用。
我需要找到一种方法来实现以下行为:
- 如果内容紧接着下一
\begin{environment}
行或从下一行开始,则应将其立即放置在环境标签之后,除非它跨越整个线宽,例如enumerate
或align
。 - 如果在环境开始处留有一个或多个空行,则内容需要从环境标签下方开始,并且第一行内容不能缩进(如标题后)。
- 在新段落的环境中缩进仍然必须是可能的。
我研究了 MWE 中指出的以下想法,但没有一个能取得预期的结果。
\documentclass[a4paper,landscape]{article}
\usepackage{amsthm}
\usepackage{thmtools}
\usepackage{enumitem}
\usepackage[a4paper,margin=1cm,landscape]{geometry}
\makeatletter
\declaretheorem[
postheadhook={
},
]{theoremA}
\declaretheorem[
postheadhook={
\mbox{}
},
]{theoremB}
\declaretheorem[
postheadhook={
\mbox{}
\@afterindentfalse
\@afterheading
},
]{theoremC}
\declaretheorem[%
postheadhook = {%
\leavevmode
\everypar{\setbox\z@\lastbox\everypar{}}
},
]{theoremD}
\declaretheorem[%
postheadhook = {%
\setbox\z@\lastbox
},
]{theoremE}
\makeatother
\begin{document}
\begin{minipage}[t]{0.3\linewidth}
\setlength{\parindent}{1cm}
\section{Type A}
\begin{theoremA}
This line is exactly where it ought to be.
This other line is indented, as it constitutes a new paragraph inside the theorem. This is fine.
\end{theoremA}
\begin{theoremA}
This line is starting right after the label, which it should \textbf{not} do.
This other line is indented, as it constitutes a new paragraph inside the theorem.
\end{theoremA}
\begin{theoremA}
\begin{enumerate}
\item line A
\item line B
\end{enumerate}
The enumeration should start on its own line, and \textbf{not} after the label.
\end{theoremA}
\end{minipage}
\hfill
\begin{minipage}[t]{0.3\linewidth}
\setlength{\parindent}{1cm}
\section{Type B}
\begin{theoremB}
This line is correctly broken to a new line and staring right after the theorem label as intended.
This other line is indented, as it constitutes a new paragraph inside the theorem. This is as intended.
\end{theoremB}
\begin{theoremB}
This line is correctly starting on a new line, however, I do \textbf{not} want it to be indented (just for the first line).
This other line is indented, as it constitutes a new paragraph inside the theorem.
\end{theoremB}
\begin{theoremB}
\begin{enumerate}
\item line A
\item line B
\end{enumerate}
The enumeration now starts on its own line as intended. Notice the topsep is being kept as intended.
\end{theoremB}
\end{minipage}
\hfill
\begin{minipage}[t]{0.3\linewidth}
\setlength{\parindent}{1cm}
% \everypar{ASDF}
\section{Type C}
\begin{theoremC}
This line is starting right after the label as intended.
This other line is \textbf{not} indented, and this is \textbf{not} the behaviour I expect.
However, if I add another line, this one gets indented as expected.
\end{theoremC}
%
\begin{theoremC}
This line is correctly moved to a new line.
This other line is indented, as it constitutes a new paragraph inside the theorem.
\end{theoremC}
%
\begin{theoremC}
\begin{enumerate}
\item line A
\item line B
\end{enumerate}
The enumeration now starts on its own line. Good. However, the topsep is ignored, which is \textbf{not} what I want.
\end{theoremC}
\end{minipage}
\pagebreak
\begin{minipage}[t]{0.3\linewidth}
\setlength{\parindent}{1cm}
\section{Type D}
\begin{theoremD}
This line is starting right after the label as intended.
This other line is \textbf{not} indented, and this is \textbf{not} the behaviour I expect.
However, if I add another line, this one gets indented as expected.
\end{theoremD}
%
\begin{theoremD}
This line is correctly moved to a new line and correctly indented.
This other line is indented, as it constitutes a new paragraph inside the theorem.
\end{theoremD}
%
\begin{theoremD}
\begin{enumerate}
\item line A
\item line B
\end{enumerate}
The enumeration now starts on its own line. Good. However, the topsep is ignored, which is \textbf{not} what I want.
\end{theoremD}
\textbf{In short, this behaves exactly like Type~C.}
\end{minipage}
\hfill
\begin{minipage}[t]{0.3\linewidth}
\setlength{\parindent}{1cm}
\section{Type E}
\begin{theoremE}
This line is exactly where it ought to be.
This other line is indented, as it constitutes a new paragraph inside the theorem. This is fine.
\end{theoremE}
\begin{theoremE}
This line is starting right after the label, which it should \textbf{not} do.
This other line is indented, as it constitutes a new paragraph inside the theorem.
\end{theoremE}
\begin{theoremE}
\begin{enumerate}
\item line A
\item line B
\end{enumerate}
The enumeration should start on its own line, and \textbf{not} after the label.
\end{theoremE}
\textbf{In short, this behaves exactly like Type~A.}
\end{minipage}
\hfill
\begin{minipage}[t]{0.3\linewidth}
\setlength{\parindent}{1cm}
\section{Future tests}
\end{minipage}
\end{document}
请原谅冗长的 MWE,但我向你保证,这是显示比较的最少结构。
我的示例编译如下:
请参阅内联注释,了解 MWE 与期望/预期行为的具体偏差。
我很高兴被指向另一个方向,只是记住我不能只用于文档作者,或者要求他们在文档中\noindent
输入空白。\mbox{}
补充1:
我按照给出的答案和评论中的建议测试了两个新案例(类型 D 和类型 E)。但是,它们没有提供令人满意的答案。请参阅所附的屏幕截图:
附加代码已直接添加到 MWE。
答案1
摘自 source2e.pdf 的 ltpara.dtx 章节:
因此,TEX 提供了在段落开头(或多或少)放入一些特殊代码
\everypar
以获得控制权的可能性。例如,在 LaTeX 和许多软件包中,有时会使用如下特殊代码:
\everypar{{\setbox\z@\lastbox}\everypar{} ...}
这将再次删除段落缩进框(该框已由 TEX 放置),然后重置\everypar
,使其在下一个段落开始时不执行任何操作,然后执行其想要执行的任何操作,例如,在\item
列表中,它将在段落文本前面排版标签。但是,只有一个这样的\everypar
标记寄存器,如果不同的软件包和/或内核都尝试在此处添加自己的代码,则协调将非常困难,甚至不可能。
\@afterheading
包含此代码,尽管它首先检查\if@afterindent
。但您真正需要的只是位\everypar
。最大的问题是 Theorem 是否已经在使用\everypar
。
定理似乎测试标签并吸收任何\par
s。 \null
不足以满足测试,但是\strut
。
\documentclass[a4paper,landscape]{article}
\usepackage{amsthm}
\usepackage{thmtools}
\usepackage{enumitem}
\usepackage[a4paper,margin=1cm,landscape]{geometry}
\declaretheorem{theoremA}
\begin{document}
\begin{minipage}[t]{0.3\linewidth}
\setlength{\parindent}{1cm}
\section{Type A}
\begin{theoremA}
This line is exactly where it ought to be.
This other line is indented, as it constitutes a new paragraph inside the theorem. This is fine.
\end{theoremA}
\begin{theoremA}\strut\newline
This line is no longer starting right after the label, as desired.
This other line is indented, as it constitutes a new paragraph inside the theorem.
\end{theoremA}
\begin{theoremA}\strut%\vspace{\dimexpr \itemsep-\baselineskip}
\begin{enumerate}
\item line A
\item line B
\end{enumerate}
The enumeration should start on its own line, and \textbf{not} after the label.
\end{theoremA}
\end{minipage}
\end{document}