
TeXbook подробно описывает (в главе 14), как TeX вычисляет общие штрафы, связанные с разбиением абзаца на строки, и что TeX выбирает последовательность точек останова, которая дает наименьшее общее количество штрафов (в процессе с тремя проходами). Однако он лишь кратко описывает, что именно происходит, если не существует последовательности точек останова, удовлетворяющей требованиям:
Грубо говоря, \TeX\ разбивает абзацы на строки следующим образом: контрольные точки вставляются между словами или после дефисов, чтобы получить строки, badness которых не превышает текущий ^|\tolerance|. Если нет возможности вставить такие контрольные точки, устанавливается ^{overfull box}.
Никаких дополнительных подробностей о сценарии переполненного поля не приводится. Меня интересуют следующие подробности: можно ли простыми словами описать, какие слова TeX выбирает для выноса на поля в таком случае? (Или вам нужно прочитать исходный код TeX, чтобы понять это?) Поскольку TeX рассматривает абзац как единое целое, проблема отсутствия допустимой последовательности точек останова на самом деле не вызвана одним словом.
Более того, я думаю, что приведенное выше утверждение из TeXbook не совсем верно: когда абзац содержит \linebreak
, вместо этого он может быть установлен с недополненными строками. Этот сценарий в основном удовлетворяет предпосылке «нет способа вставить такие контрольные точки», однако TeX устанавливает недополненные строки вместо переполненных строк, как указано выше.
(Этот вопрос в основном из интереса. Но действительно существует сценарий, при котором абзац с переполненными строками может оказаться в готовом документе, а именно, если избыточный размер переполненных строк не превышает \hfuzz
.)
решение1
TeX выбирает разрывы строк на основе расчета штрафных очков, которые суммируются в сумму, называемуюобщие недостатки.
Первый проход, не применяющий возможности переноса TeX, может не соответствовать ограничениям, установленным целочисленным параметром \pretolerance
. Но второй проход TeX всегда успешен. Он может быть неуспешным в том смысле, что TeX должен создать переполненные строки. Недополненные строки создаются только в том случае, если пользователь этого хочет.
Что я имею в виду. Вы можете задать \parfillskip=0pt
и дать TeX короткую строку, скажем, всего с одним пробелом, и TeX сообщит и недополненную строку. Автор всегда несет ответственность за последний перенос строки; TeX ничего не вставляет в однострочный абзац. Аналогично, команда разрыва строки, которая выводит, \penalty-10000
заставляет TeX подчиняться желанию автора разорвать строку в этой точке. Это принудительный разрыв, который TeX вставляет.
Вот как работает TeX; я стараюсь использовать простые слова, но это техническая тема: TeX разрывает строки в местах склеивания (включая кернинг, за которым следует клей, и в конце встроенной математики, за которой следует клей) или в местах штрафа, т. е. дефиса в тексте, дефиса, вставленного TeX во втором проходе, после отношения в математическом режиме и т. д., а также, как \penalty-10000
описано выше.
Конечно, TeX считает начало текста начальной точкой останова. Чтобы создать абзац, TeX переходит от места, где возможен останов (во втором проходе это место может быть создано TeX с помощью вставленного дефиса), к следующему, пока ширина собранного материала, включая либо усадку, либо растяжимость, не позволит TeX построить строку с несовершенством, подчиняющимся текущему допуску вместе с одной из ранее найденных (или принудительных) точек останова. TeX отмечает такое место как точку останова и запоминает для него связанную с ним предыдущую точку останова, чтобы впоследствии можно было перейти от конца абзаца обратно к началу со строками, которые минимизируют общие недостатки.
TeX также создает точку останова, если видит, что пользователь вставил \penalty-10000
. Затем он начинает процесс, как если бы он был в начале абзаца. Ни одна последующая точка останова не может достичь этой точки останова, т. е. следующая точка останова должна записать эту принудительную точку останова пользователя как предыдущую точку останова.
Если не удается найти место для построения строки с неточностью не более текущего допуска, TeX останавливает обработку, если она находится на первом проходе, а затем начинает второй проход. В противном случае, если TeX находится на втором проходе, он ищет следующее место, где возможен разрыв без построения недозаполненной строки. Это становится точкой разрыва, хотя строка переполнена. Затем TeX продолжает процесс. Таким образом, второй проход проходит по всему абзацу. Обратите внимание, что абзац может иметь более одной переполненной строки.
Если \emergencystretch
не 0pt и второй проход не смог сделать то, что было запрошено, т. е. найти контрольные точки без переполненной строки или уменьшить количество строк, если \looseness=-1
, то TeX начинает третий проход, который работает как второй. Разница в том, что TeX добавляет размерность к \emergencystretch
растяжимости каждой строки. Таким образом, TeX принимает место в качестве контрольной точки, хотя ширина собранного материала и растяжимость в материале не могут заполнить строку с недостатком, меньшим или равным текущему допуску. Но ширина плюс растяжимость плюс размерность
\emergencystretch
достаточно велики, чтобы сделать это; визуально такая строка недополнена.
Есть несколько параметров, которые влияют на отчетность и маркировку. Как вы сказали, \hfuzz
размер может опустить правило переполнения, но это не меняет факта: есть строка переполнения. Другой параметр, называемый , \hbadness
отвечает, если выдается предупреждение.
Таким образом, я не понимаю, почему цитируемый текст TeXbook неверен, ведь это неформальное описание высокого уровня.