我正在写一份需要编号段落的规范文档。我是这样实现的:
\reversemarginpar
\newcommand\countparagraphs{
\everypar{%
\addtocounter{paragraph}{1}%
\marginpar{\hfill\ttfamily\bfseries\arabic{paragraph} \textsection}%
}
}
\makeatletter
\@addtoreset{paragraph}{section}
\makeatother
\newcommand\CountedSection[1]{\section{#1}\countparagraphs}
\setlength{\parindent}{0pt}
\setlength{\parskip}{0.7\baselineskip}
但是,这会导致奇怪的分页符。具体来说,页面在页面结束前会分出几个段落。
我确定这是由于使用而导致的,\marginpar{...}
并将其替换为
\hspace{-4em}\makebox[3em][r]{...}\hspace{1em}
从而解决了问题。
不过我想知道这里到底发生了什么。为什么会\marginpar
影响分页?
以下是 MWE:
\documentclass[a4paper]{article}
\usepackage[margin=3cm]{geometry}
\newcommand\countparagraphs{\everypar{\marginpar{!}}}
\newcommand\CountedSection[1]{\section{#1}\countparagraphs}
\title{MWE}
\begin{document}
\maketitle
\tableofcontents
\setlength{\parindent}{0pt}
\setlength{\parskip}{0.7\baselineskip}
\CountedSection{Lipsum 1}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Praesent mollis ornare ullamcorper.
Nunc fringilla luctus justo auctor consequat.
Sed fringilla metus facilisis diam ultrices eleifend.
Sed eget leo nec neque lobortis hendrerit.
In fringilla dui vitae lectus vehicula a vehicula dui bibendum.
Nunc condimentum, nunc nec feugiat ornare, augue dolor lobortis arcu, id posuere neque orci at enim.
Sed vehicula, nibh a tristique imperdiet, ante erat vulputate nulla, in accumsan odio felis at odio.
Fusce orci lorem, sollicitudin sed imperdiet vitae, fermentum ut urna.
Etiam nec iaculis diam. Duis ante elit, imperdiet id ornare sit amet, porta porttitor nunc.
Nullam magna sem, imperdiet eget fermentum et, accumsan ut enim.
\CountedSection{Lipsum 2}
Vivamus consequat volutpat quam, eu sollicitudin ligula varius vitae.
Maecenas tortor mi, molestie at faucibus vitae, dapibus eget nibh. In hac habitasse platea dictumst.
Nulla molestie ipsum ac sapien interdum eu faucibus eros viverra.
Nulla eu odio nunc. Ut ut libero ut eros adipiscing luctus.
Nunc non nulla odio. Curabitur ac facilisis orci.
Curabitur vitae dui metus, et blandit magna. Donec sollicitudin sodales orci non mollis.
\CountedSection{Lipsum 3}
Morbi lacinia scelerisque odio, sollicitudin tempus erat mattis ut.
In elementum auctor rhoncus. In sit amet lorem a ligula rhoncus accumsan quis non magna.
Vivamus sit amet erat at magna ultricies vulputate. Nunc tortor neque, blandit eu elementum malesuada, iaculis a eros.
Fusce vulputate, elit et iaculis fringilla, orci dui congue justo, at cursus elit velit vitae felis. Duis lacinia aliquam quam, sed vulputate risus porttitor vitae.
Sed dictum lectus eget quam pharetra hendrerit pharetra nibh ultricies. Donec vitae diam purus, a consequat ligula. Donec imperdiet vulputate consequat.
Nunc eleifend dapibus eleifend.
Donec lobortis enim ac quam sagittis fermentum.
Cras vestibulum accumsan nisl, et molestie justo blandit eu. Nunc pretium, tellus sed rutrum euismod, erat quam lacinia est, in convallis nisi ipsum nec dolor. Cras non urna enim.
\CountedSection{Lipsum 4}
Quisque ornare, felis eu tincidunt lacinia, sapien turpis molestie nulla, sed vestibulum massa arcu nec metus.
Phasellus placerat interdum congue.
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla ac nibh nec diam rutrum placerat.
Vivamus in imperdiet nisi.
Donec nibh est, vehicula et molestie eu, lobortis in ante. Nullam aliquam orci et justo rhoncus porta.
Aliquam ac sodales purus.
\end{document}
答案1
简短的回答是,这\everypar
绝对不是一个用于定义的用户命令,除非你遵守 LaTeX 对它的限制(并且你完全理解它在内核中的使用方式,这一点并没有非常突出的记录,但它是不是用户命令)。因此,这有点像“不支持的输入 -> 任意结果”。如果你看看
\section{foo} \showthe\everypar
然后你会看到\everypar
此时有以下定义:
> \if@nobreak \@nobreakfalse \clubpenalty \@M \if@afterindent \else {\setbox \z
@ \lastbox }\fi \else \clubpenalty \@clubpenalty \everypar {}\fi .
l.4 \section{foo} \showthe\everypar
这意味着您对 的重新定义\everypar
会破坏其后段落的所有部分处理。特别是,该部分将开关“@nobreak”设置为 true,现在它没有被重置,这会带来大量意想不到的副作用,包括一些处理\marginpar
...
因此,当然可以更详细地分析这一点,但是... :-)