
В простом TeX и производных форматах концепция растягиваемой/сжимаемой длины, также известная какклейилипропускатьилидлина резинысуществует, в общем определяется как
<dimen> plus <stretch-dimen> minus <shrink-dimen>
где <dimen>
— базовый размер, а <stretch-dimen>
и <shrink-dimen>
— максимальные значения растяжения и сжатия соответственно. Длина пропуска будет регулироваться в этих пределах, чтобы соответствовать своему контейнеру.
Поскольку наименьшей единицей вычислений TeX является масштабированная точка, 1sp
я предполагаю, что все вычисления растяжения/сжатия квантуются на этом уровне.
Можно ли изменить "единицу квантования" для длин пропуска? Я думаю, что нет, потому что это глубоко внизу (внутри) примитива. Но я далек от TeXpert, и если бы это было возможно, я думаю, что это могло бы быть полезно для задач набора текста в стиле сетки.
Вот значительно упрощенный пример MWE, описывающий общую идею с помощью простого кода TeX:
\def\z{\hbox to 0pt{\hss\strut\vrule\hss}}
\def\zz{\z\hskip4pt}
\def\zzz{\zz\zz\zz\zz\zz}
x\z\hskip12pt plus 12pt minus 0pt %step 4pt
\z
x\z\hskip16pt plus 12pt minus 0pt %step 4pt
\z
x\hbox to 23pt{\z\hfill\hskip16pt plus 12pt minus 0pt %step 4pt
\z\hfill}
x\zzz\zzz\zzz\zzz
\bye
который производит:
В первых двух строках используется базовый размер, поэтому правила выравниваются по «сетке» (последняя строка). Однако в предпоследней строке используется компонент растяжения, который не кратен шагу сетки, поэтому правило не выравнивается.
Есть ли способ настроить «квантование» так, чтобы компонент растяжения привязывался к ближайшему кратному шагу сетки (здесь, 4pt
)?
решение1
Вычисление результатов «плюс и минус» выполняется в TeX с использованием машинно-зависимой реализации чисел, поэтому Кнут решил, что не будет возможности доступа к этим результатам макропрограммистом, чтобы исключить создание машинно-зависимых результатов в документе с помощью макроязыка.
Предлагаю макрос \roundto{dimen}
. Этот макрос пересчитывает ширину предыдущего поля в множитель "dimen". Использование в нашем примере будет:
x\hbox to 23pt{\z\hfill\hskip16pt plus 12pt minus 0pt \z\hfill}
x\hbox{\z\hskip16pt}\hbox to\dimexpr(23pt-16pt)/2{\hfil}\roundto{4pt}\z
x\zzz\zzz\zzz\zzz
Ваш пример (первая строка) включает фиксированный \hskip16pt
плюс 2*\hfill
в 23pt. Поэтому каждый \hfill
занимает (23pt-16pt)/2
место. находится \z
после первого \hfill
, поэтому второй блок в моем примере имеет этот размер. И макрос \roundto
округляет ширину этого блока до значения, кратного 4pt. печатается \z
после округления.
Макрос \roundbox
можно реализовать следующим образом:
\newcount\tmpnum
\def\roundto#1{\setbox0=\lastbox \tmpnum=\wd0 \dimen0=#1\relax
% \advance\tmpnum by\dimexpr \dimen0/2\relax
% uncomment this ^ ^, if you need "central" roundning
% \advance\tmpnum by\dimen0 \advance\tmpnum by-1
% uncomment this ^ ^, if you need "upper" roundning
\divide\tmpnum by\dimen0 \multiply\tmpnum by\dimen0
\wd0=\the\tmpnum sp
\box0
}
Значимое использование \roundto
макроса:
x\hbox{\z various text\quad}\roundto{4pt}\z next text is aligned.
x\zzz\zzz\zzz\zzz