自动段落编号按 itemize 拆分

自动段落编号按 itemize 拆分

我正在开发一个 LaTeX 解决方案,需要处理其他人用 Markdown 编写的纯文本。我需要自动从纯文本中对段落进行编号(即文本中不会出现诸如\paragraph或 之类的 LaTeX 代码)。\item

为了推动这一进程,我之前曾询问过这个问题并得到了一些指点,帮助我在处理过的文档中通过修改引入自动编号的段落\@afterheading(再次感谢@NicolaTabot)。

不幸的是,我发现一个问题,即项目符号列表似乎破坏了解决方案。

我的最小工作示例如下:

\documentclass[11pt]{article}
\usepackage{titlesec}
\setcounter{secnumdepth}{3}

\setlength{\parindent}{0em} % indent subsequent paragraphs

\newcounter{para}
\newcommand*{\numberedparagraph}{%
\refstepcounter{para}
\textbf{\thepara.\space}
}

\let\oldep\everypar\newtoks\everypar  
\oldep{\the\everypar\everypar{\numberedparagraph}}

\makeatletter %
\renewcommand{\@afterheading}{%
  \@nobreaktrue
\everypar{%
\if@nobreak
  \@nobreakfalse
  \clubpenalty\@M
  \if@afterindent
  \else
{\setbox\z@\lastbox}%
  \fi
\else
  \clubpenalty\@clubpenalty
  \everypar{\numberedparagraph}% <- modification
\fi
\numberedparagraph% <- modification
  }%
}

\begin{document}

\everypar{\numberedparagraph}

\section{Section 1}

This is paragraph 1.

This is paragraph 2, and here are some bullets:

\begin{itemize}
    \item One.
    \item Two.
    \item Three.
\end{itemize}

And then this paragraph should be numbered 3 but it is not.

Numbering returns for this paragraph, but now the count is incorrect.

\end{document}

以下是结果文档的屏幕截图:

enter image description here

有人能帮我吗?

答案1

以下是两种可能的解决方案。我首先编写了下面的解决方案,它是原始代码的简单扩展,它执行的操作与\itemize您已经为 执行的操作相同\section。我认为上面的解决方案可能更耐用,因为它似乎不太可能出现故障(并且更容易适应),但事情可能是出于我不知道的其他原因而设置的。


新解决方案:

这是一个我更喜欢的新解决方案:

\documentclass[11pt]{article}

\usepackage{titlesec}
\setcounter{secnumdepth}{3}

\usepackage{etoolbox} %% for \apptocmd and \pretocmd

\setlength{\parindent}{0pt} % do not indent subsequent paragraphs

\newcounter{para}
\newcommand*{\numberedparagraph}{%
  \refstepcounter{para}%
  \makebox[0pt][r]{\textbf{\thepara.~}}% %% This puts the number in the margin
  %\makebox[0pt][r]{\makebox[0pt][l]{\textbf{\thepara.}}\hspace{2em}}% %% This also left-aligns multi-digit numbers
  %\textbf{\thepara.~}% %% And this indents the paragraph instead
}

\let\oldep\everypar
\newtoks\everypar
\oldep{\the\everypar\ifinhibitparnums\numberedparagraph\fi}

\newif\ifinhibitparnums
\inhibitparnumstrue

%% Inhibiting paragraph numbers in section/subsection/... titles
\makeatletter
% \pretocmd{\@sect}{\inhibitparnumsfalse}{}{}         %% <- this only works without titlesec
% \apptocmd{\@sect}{\inhibitparnumstrue}{}{}          %% <- this only works without titlesec
\pretocmd{\ttl@straight@ii}{\inhibitparnumsfalse}{}{} %% <- this only works with titlesec
\apptocmd{\ttl@straight@ii}{\inhibitparnumstrue}{}{}  %% <- this only works with titlesec
\makeatother

%% Inhibiting it in itemize
\pretocmd{\itemize}{\inhibitparnumsfalse}{}{}
%% N.B. \ifinhibitparnums is reset automatically when the environment ends

\begin{document}

\section{Section 1}

This is paragraph 1.

This is paragraph 2, and here are some bullets:

\begin{itemize}
    \item One.
    \item Two.
    \item Three.
\end{itemize}

And then this paragraph should be numbered 3, and it is! Also it is long enough to span two lines!

Numbering returns for this paragraph, and the count is still correct.

\end{document}

我定义了一个条件,\ifinhibitparnums并且仅当它设置为时才对段落进行编号false。我通过重新定义来防止对章节标题进行编号\ttl@straight@ii,这会为 生成章节标题titlesec,因此它首先将此条件设置为true,然后执行其操作并最终将其设置\ifinhibitparnumsfalse。(更准确地说,我使用\pretocmd添加\inhibitparnumstrue到此宏的前面并\apptocmd附加\inhibitparnumsfalse。这些来自etoolbox包。)

例如,您还可以尝试使用 来修补表格环境\pretocmd{\tabular}{\inhibitparnumstrue}{}{}。这也可以在星号环境中工作,如中所述这个答案

要暂时禁止段落编号,您也可以手动输入\inhibitparnumstrue,要恢复编号,请输入\inhibitparnumsfalse

输出如下:

enter image description here


原解决方案:

\everypar环境结束后,的值会暂时改变,就像 之后一样。这是由 调用的\section内部宏 完成的。\@doendpe\end

因此,一个可能的解决方案就是\@doendpe按照您已经修改的方式重新定义\@afterheading

\documentclass[11pt]{article}
\usepackage{titlesec}
\setcounter{secnumdepth}{3}

\setlength{\parindent}{0pt} % indent subsequent paragraphs

\newcounter{para}
\newcommand*{\numberedparagraph}{%
  \refstepcounter{para}%
  \makebox[0pt][r]{\textbf{\thepara.~}}% %% This puts the number in the margin
  %\makebox[0pt][r]{\makebox[0pt][l]{\textbf{\thepara.}}\hspace{2em}}% %% This also left-aligns multi-digit numbers
  %\textbf{\thepara.~}% %% And this indents the paragraph instead
}

\let\oldep\everypar\newtoks\everypar  
\oldep{\the\everypar\everypar{\numberedparagraph}}

\makeatletter

\renewcommand{\@afterheading}{%
  \@nobreaktrue
\everypar{%
\if@nobreak
  \@nobreakfalse
  \clubpenalty\@M
  \if@afterindent
  \else
{\setbox\z@\lastbox}%
  \fi
\else
  \clubpenalty\@clubpenalty
  \everypar{\numberedparagraph}% <- modification
\fi
\numberedparagraph% <- modification
  }%
}

\def\@doendpe{\@endpetrue
  \def\par{%
    \@restorepar\everypar{\numberedparagraph}% <- modification
    \par\@endpefalse
  }%
  \everypar{%
    {\setbox\z@\lastbox}\everypar{\numberedparagraph}% <- modification
    \numberedparagraph % <- modification
    \@endpefalse
  }%
}

\makeatother % <- you forgot this, it is good form to restore the catcode of @

\AtBeginDocument{\everypar{\numberedparagraph}}

\begin{document}

\section{Section 1}

This is paragraph 1.

This is paragraph 2, and here are some bullets:

\begin{itemize}
    \item One.
    \item Two.
    \item Three.
\end{itemize}

And then this paragraph should be numbered 3 but it is not.

Numbering returns for this paragraph, but now the count is incorrect.

\end{document}

感觉应该有一个更好的解决方案(编辑:见上文) 。 (无论 LaTeX 对 进行什么操作,它都不会中断\everypar。)

相关内容