Portál AbcLinuxu, 2. května 2025 06:12
Dnes si ukážeme základní vlastnosti boxů v TeXu. Práce s boxy je v závěru ilustrována příkladem, ve kterém programátor maker navrhuje design jedné složitější stránky knihy.
Připomínám, že \hbox
uchovává sazbu znaků nebo boxů zleva doprava na
společném účaří a \vbox
obsahuje boxy (explicitně zadané nebo jako
řádky po zlomu odstavce) uspořádané shora dolů na levou zarážku.
Napíšeme-li \hbox{text}
, bude mít výsledný box šířku textu. Na text
nebude kladeno žádné násilí, tj. pokud v něm jsou mezery, zůstávají
v základní velikosti bez roztahování nebo stlačování. Je ovšem také možno
napsat \hbox to<rozměr>{text}
, například \hbox to2cm{text}
.
V tomto případě bude mít box stanovenou šířku a na mezery v textu bude
kladeno rovnoměrné násilí, aby byla celková šířka boxu dodržena. Pokud
k tomu nemají mezery dostatečnou pružnost nebo mezery v textu úplně
chybějí, TeX vykřikne na terminál a do logu Overfull
nebo
Underfull \hbox
.
Mezeru včetně pružnosti je možno specifikovat pomocí
\hskip <základní velikost> plus<roztažení> minus<stlačení> například: \hskip 2cm plus3cm minus1cm
V uvedeném příkladu má mezera základní velikost 2 cm, je ochotna se
roztáhnout o 3 cm a stlačit o 1 cm, tedy může mít minimální
rozměr 1 cm. Maximální stlačení není nikdy překročeno, zatímco k většímu
roztažení může dojít, ale s velmi vysokým „badness“ a s křikem.
Jestliže parametry plus
anebo minus
chybějí, považují se za
nulové (mezera bez možnosti roztažení resp. stlačení).
V parametrech plus
nebo minus
je možné specifikovat
neomezenou roztažitelnost nebo stlačitelnost pomocí násobku fil
,
například
\hskip 0pt plus1fil
vytvoří mezeru nulového rozměru, ale s ochotou se libovolně roztáhnout.
Vyskytne-li se v textu taková mezera a je třeba text roztáhnout, všechny
mezery s omezenou roztažitelností splasknou na svou základní velikost
a „badness“ je nulové. Počet fil
udává poměr, v jakém se mezery
typu fil
budou roztahovat, je-li jich v textu více. Například mezera
2fil
bude dvojnásobně roztaženější než mezera 1fil
. Kromě toho
mohou existovat mezery s pružností v násobcích fill
nebo
filll
. Vyskytne-li se v textu mezera typu fill
, splasknou
na základní velikost nejen mezery omezené pružnosti, ale i mezery typu
fil
. Můžeme říci, že mezera typu fill
je „nekonečněkrát
pružnější“, než fil
. A podobně filll
je nekonečněkrát
pružnější než fill
.
Následující příklad ukazuje základní možnosti umístění textu. K přečtení
příkladu je třeba ještě vědět, že \hfil
je zkratka za
\hskip0pt plus1fil
a \hsize
je šířka sazby.
\hbox to\hsize{\hfil text\hfil} % umístění textu na střed \hbox to\hsize{text\hfil} % umístění textu doleva \hbox to\hsize{\hfil text} % umístění textu doprava \hbox to\hsize{\hfil text\hfil\hfil} % text v první třetině % tento poslední příklad je shodný s: \hbox to\hsize{\hfil text\hskip0pt plus2fil}
Uvedené příklady vytvoří box požadované šířky a umístí do něj text na
patřičné místo. Text nesmí být větší, než je \hsize
, jinak se dočkáme
hlášení Overfull \hbox
. Pokud bychom chtěli dovolit, aby texty větší
než \hsize
přečnívaly z boxu, stačí použít kromě libovolné
roztažitelnosti i libovolnou stlačitelnost, tedy
\hskip 0pt plus1fil minus1fil
Pro tuto mezeru má TeX zkratku \hss
. Takže
\hbox to\hsize{\hss text\hss} % umístění textu na střed
Tento příklad toleruje text jakékoli šířky. Na obou koncích bude široký text přečnívat přes okraj sazby stejně.
PlainTeX definuje pro tento způsob usazování textu makra \leftline
.
\rightline
a \centerline
takto:
\def\line{\hbox to\hsize} \def\leftline#1{\line{#1\hss}} \def\rightline#1{\line{\hss#1}} \def\centerline#1{\line{\hss#1\hss}}
Někdy se hodí umístit do sazby box nulové šířky, přitom sazba v něm
obsažená vyčnívá z boxu doleva nebo doprava. PlainTeX definuje makra
\llap{text}
(text vyčnívá doleva) a \rlap{text}
(text
vyčnívá doprava):
\def\rlap#1{\hbox to0pt{#1\hss}} \def\llap#1{\hbox to0pt{\hss#1}}
Analogicky jako \hbox
se specifikovanou šířkou je možné vytvořit
\vbox
se specifikovanou výškou. Místo \hskip
, \hfil
a \hss
se pak použijí mezery \vskip
, \vfil
a \vss
.
Po rozlomení odstavce do řádků TeX zpracuje obsah každého řádku pomocí
\hbox to\hsize{\hskip\leftskip obsah řádku\hskip\rightskip}
Protože obsahy registrů \leftskip
a \rightskip
jsou
implicitně nulové a k poslednímu východovému řádku je připojena mezera
z \parfillskip
(nastavena na 0pt plus1fil
), je odstavec
zarovnán do bloku. Ovšem například po nastavení \leftskip=0pt plus 1fill
vzniká sazba odstavce na pravou zarážku s nevyrovnaným levým okrajem. Všimněte
si úrovně pružnosti fill
, která způsobí, že splaskne i mezera
východového řádku, která má pružnost pouhé fil
.
PlainTeX definuje makro \raggedright
, které naopak zahájí
sestavování odstavců na levou zarážku. Dělá to poněkud chytřeji než jednoduchým
\rightskip=0pt plus 1fill
, aby bylo třepení na pravém okraji pokud možno co
nejmenší a došlo i na dělení slov.
Pro nastavení libovolného tvaru odstavce (s rozdílně širokými a rozdílně
usazenými řádky) slouží příkaz \parshape
. Pro pravoúhlý výřez
v odstavci stačí vhodně nastavit registry \hangindent
a \hangafter
.
Boxy je možné ukládat do číslovaných registrů, měřit jejich rozměry, nastavovat
jim rozměry jiné, rozebírat je, rozlamovat \vbox
y. K tomu příslušné
příkazy jsou uvedeny v následující tabulce, podrobnější popis je pak možné
dohledat například v TBN.
\setbox
| vložení boxu do číslovaného registru |
\ht , \dp , \wd | změření nebo nastavení výšky, hloubky, šířky boxu |
\box , \copy
| vložení boxu z registru do sazby |
\unhbox , \unvbox
| vložení obsahu boxu z registru do sazby |
\lastbox
| odebrání posledního boxu ze sazby |
\vsplit
| rozlomení sloupce ve \vbox u dle specifikované výšky |
\raise , \lower
| umístění boxu jinam než přesně na účaří |
\moveleft , \moveright
| umístění boxu jinam, než přesně na levou zarážku |
\vtop , \vcenter
| varianty \vbox u s jinak umístěným výsledným účařím |
Obvyklý postup při formátování řádků obsahu knihy by mohl vypadat třeba takto:
\hbox to\hsize{Název kapitoly \leaders\hbox to.8em{\hss.\hss}\hskip1em plus1fil\ číslo strany}
Je zde použit příkaz \leaders
, který funguje jako pružná mezera
vymezená pomocí \hskip
za ním, ovšem mezera není vyplněna bílým
místem, ale opakovaně kladenými boxy. V tomto příkladě se opakuje
\hbox to.8em{\hss.\hss}
, tedy box šířky 0,8 em (jednotka 1em je stupeň
použitého písma), ve kterém je uprostřed tečka.
Popíši ještě jiný příklad sazby obsahu, tentokrát méně obvyklý. Příklad se snaží co nejvěrněji napodobit stránku jisté knihy, na kterou mě v diskusi odkázal jeden čtenář s dotazem, jak by se taková věc dělala v TeXu. Uvědomuji si, že to je příklad asi ne příliš praktický, protože stránky takové knihy by zřejmě bylo přirozenější graficky navrhovat v interaktivním programu na obrazovce než zapisováním přesných rozměrů do zdrojového kódu. Příklad ale ilustruje obecnou práci s boxy, takže se nám hodí. Můžete si stáhnout zdrojový text příkladu, dále se můžete podívat na výstupní PDF, porovnat to s originální ukázkou a pokud to budete chtít vyzkoušet, budete potřebovat ještě jeden obrázek.
Ukázka využívá makro OPmac. Dále je natažen font Helvetica-narrow, který je přítomen v každé distribuci. Není sice zcela podobný fontu, který byl ve skutečné knize použit, ale pro účely testování nám to stačí. Pak je deklarována barva „skoro černá“, která tvoří podklad stránky s obsahem. Konečně je deklarován netypický formát knihy a nastaveny na něm nulové okraje, tj. sazba bude zahájena zcela vlevo a nahoře bez okrajů.
\input opmac \input chelvet \narrow % Zúžená varianta fontu Helvetica \def\DarkGrey{\setcmykcolor{0 0 0 .9}} % Skoro černý podklad \sdef{pgs:vu}{(160,188)mm} % Formát knihy, deklarace speciálního formátu vu \margins/1 vu (0,0,0,0)mm % Nulové okraje, použití formátu vu (viz opmac-u.pdf)
Stránka s obsahem je navržena takto:
\begingroup \nopagenumbers \localcolor % podkladová barva: \DarkGrey \hrule height\pdfpageheight width\pdfpagewidth \kern-\pdfpageheight % Fialovoučký obrázek: \hbox{\kern20mm \picwidth=26mm \picheight=185mm \inspic newsprint.pdf \vrule height\pdfpageheight width0pt} \kern-\pdfpageheight % Text obsahu: \kern35mm \moveright46mm\vbox{ \hbox{\kern7mm \typosize[20/]\White\bf CONTENTS} \vskip10mm \typosize[10/20]\rm \maketoc } \vfil\break % ukončení stránky \endgroup
Celá stránka je vytvořena uvnitř skupiny, kde je vypnutí tisku stránkové číslice
a nastavení barev lokální. Podkladová barva \DarkGrey
je vytištěna
jako \hrule
, což je obdélník nastavený na šířku a výšku papíru. Po
vytištění tohoto skoro černého obdélníka se vracíme zpět na začátek strany pomocí
záporného \kern
. V další vrstvě je vložen fialový obrázek 20 mm
od okraje stránky. Obrázek má šířku 26 mm a výšku 185 mm. Za obrázkem
následuje pomocí \vrule
neviditelná podpěra nulové šířky, ale výšky
stejné, jako je výška papíru. Ta podpěra způsobí, že výška celého \hboxu
bude stejná jako výška stránky, takže je logické, že se zpátky na začátek stránky
vrátíme již jednou použitým záporným kernem.
Dále se posuneme o 35 mm od horního okraje papíru dolů a text
umístíme ve \vbox
u, který je posunut o 46 mm doprava (46=20+26),
tj. začíná přesně na pravém okraji fialového obrázku. Tento \vbox
obsahuje nejprve \hbox
s nápisem CONTENTS ve velikosti 20pt. Nápis
je posunut o 7 mm doprava, takže začíná v ose pozdějších stránkových
číslic. Pod nápisem je mezera 10 mm a dále začíná sazba v písmu 10pt
s 20pt řádkováním. Text je vysázen pomocí makra z OPmac
\maketoc
, které vyzvedne informace o obsahu z pracovního
souboru, kam se ukládají při předchozím běhu TeXu.
Makro \maketoc
expanduje na jednotlivá makra pro řádky obsahu:
\tocline{úroveň}{info}{číslo}{nadpis}{strana}
. Aby se správně vysázelo, co
potřebujeme, je třeba makro \tocline
definovat:
\def\tocline #1#2#3#4#5{% \hbox{\llap{\vbox{\kern3mm \hsize=23mm \baselineskip=12pt \leftskip=0pt plus1fill \rightskip=3mm \noindent\DarkGrey \ifnum#3>0 Chapter #3\else #2\fi}}% \White\hbox to14mm{\hss#5\hss}\uppercase{#4}}}
Jeden řádek obsahu je \hbox
. Doleva pomocí \llap
nad
fialový obrázek přečnívá \vbox
, který obsahuje odstavec se slovem Chapter
nebo jinými texty. Pouze v případě „Contributor Biographies“ je tento odstavec
rozlomen do dvou řádků. Nad odstavcem je vertikální mezera 3 mm, dále je pro
odstavec nastaveno \hsize=23mm
(zhruba jako šířka fialového obrázku)
a \baselineskip
udává řádkování. Pomocí \leftskip
je
zařízeno, že odstavec bude na pravou zarážku a pomocí \rightskip
je
vložena vhodná mezera od pravého okraje fialového obrázku. Veškeré toto nastavení
je lokální uvnitř \vbox
u. Pomocí \noindent
je odstavec
zahájen. Číslovaná kapitola má své číslo kladné a v takovém
případě přidáme slovo Chapter. Nečíslovaná kapitola má #3=0
a pak
vytiskneme parametr #2
, který v tuto chvíli
obsahuje text „Introduction“, „Contributor Biographies“ atd.
Následně je od hrany fialového obrázku směrem doprava vložen \hbox
šířky 14 mm a na jeho střed je umístěna stránková číslice. Konečně je
velkými písmeny (\uppercase
) vysázen nadpis kapitoly.
Zdrojový text ukázky obsahuje ještě definici nečíslovaných kapitol a práci s externím souborem s údaji pro obsah. To ovšem není obsahem tohoto dílu seriálu, kde jsme se seznámili především s boxy.
\documentclass{article} \newcommand{\x}{\x} \begin{document} \x \end{document}
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.