当章节标题后面跟着普通文本时,如何有条件地在章节标题后添加句点

当章节标题后面跟着普通文本时,如何有条件地在章节标题后添加句点

作为后续行动在小节标题后添加句号/点,我需要找到一种方法,当标题后面直接跟着普通文本时,有条件地在小节标题后面添加一个句号/点。如果后面跟着另一个标题或浮动文本,则不应有句号。在下面的示例中,第 1.1 节的标题不应以句号/点结尾,因为它后面紧跟着一个小节,而不是普通文本。

背景:这是我正在研究的 ANSI 标准的严格样式规范。

有人能帮忙吗?

\documentclass{scrartcl}

% Body Section Definitions
\RedeclareSectionCommand[
  font=\sffamily\large,
  runin=false,
  beforeskip=10pt,
  afterskip=4pt,
  afterindent=false
]{section}
\RedeclareSectionCommand[
  font=\normalsize\normalfont\bfseries,
  runin=true,
  beforeskip=10pt
]{subsection}
\RedeclareSectionCommand[
  font=\normalsize\normalfont\bfseries,
  runin=true,
  beforeskip=10pt
]{subsubsection}

\renewcommand{\sectioncatchphraseformat}[4]{\hskip #2#3#4.}

\begin{document}

\section{Level 1 headings never end in a period}

\subsection{Level 2 headings should only end in a period if they are immediately followed by normal text}

\subsubsection{Level 3 is the same as level 2}

This section begins with normal text content, and its heading should end in a period. But the previous section should not end in a period because it is followed by another heading.

\end{document}

在此处输入图片描述

答案1

如果一个标题后面跟着另一个标题,则很难进行检测。但是,使用一些启发式方法,您可以检测到一个标题前面是否有另一个标题。在下面的例子中,我使用标题末尾的跳过来检测下一个级别的标题。为此,我使用做钩子用户手册第二部分中对 KOMA-Script 的解释:

\documentclass{scrartcl}

% Body Section Definitions
\RedeclareSectionCommand[
  font=\sffamily\large,
  runin=false,
  beforeskip=10pt,
  afterskip=4pt,
  afterindent=false
]{section}
\RedeclareSectionCommand[
  font=\normalsize\normalfont\bfseries,
  runin=true,
  beforeskip=10pt
]{subsection}
\RedeclareSectionCommand[
  font=\normalsize\normalfont\bfseries,
  runin=true,
  beforeskip=10pt
]{subsubsection}

\makeatletter
\newcommand*{\storesubsectiondot}[1]{%
  \ifdim\lastskip=4pt \else
    \immediate\write\@mainaux{\string\global\string\@namedef{subsection\thesubsection dot}{.}}%
  \fi
}
\AddtoDoHook{heading/preinit/subsubsection}{%
  \storesubsectiondot
}
\newcommand*{\addsubsectiondot}{%
  \@nameuse{subsection\thesubsection dot}%
}
\AtEndDocument{\storesubsectiondot{}}
\makeatother
\renewcommand{\sectioncatchphraseformat}[4]{\hskip #2#3#4\Ifstr{#1}{subsection}{\addsubsectiondot}{.}}

\begin{document}

\section{Level 1 headings never end in a period}

\subsection{Level 2 headings should only end in a period if they are
  immediately followed by normal text}

Here we have normal text.

\subsubsection{Level 3 is the same as level 2}

This section begins with normal text content, and its heading should end in a
period. The previous section should also end in a period because it is
followed by normal text.

\section{Level 1 headings never end in a period}

\subsection{Level 2 headings should only end in a period if they are
  immediately followed by normal text}

\subsubsection{Level 3 is the same as level 2}

This section begins with normal text content, and its heading should end in a period. But the previous section should not end in a period because it is followed by another heading.

\section{Level 1 headings never end in a period}

\subsection{Level 2 headings should only end in a period if they are
  immediately followed by normal text}

This section begins with normal text content and therefore should have a dot.
\end{document}

\AtEndDocument用于检测最后一个标题后面是否跟着文本。也许这可以做得不那么具有启发性,因为最后一个标题后面应该总是跟着文本。如果需要,您还应该能够对较低级别执行类似操作。

但如你所见,这确实很复杂。因此,更手动的建议是:

\documentclass{scrartcl}

% Body Section Definitions
\RedeclareSectionCommand[
  font=\sffamily\large,
  runin=false,
  beforeskip=10pt,
  afterskip=4pt,
  afterindent=false
]{section}
\RedeclareSectionCommand[
  font=\normalsize\normalfont\bfseries,
  runin=true,
  beforeskip=10pt
]{subsection}
\RedeclareSectionCommand[
  font=\normalsize\normalfont\bfseries,
  runin=true,
  beforeskip=10pt
]{subsubsection}

\DeclareRobustCommand{\sentencedot}{.}
\BeforeStartingTOC[toc]{\RenewCommandCopy\sentencedot\relax}

\begin{document}

\tableofcontents
\section{Level 1 headings never end in a period}

\subsection{Level 2 headings should only end in a period if they are
  immediately followed by normal text\sentencedot}

Here we have normal text.

\subsubsection{Level 3 is the same as level 2\sentencedot}

This section begins with normal text content, and its heading should end in a
period. The previous section should also end in a period because it is
followed by normal text.

\section{Level 1 headings never end in a period}

\subsection{Level 2 headings should only end in a period if they are
  immediately followed by normal text}

\subsubsection{Level 3 is the same as level 2\sentencedot}

This section begins with normal text content, and its heading should end in a period. But the previous section should not end in a period because it is followed by another heading.

\section{Level 1 headings never end in a period}

\subsection{Level 2 headings should only end in a period if they are
  immediately followed by normal text\sentencedot}

This section begins with normal text content and therefore should have a dot.
\end{document}

答案2

由于没有一种干净的方法可以直接在 LaTeX 中执行此操作,所以我最终编写了一个排箫通过过滤器自动执行此操作潘多克

import panflute as pf

HEADING_NAMES = [
  "chapter",
  "section",
  "subsection",
  "subsubsection",
  "paragraph",
  "subparagraph"]

def action(elem, doc):
  if isinstance(elem, pf.Header):
    if isinstance(elem.next, pf.Para):
      if elem.level > 1:
        before = inlatex(f"\\hypertarget{{{elem.identifier}}}{{%\n\\{HEADING_NAMES[elem.level]}[")
        middle = inlatex(r"]{")
        after = inlatex(fr".}}\label{{{elem.identifier}}}}}")
        return [pf.Plain(before, *elem.content, middle, *elem.content, after)]

def main(doc=None):
  return pf.run_filter(action, doc=doc)

if __name__ == "__main__":
  main()

注意:此过滤器可以简化一次此功能已实施。

相关内容