
\kap Tvorba tabulek
%%%%%%%%%%%%%%%%%%%

\sub Opakovac� v�pl�ky typu \tt\char`\\leaders           [leaders]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Slovo |\leaders| bychom mohli p�elo�it jako \uv{veden�}, s~v�znamem v�st o�i
v~obsahu knihy od n�zvu kapitoly k~��slu strany.\inl[leaders]\inl[tabulky]
Typografov� k~tomu obvykle pou��vaj� te�ky, ale |\leaders| um� stanoven�
prostor opakovan� vypl�ovat ��mkoli.

|\leaders| se chov� jako |\hskip| v~horizont�ln�m seznamu nebo |\vskip|
ve vertik�ln�m seznamu. Vytvo�� tedy pru�n� v�pln�k. Na rozd�l od
netisknouc�ch pru�n�ch v�pl�k� vytvo�en�ch pomoc� |\hskip| a |\vskip|,
primitiv |\leaders| do m�sta v�pl�ku obvykle n�co tiskne. Povel |\leaders|
m� tyto parametry:

\beguk
\leaders <box or rule> <glue specification>
\enduk

kde <box or rule> je konstrukce boxu podle pravidla <box> nebo
linka |\hrule| nebo |\vrule| s~<rule specification>
(viz syntaktick� pravidla v~��sti~B). Je mo�n� pou��t oba primitivy
pro linky bez z�vislosti na tom, zda se vytv��� horizont�ln� nebo
vertik�ln� seznam. Parametr <box or rule> ur�uje, co se bude (t�eba
opakovan�) ve v�pl�ku s�zet. D�le <glue specification> ud�v� charakter
v�pl�ku <glue>. Ve vertik�ln�m m�du m��eme pou��t t�eba |\vskip|,
|\vss| a v~horizont�ln�m m�du |\hskip|, |\hfil| a dal��. Tato specifikace
ur�uje chov�n� |\leaders|, pokud se na n�j d�v�me jako na pru�n� v�pln�k.

\beguk Uk�zka pou�it� \leaders
\leaders \hbox{abc}\hfil % chov� se jako \hfil a s�z� abcabc...
\leaders \hrule\hskip5cm % linka 0.4pt vysok� a 5cm �irok�
\leaders \vrule\hskip5cm % v��ka, hloubka podle vn�j��ho boxu
\leaders \vrule\hfil     % nyn� pru�� v�echny t�i rozm�ry
\leaders \vrule height3pt depth0pt \hskip10pt  % tot� jako:
  \vrule height3pt depth0pt width10pt
\leaders \hbox{abc}\vfil % jen ve vert. m�du, pod sebou boxy abc
\enduk

Vylo��me nejprve �innost primitivu |\leaders|, je-li <box or rule>
skute�n� linkou, tj.~je-li pou�it primitiv |\hrule| nebo |\vrule|.
V~horizont�ln�m m�du se ignoruje ���ka linky
a m�sto n� se
pou�ije ���ka podle v�sledn�ho rozm�ru pru�n�ho v�pl�ku. Uva�ujme
nap��klad:

\beguk
\hbox to1cm {\leaders \hrule \hfil}     !lnl[prvnilead]
\hbox to1cm {\leaders \vrule height0.4pt \hfil}
\hbox to1cm {\vbox to0.4pt{}\leaders \vrule \hfil}
\enduk

Ve v�ech t�ech p��padech dost�v�me stejn� v�sledek. Box s~nulovou hloubkou
vysok� 0,4\,pt a �irok� 1\,cm. Cel� box je �ern�, tak�e vid�me
vodorovnou linku d�lky 1\,cm a tlou��ky 0,4\,pt.
V~prvn�m p��pad� (na ��dku~\lnr[prvnilead]) plyne v��ka boxu z~implicitn�
v��ky |\hrule|, ve druh�m p��pad� jsme ji napsali explicitn� a ve t�et�m
vyplynula v��ka |\vrule| z~nejvy���ho elementu v~boxu, kter�m je pr�zdn�
|\vbox|.

Ve vertik�ln�m m�du se ignoruje v��ka a hloubka linky. Hloubka bude nulov�
a v��ka bude rovna v��ce pru�n�ho v�pl�ku, kter� |\leaders|
vypl�uje. Nap��klad:

\beguk
\vbox to1mm{\leaders \hrule height10cm depth10cm width10cm\vfil}
\enduk

vytvo�� box s~v��kou 1\,mm, hloubkou 0\,mm a ���kou 10\,cm. Cel� je
vypln�n �ernou barvou. Poznamenejme, �e i jin� barvy jsou mo�n�,
je-li pou�it vhodn� |\special| pro konkr�tn� tiskov� za��zen� (nap��klad
PostScriptov� za��zen�).

Je-li v�sledn� rozm�r pru�n�ho v�pl�ku z~|\leaders| z�porn�, nekresl� se
nic. \endpar

Nap��klad v~z�hlav� t�to kn��ky je pou�ito:

\beguk
\leaders\hrule height3pt depth-2.6pt \hfil
\enduk

co� vypl�uje prostor vedle textu z�hlav� �arou. Celkov� tlou��ka t�to ��ry
je tedy \hbox{$3\,{\rm pt}-2{,}6\,{\rm pt} = 0{,}4\,{\rm pt}$} a je na
��dku ve v��ce 2,6\,pt od ��a��. \endpar

Uva�ujme nyn� p��pad, kdy <box or rule> je skute�n� <box>.
Pak se mezera, odpov�daj�c� definitivn�
velikosti pru�n�ho v�pl�ku ur�en�ho <glue specification>, vypln� opakovan�
dan�m boxem. Zhruba �e�eno, dan� box se pou�ije tolikr�t, aby se jeho
kopiemi polo�en�mi vedle sebe cel� mezera vyplnila. Tu��me, �e to naprosto
p�esn� nejde, proto�e boxem ���ky $w$ m��eme opakovan� vyplnit jen mezeru
o~velikosti cel�ho n�sobku $w$, ale mezera, dan� <glue specification>
m��e b�t jak�koli.

\TeX{} �e�� uveden� dilema t�emi r�zn�mi zp�soby podle toho, zda se pou�ije
primitiv |\leaders|, nebo jeho alternativy
|\cleaders| a |\xleaders|.\inl[xleaders]\inl[cleaders]
V�echny t�i primitivy maj� stejnou syntaxi z�pisu a li�� se jen v~algoritmu
um�s�ov�n� opakovan�ch box� do stanoven� mezery. Nejprve ilustrujeme chov�n�
t�chto primitiv� na obr�zku:

\setbox1=\vbox{\hrule\hbox to30pt{\vrule height12pt depth4pt
  \hfil\vrule\kern-0.4pt}\hrule\kern-4pt}
\setbox0=\vbox{\hrule\hbox to30pt{\vrule height12pt depth4pt
  \hfil x\hfil\vrule\kern-0.4pt}\hrule\kern-4pt}
\bigskip
\setbox2=\hbox{n�jak� text vlevo\hskip30pt}
\vbox{\lineskiplimit=-20pt
\hbox to\hsize{n�jak� text vlevo\leaders\copy0 \hfil pou�it� " "|\leaders|}
\vskip-\baselineskip
\hbox to\wd2{\leaders\box1\hfil}
\bigskip
\hbox to\hsize{n�jak� text vlevo\cleaders\copy0 \hfil pou�it� |\cleaders|}
\bigskip
\hbox to\hsize{n�jak� text vlevo\xleaders\box0 \hfil pou�it� |\xleaders|}}

Tento obr�zek je v�stupem tohoto k�du (a� na r�me�ky):

\beguk
\hbox to\hsize{n�jak� text vlevo%
    \leaders\hbox to30pt{\hfil x\hfil}\hfil pou�it� " \leaders"}
\hbox to\hsize{n�jak� text vlevo%
   \cleaders\hbox to30pt{\hfil x\hfil}\hfil pou�it� "\cleaders"}
\hbox to\hsize{n�jak� text vlevo%
   \xleaders\hbox to30pt{\hfil x\hfil}\hfil pou�it� "\xleaders"}
% uvozovky "..." jsou zde hranicemi verbatim prost�ed�.
\enduk

Opakovan� box m� ve v�ech p��padech ���ku 30\,pt a m� uprost�ed
p�smeno~\uv{x}. Pop��eme nyn� v�echny t�i zp�soby um�st�n� box�:

P�i pou�it� |\leaders| se \TeX{} pod�v� na lev� okraj
vn�j��ho boxu, v~n�m� je |\leaders| pou�it. Odtud za�ne pomysln�
opakovat stanoven� box a� do chv�le, kdy je pokryt cel� text
vlevo od m�sta, kde za��n� |\leaders|. Pak nav�e a za�ne skute�n� s�zet
boxy a� do chv�le, kdy je vypln�na po�adovan� mezera tak, �e se dal�� box
u� nevejde.

Je-li pou�it |\cleaders|, \TeX{} vlo�� do po�adovan� mezery maxim�ln� po�et
box�, v�echny jsou t�sn� u~sebe. Vlevo i vpravo od t�to skupiny box�
\TeX{} dopln� stejnou mezeru k~vypln�n� p��padn�ho nevy�erpan�ho zbytku.

P�i pou�it� |\xleaders| \TeX{} vlo�� rovn� maxim�ln� po�et box�, ov�em
p�ed prvn�, za posledn� a mezi ka�d� dva vlo�� stejnou mezeru. Velikosti
t�chto mezer vypln� v~sou�tu nevy�erpan� zbytek.  \endpar

Prvn� alternativa, tj.~pou�it� |\leaders|, se hod� pro vkl�d�n� te�ek do
obsah�. Pokud t�eba m�me

\beguk
\tocline{<n�zev kapitoly>}{<��slo strany>}
\enduk

pak m��eme definovat

\beguk
\def\tocline #1#2{%
    \line{#1 \leaders\hbox to1em{\hfil.\hfil}\hfil\ #2}}
\enduk

Proto�e \TeX{} m��� usazen� box� s~te�kami od lev�ho okraje vn�j��ho boxu,
budou v�echny te�ky na jednotliv�ch ��dc�ch v~obsahu p�esn� pod sebou.
Nez�le�� na tom, jak dlouh� je text s~n�zvem kapitol. \endpar

P�i opakov�n� box� ve vertik�ln�m m�du \TeX{} pracuje s~celkovou v��kou
opakovan�ho boxu (tj.~v��ka plus hloubka). S~t�mto rozm�rem pracuje
analogicky, jako v~horizont�ln�m m�du pracuje s~���ku opakovan�ho boxu.
Boxy klade pod sebe.

Nen�-li v�sledn� mezera z~<glue specification> v~|\leaders| kladn�, \TeX{}
nevys�z� ��dn� box. Nen�-li rozm�r opakovan�ho boxu kladn�, \TeX{} rovn�
netiskne ��dn� box. \uv{Rozm�r} zde znamen� ���ku v~p��pad�
horizont�ln�ho m�du a celkovou v��ku ve vertik�ln�m m�du.

V~m�st� pro z�pis boxu m��eme pou��t primitiv |\box|. \TeX{} pak
opakuje box z~dan�ho registru. Je ov�em t�eba upozornit na to, �e po
takov�m pou�it� boxu v~|\leaders| je hodnota registru ztracena. Box je sice
v~r�mci jednoho |\leaders| opakov�n, ale nakonec je registr vypr�zdn�n.
Pokud budeme obsah boxu pot�ebovat i
nad�le, mus�me pou��t nam�sto |\box| primitiv~|\copy|.
\endpar

{\subpar P��klad.}
Pop��eme sazbu obsahu v~t�to kn��ce. V�imn�me si, �e te�ky
jsou tam st��d�ny tak, �e kdy� na n� polo��me prav�tko pod �hlem
$63{,}5^{\textstyle\circ}$, m�me te�ky na jeho hran� p�kn� v~jedn� �ad�.

Uva�ujme, �e obsah sestavujeme z~pracovn�ho souboru {\tt tbn.toc}, kde
jednotliv� ��dky vypadaj� t�eba takto:

\beguk Uk�zka obsahu souboru tbn.toc
\partline {A}{Algoritmy}{9}
\chaptocline {1}{Vstupn� ��sti \TeX u}{10}
\subtocline {1.1}{Koncept vstupn� br�ny \TeX u}{10}
\subtocline {1.2}{Input procesor}{12}
\subtocline {1.3}{Token procesor}{19}
\chaptocline {2}{Expand procesor}{31}
\subtocline {2.1}{Definov�n� maker}{31}
<atd...>
\enduk

Vid�me, �e pro kapitolu m�me ��dek za��naj�c� sekvenc� "\chaptocline" a pro
sekci je pou�ita sekvence "\subtocline".
Pro sazbu takov�ch te�ek pou��v�me |\leaders| s~opakovan�m boxem:

\beguk
\hbox to12pt{\kern\dimen0.\hss}
\enduk

kde pro |\dimen|{\tt0} postupn� st��d�me hodnoty 3\,pt a 9\,pt. Pro
vyst��d�n� hodnot je pou�ito makro "\cvak". Cel� v�c vypad� tedy takto:

\beguk Makro pro sazbu obsahu se st��dav�mi te�kami
\def\cvak{\ifdim\dimen0!<6pt \dimen0=9pt \else \dimen0=3pt \fi}  !inl[cvak]
\def\puntiky{\leaders\hbox to12pt{\kern\dimen0.\hss}\hfil}
\def\chaptocline #1#2#3{\medskip
   \line{#1.\enskip #2\hfil #3}\medskip}
\def\subtocline #1#2#3{%
   \line{\qquad #1\quad #2\puntiky\hbox to2em{\hfil#3}}\cvak}
\def\partline #1#2#3{\cvak\bigskip
   \line{\bf ��st #1: #2 \puntiky\ #3}\cvak}
\enduk

�daje o~stran�ch~kapitol nejsou v~��dkov� osnov�. Nelze tedy v~t�chto
��dc�ch um�stit te�ky tak, aby v~obou sm�rech navazovaly. Proto jsem
se p�i n�vrhu typografie dokumentu rozhodl, �e tam ��dn� te�ky nebudou.
Jeliko� mezi posledn�m ��dkem sekce n�jak� kapitoly a dal��m ��dkem sekce
n�sleduj�c� kapitoly jsou vynech�ny dohromady dva ��dky (p�l plus jedna
plus p�l), sta�� v~tomto m�st� uplatnit jedno "\cvak". D�le se provede v�dy
jedno "\cvak" za ka�d�m ��dkem sekce. \endpar

V plainu jsou pomoc� |\leaders| a |\cleaders| definov�na makra |\hrulefill|
a |\dotfill| (viz ��st~B). \endpar


\sub Tabulky s~pevnou ���kou sloupc�                      [sloupce]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Pokud dop�edu v�me, jak �irok� budou jednotliv� sloupce tabulky, nemus�me
pou��t primitiv |\halign|, o~n�m� bude �e� v~dal�� kapitole.
Vyu�ijeme mo�nost ps�t |\hbox|" to"<dimen>. T�m nastav�me ���ky
jednotliv�ch sloupc�.

My�lenku hned ilustrujeme na p��klad�. Ka�d� semestr za mnou p�ijdou
kolegov�, �e pot�ebuj� vytisknout seznamy student�, aby si do seznam� mohli
d�lat v~pr�b�hu jednotliv�ch t�dn� v~semestru pozn�mky. Jm�na student�
jsou v�stupem jist� datab�ze. P�edpokl�dejme, �e jsou jm�na rozd�lena po
jednotliv�ch studijn�ch skupin�ch.
V~jedn� skupin� je maxim�ln� 25~student�. Vytiskneme pro
ka�dou skupinu p�tadvaceti��dkov� formul��, kde v~ka�d�m ��dku bude
naps�no jm�no jednoho studenta. Je-li student� m�n� ne�~25, budou zbyl�
��dky pr�zdn�, ale p�ihr�dky a ��slo nakresl�me.

Jeden ��dek bude vypadat t�eba takto:

\bigskip
\vbox{\parskip=0pt
\def\\#1 #2|{\hbox to#1{\enspace #2\hss}\cara}
\def\cara{\kern-0.4pt\vrule}
\def\radek #1|#2|{\vrule height4.5mm depth1.5mm
   \\10mm \hfill #1\enspace|\\50mm #2|\\19mm |\\1mm |%
   \zbytek{}\par \hrule}
\def\zbytek #1{\tempnum=0
   \loop \advance\tempnum by1
     \hfill\hbox to0pt{\hss#1\hss}\hfill\cara
   \ifnum\tempnum\<8 \repeat\hbox{}}
\hrule
\noindent\radek 1.|Mravenec Ferdinand|}

Prvn� sloupec obsahuje po�adov� ��slo, druh� jm�no studenta, dal��
pol��ko je pro individu�ln� vyu�it� u�itele. Pak za dvojitou �arou
n�sleduje patn�ct p�ihr�dek, proto�e semestr m� obvykle patn�ct
t�dn�. �ten�� v~knize vid� jen osm p�ihr�dek, proto�e na ���ku sazby knihy
by v�ech patn�ct p�ihr�dek vypadalo moc st�sn�n�.

Najednou tiskneme seznamy se stovkami a� tis�ci studenty
a je vhodn�, aby formul��e pro jednotliv� studijn� skupiny vypadaly
stejn�. To znamen�, �e ���ky p�ihr�dek by m�ly b�t stanoveny jednotn�.
Kdybychom pou�ili |\halign|, museli bychom do \TeX{}u na��st celou
datab�zi, aby \TeX{} rozhodl podle \uv{nejdel��ho} jm�na, jak �irokou volit
p�ihr�dku pro jm�na. To je neekonomick� a dokonce neu�ite�n�. Zat�mco
v�jime�n� n�jak� zahrani�n� student z~D�ln�ho v�chodu m� jm�no
slo�eno z~p�ti nebo v�ce slov,
v�t�ina student� m� jm�no obvykl� d�lky. Kv�li t�m v�jimk�m
ze zahrani�� by seznamy v�ech ostatn�ch studijn�ch skupin v~p�ihr�dce pro
jm�no zbyte�n� pl�tvaly m�stem. Je proto vhodn�j�� toho Muhameda
Abu Ali Admal atd. nechat vys�zet p�es okraj p�ihr�dky.

Vol�me tedy pevnou ���ku p�ihr�dek. Nap��klad pro po�adov� ��slo n�m bude
sta�it 1\,cm, proto�e se tam pro ka�dou skupinu vyskytuje nejv��e
��slo dvojcifern�. D�le pro jm�no jsme stanovili ���ku p�ihr�dky 5\,cm.
Dal�� pol��ko ur�en� pro pot�ebu u�itele bude m�t 2\,cm a pak ostatn�ch
15~p�ihr�dek vypln� stejnom�rn� zbytek.

Pro za��tek a pro jednoduchost p�edpokl�dejme, �e vstupn� soubor z~datab�ze
jmen u� u~ka�d�ho studenta obsahuje \TeX{}ovskou sekvenci a odd�lova�, tedy
�daje vypadaj� takto:

\beguk
\p Mravenec Ferdinand*
\p Nov�k Jan*
<atd...>
\enduk

Vytvo��me makro "\p", kter� bude s�zet jeden ��dek formul��e:

\beguk Sazba tabulky s pevn�mi rozm�ry sloupc�
\offinterlineskip !inl[pevnatab]
\newcount\num \newcount\tempnum
\parindent=0pt \parskip=0pt
\def\\!empty#1 #2|{\hbox to#1{\enspace #2\hss}\cara} !lnl[hboxto]
\def\cara{\kern-0.4pt\vrule}
\def\radek #1|#2|{\vrule height4.5mm depth1.5mm !lnl[vrulehd]
   \\10mm \hfill #1\enspace|\\50mm #2|\\19mm |\\1mm |% !lnl[celyradek]
   \zbytek \par \hrule}
\def\zbytek{\tempnum=0
   \loop \advance\tempnum by1 \hfill\cara
   \ifnum\tempnum!<15 \repeat}
\def\p #1*{\advance\num1 \radek\the\num.|#1|}
\enduk

Zde jsme si na ��dku~\lnr[hboxto] definovali zkratku, abychom nemuseli
po��d dokola ps�t |\hbox|" to"<dimen>. Makro "\radek" vytvo�� cel� jeden
��dek formul��e a vezme dva parametry: prvn�, ��slo, vytiskne do
prvn� p�ihr�dky a druh�, jm�no studenta, do druh�. Linka "\vrule" se
stanovenou v��kou a hloubkou (��dek~\lnr[vrulehd]) ur�uje
celkovou v��ku ka�d�ho ��dku formul��e. Linka zde funguje jako podp�ra.
P�edpokl�d� se, �e ��dn� text se jm�nem nebude m�t nikdy v��ku nebo hloubku
v�t��, ne� m� tato linka. Tato linka tak� zahajuje odstavcov� m�d. Na
n�sleduj�c�m ��dku v~k�du~(\lnr[celyradek]) pak definujeme celou strukturu
��dku formul��e. Sazba prob�h� v~odstavcov�m m�du. Pomoc� makra "\zbytek"
vlo��me patn�ct vertik�ln�ch �ar stejn� daleko od sebe (|\hfill| vytla��
|\parfillskip| z~konce ��dku odstavce). Pak uzav�eme odstavec. Kone�n�
nakresl�me vodorovnou ��ru pod ��dkem (|\hrule|).

Nesm�me zapomenout p�idat ��ru nad prvn�m ��dkem formul��e.
D�le po na�ten�
seznamu student� jedn� skupiny se mus�me postarat o~to, aby byl zbytek
��dk� do dvaceti p�ti dopln�n pr�zdn�mi kolonkami. Proto je�t�
definujeme makro "\dodelej", kter� dotiskne zbytek do dvaceti p�ti ��dk�:

\beguk
\def\dodelej{\loop \advance\num by1
   \ifnum\num!<26 {\radek\the\num.||}\repeat \vfil\break}
\enduk

V�imn�me si, �e jsme zde sazbu ��dku makrem "\radek" uzav�eli do skupiny.
M�me tam toti� je�t� jeden |\loop| a je pot�eba, aby se vnit�n� cyklus 
s~vn�j��m neh�dal.

Nyn� makro tro�ku vylep��me, abychom nemuseli v~datab�zi p�ed ka�d� jm�no
ps�t "\p" a na konec nemuseli p�ipojovat hv�zdi�ku. Nech� se pomoc�
|\obeylines| stane konec vstupn�ho ��dku "^^M" aktivn�. Znak "^^M" bude
slou�it jako separ�tor:

\beguk
{\obeylines\gdef\p #1^^M{\advance\num1 \radek\the\num.|#1|}}
\enduk

Nyn� sta�� na��st soubor z~datab�ze p�i aktivn�m "^^M" a p�i
|\everypar|"={\p}". \endpar

Uveden� p��klad rozvedeme na uk�zce maker pro zpracov�n� skute�n�ho
v�stupu z~datab�ze, kter� se pou��v� na na�� fakult�. Tv�rci v�stupn�ch
procedur z~datab�ze p�edpokl�dali, �e u�ivatel pou�ije jednoduchou
��dkovou tisk�rnu a na \TeX{} v�bec nepomysleli. O~to budeme m�t v~makru
v�ce pr�ce spr�vn� na��st v�stupn� sestavu z~datab�ze, kter�
vypad� takto:

\beguk
  Komponenta studium                 Datum a �as: 23.09.96 15:17
!indent
    Ro�n�k:   1   Skupina:     21
!indent
   P��jmen�           Jm�no             Rodn� ��slo
   -----------------  ----------------  -----------
   Mravenec           Ferdinand         1234567890
   Erben              Karel Jarom�r     0987654321
   <atd., dal�� studenti>
   <pr�zdn� ��dky>
                                            Strana 1     ze 18
^^L
!indent
  Komponenta studium                 Datum a �as: 23.09.96 15:17
!indent
    Ro�n�k:   1   Skupina:    22
!indent
   P��jmen�           Jm�no             Rodn� ��slo
   ------------------ ----------------- -----------
   Nov�k              Jan               3333333333
   <dal�� studenti a pr�zdn� ��dky>
                                            Strana 2     ze 18
^^L
<dal�� skupiny stejn�>
\enduk

Makro, kter� dok�e takovou datab�zi na��st a vytisknout tabulky se seznamy
student� podle pr�v� popsan�ho form�tu, m��e vypadat n�sledovn�:

\beguk Zpracov�n� datab�ze student� do tabulek
\nopagenumbers \offinterlineskip !inl[database]!inl[seznam]
\newcount\num \newcount\tempnum
\special{landscape}  \hsize=\vsize \voffset=-.5cm  !lnl[speclandscape]
\parindent=0pt  \parskip=0pt
\def\\#1 #2|{\leavevmode\hbox to#1{\enspace #2\hss}\cara}
\def\cara{\kern-0.4pt\vrule}
\def\radek #1|#2|{\vrule height4.5mm depth1.5mm
   \\10mm \hfill #1\enspace|\\50mm #2|\\19mm |\\1mm |%
   \zbytek{}\par \hrule}
\def\zbytek #1{\tempnum=0
   \loop \advance\tempnum by1
     \hfill\hbox to0pt{\hss#1\hss}\hfill\cara
   \ifnum\tempnum!<15 \repeat\hbox{}}
\def\dodelej{\loop \advance\num by1 %
   \ifnum\num!<26 {\radek\the\num.||}\repeat \vfil\break \num=0}
\def\setcatnumbers#1{\tempnum=`0 % kategorie pro ��slice
    \loop \catcode\tempnum=#1 
       \ifnum\tempnum!<`9 \advance\tempnum by1 \repeat}
\obeylines  !lnl[startobey]
\def\p #1^^M{\advance\num1 \radek\the\num.|#1|}%
\def\demask Komponenta #1Ro�n�k: #2 Skupina: #3^^M{\everypar={}%
   \vrule height5mm depth2mm width0mm %
   {\let\cara=\relax % Sazba z�hlav� tabulky; nepot�ebujeme ��ry
    \\80mm \bf \vrule width0pt depth4pt  Skupina #3|% podp�ra
    \zbytek{\the\tempnum}}\par\hrule                % ��sla t�dn�!lnl[uzijzbytek]
   \setcatnumbers{9} \maskpata}
\def\maskpata #1-^^M#2Strana#3^^M{\everypar={\p}#2\everypar={}%
   \dodelej \everypar={\demask}\setcatnumbers{12}}
\everypar={\demask}
\input database.txt
\end
\enduk

N�kter� ��sti makra si je�t� zaslou�� na�i pozornost.
Na ��dku~\lnr[speclandscape] jsme pou�ili |\special|"{landscape}", co� d�v�
do {\tt dvi} pokyn pro ovlada� {\tt dvips}, aby se formul�� tiskl na stranu
oto�en o~90$^{\textstyle\circ}$. Proto budeme m�t pro jednotliv� ��dky dost
m�sta a m��eme nastavit |\hsize|{\tt=}|\vsize|.

Makro "\zbytek" jsme roz���ili, aby obsahovalo jeden parametr, kter� bude
um�st�n uprost�ed ka�d� p�ihr�dky pro t�den semestru. Pou�it�
"\zbytek{\the\tempnum}" na ��dku~\lnr[uzijzbytek]
n�m tedy vys�z� ��sla jednotliv�ch t�dn�, co� pot�ebujeme do z�hlav�.

Od ��dku \lnr[startobey] nastavujeme znak~"^^M" (konec ��dku) jako aktivn�
a m� v�znam |\par|. Konec ��dku bude toti� odd�lova�em pro parametry na�ich
dal��ch maker. Makro "\demask" se spust� z~"\everypar", sotva se \TeX{} dostane
k~prvn�mu slovu v~datab�zi, kter�m je slovo {\tt Komponenta}. V�e a� po
slovo {\tt Ro�n�k} p�esko��me a do "#3" ukl�d�me ��slo skupiny, kter�
budeme s�zet v~z�hlav�. Po sazb� z�hlav� pot�ebujeme z~n�sleduj�c�ch
vstupn�ch �daj� \uv{odd�lit zrno od plev}, co� provede makro "\maskpata".
Do parametru "#1" se schovaj� zbyte�nosti ze vstupn�ho z�hlav� v�etn� v�ech
podtrhovac�ch znak� \uv{"---"} a� po posledn�. To jsou plevy.
V~parametru "#2" m�me zrno, kter� je nav�c na�teno v okam�iku, kdy ��slice
{\tt 0}~a�~{\tt 9} maj� kategorii~9 (ignoruj), tak�e ignorujeme �daje
o~rodn�ch ��slech. Kone�n� v~parametru~"#3" jsou zase plevy. P�i
|\everypar|"={\p}" pak zpracujeme jednotliv� ��dky \uv{zrna} zp�sobem, kter�
jsme popsali v��e. Nakonec vrac�me ��slic�m p�vodn� kategorii~12, abychom
mohli p�e��st ze z�hlav� dal�� strany ��slo skupiny.

V�imneme si je�t�, �e v�stup z~datab�ze klade mezi jednotliv� str�nky
ur�en� pro levnou ��dkovou tisk�rnu znak "^^L" (konec strany). To n�s
v~plainu v�bec nevyv�d� z~m�ry, proto�e tento znak zde m� aktivn� kategorii
a m� v�znam "\par". \endpar


\begingroup

{\subpar Makro plainu emuluj�c� vlastnosti psac�ho stroje.}
Ve zbyl� ��sti t�to sekce se budeme zab�vat makry plainu pro
tzv.~|\tabalign|\inl[tabalign],
co� umo��uje nastavovat a posl�ze pou��vat sloupe�ky
s~pevnou ���kou. Vyu�it� makra nen� p��li� �ast�. Snad je to proto, �e a�
p��li� p�ipom�n� vlastnosti psac�ho stroje. V�me, �e p��prava sazby a
pou��v�n� psac�ho stroje jsou dv� zcela odli�n� v�ci.

Nejprve vylo��me vlastnosti makra na u�ivatelsk� �rovni a teprve v~dal��
��sti se pust�me do rozboru maker plainu, kter�mi jsou tyto vlastnosti
implementovan�.

V prost�ed� |\tabalign| u�ivatel pou��v� tzv.~{\it tabul�tory},\inl[tabulator]
kter� ozna�uje symbolem~\uv{"&"}. Jedn� se o~neviditeln� zna�ky, jejich�
poloha v~��dku ur�uje um�st�n� lev�ch okraj� jednotliv�ch sloupc�.

��dek ��zen� prost�ed�m |\tabalign| se zapisuje ve form�tu
|\+|<obsah ��dku>"\cr". V~<obsahu ��dku> se mohou vyskytovat znaky~\uv{"&"},
kter� mohou m�t jeden z~t�chto v�znam�:

\begitems
* Nastaven� polohy tabul�toru podle polohy aktu�ln�ho bodu sazby.
* Vyu�it� polohy tabul�toru pro um�st�n� n�sleduj�c�ho textu.
\enditems

Znaky~\uv{"&"} v~<obsahu ��dku> po��t�me zleva \uv{prvn�, druh�, t�et�} atd.
P�itom $n$-t� znak~\uv{"&"} reprezentuje $n$-t� tabul�tor. Nen�-li $n$-t�
tabul�tor nastaven, p��tomnost $n$-t�ho znaku~\uv{"&"} jej nastavuje. Je-li
$n$-t� tabul�tor nastaven, nenastavuje se znovu, ale za��tek textu
za $n$-t�m znakem~\uv{"&"} bude (po ignorov�n� vstupn�ch mezer) um�st�n
v~poloze tabul�toru. Na po��tku nen� nastaven ��dn� tabul�tor. P��klad:

\beguk
\+ Tady nastavuji prvn�:& tu druh�:& a p��u dal�� text \cr
\+ text od kraje & od prvn�ho & od druh�ho, nastavuji t�et�:&\cr
\+ &&& text od t�et�ho tabul�toru\cr
\enduk

Tento experiment n�m d�v� n�sleduj�c� v�sledek:

\bigskip
\+ Tady nastavuji prvn�:& tu druh�:& a p��u dal�� text \cr
\+ text od kraje & od prvn�ho & od druh�ho, nastavuji t�et�:&\cr
\+ &&& text od t�et�ho tabul�toru\cr

V~uk�zce si m��eme v�imnout dvou vlastnost�: (1)~Text podle tabul�tor�
se m��e beztrestn� p�ekr�vat. (2)~Text s�zen� z~<obsahu ��dku> m��e
beztrestn� vy�n�vat ze zrcadla sazby dan�ho ���kou |\hsize|.

Pomoc� makra |\cleartabs| pou�it�m v~<obsahu ��dku> m��eme mazat nastaven�
v�ech tabul�tor� vpravo od z�pisu |\cleartabs|. Jin�mi slovy,
v�echny n�sleduj�c� znaky~\uv{"&"} pou�it� za |\cleartabs| v~<obsahu ��dku>
polohu tabul�toru znovu nastavuj� a nepou��vaj�. Nav�eme-li na n�
p�edchoz� p��klad:

\beguk
\+ dal�� text od kraje & od prvn�ho a znovu
   nastavuji druh�:\cleartabs & a nastavuji je�t� t�et�:&\cr
\enduk

Pomoc� makra |\settabs|, kter� pou��v�me mimo <obsah ��dku>, lze vymazat
polohy v�ech tabul�tor� a nastavit je znova. Pou�ije-li se toto makro ve
form�tu

\beguk
\settabs\+ <obsah ��dku>\cr
\enduk

pak znaky~\uv{"&"} uvnit� <obsahu ��dku> nastavuj� tabul�tory, ale v�sledn� text
se netiskne. M��eme tedy nastavit tabul�tory podle n�jak�ho
abstraktn�ho textu, o~kter�m v�me, �e reprezentuje nap��klad nej�ir�� z�pis
v~jednotliv�ch sloupe�c�ch.

Existuje je�t� jeden zp�sob pou�it� makra |\settabs| pro nastaven�
tabul�tor�. P�i z�pise "\settabs<number>\columns" \TeX{} nastav�
$n=<number>$ tabul�tor� tak, �e posledn� ($n$-t�) je p�esn� na prav�m
okraji zrcadla ur�en�ho podle |\hsize| a v�echny ostatn� jsou rovnom�rn�
daleko od sebe a rozd�luj� ���ku zrcadla na $n$ stejn� �irok�ch
sloupe�k�. Nap��klad po:

\beguk
\settabs 3\columns
\+ Od kraje & Od prvn�ho & Od druh�ho \cr
% "& Od t�et�ho" neuk�eme, proto�e by vy�n�val ven ze zrcadla.
\enduk

dost�v�me:

\bigskip
\settabs 3\columns
\+ Od kraje & Od prvn�ho & Od druh�ho \cr

Zarovn�n� textu nalevo v~ka�d�m sloupe�ku je za��zeno pomoc� |\hss|
p�ipojovan�m vpravo k~textu. Proto m��eme ve sloupci text centrovat t�eba
takto:

\beguk
\settabs 3\columns
\+\hss prvn� sloupec&\hss druh�&\hss a t�et�&\cr
\enduk

Kdybychom t�sn� p�ed |\cr| nenapsali znak~\uv{"&"}, nebude \TeX{} k~textu
��dn� |\hss| p�ipojovat. Text posledn�ho sloupce t�sn� p�ed |\cr| toti�
nen� nijak upravov�n. \endpar

\endgroup

Nyn� si pop��eme �innost makra plainu, kter� n�m uveden� prost�ed�
|\tabalign| nab�z�. Zjist�me, �e se makro nakonec op�r� o~primitiv
|\halign|, ov�em nen� vyu�ita jeho vlastnost sestavov�n� sloupe�k� podle
nej�ir��ho textu.

Makro budeme komentovat po ��stech. Nejprve uvedeme deklarace:\pgl[tabalign]

\beguk Plain
\newif\ifus@ \newif\if@cr
\newbox\tabs \newbox\tabsyet \newbox\tabsdone
\enduk

Pomoc� "\ifus@" se pt�me na to, zda si u�ivatel p�eje tisknout
<obsah ��dku>. V�me, �e p�i "\settabs\+<obsah ��dku>\cr" podl�h� sestaven�
<obsahu ��dku> stejn�m pravidl�m, pouze v�sledek nakonec nevytiskneme.
V~takov�m p��pad� bude "\ifus@" d�vat \uv{false}.
D�le podle "\if@cr" makro zji��uje, zda je p�e�tena posledn� polo�ka,
za kterou u� n�sleduje |\cr|. Tuto polo�ku makro zpracuje odli�n�m zp�sobem.

V~boxu "\tabs" je seznam box�, jejich� ���ky ur�uj� ���ky
jednotliv�ch sloupc� v~opa�n�m po�ad�, ne� ve kter�m po��t�me sloupce.
���ka posledn�ho boxu v~"\tabs" tedy ur�uje ���ku prvn�ho sloupce.
Nap��klad po "\settabs 3\columns" m�me v~"\tabs" t�i boxy,
ka�d� m� ���ku rovnou t�etin� |\hsize|.

Na za��tku sestavov�n� <obsahu ��dku> vlo��me boxy z~"\tabs" do "\tabsyet".
D�le v~pr�b�hu sestavov�n� <obsahu ��dku> budeme jednotliv� boxy
odpov�daj�c� zpracov�van�m polo�k�m p�erovn�vat z~"\tabsyet" do
"\tabsdone". P�i t�to �innosti m��eme n�kter� boxy p�idat (nov�
tabul�tory), n�kter� mazat ("\cleartabs") a posl�ze t�eba zase p�id�vat. Na
konci ��dku (p�i~"\cr") vr�t�me (p��padn�) nov� �daje o~tabul�torech do
"\tabs".

Nyn� n�sleduj� makra "\cleartabs" a "\settabs" a za��tek makra "\+".

\beguk Plain
\def\cleartabs{\global\setbox\tabsyet=\null \setbox\tabs=\null}!pgl[cleartabs]
\def\settabs{\setbox\tabs=\null \futurelet\next\sett@b} !pgl[settabs]
\let\+=\relax % in case this file is being read in twice
\def\sett@b{\ifx\next\+
    \def\nxt{\afterassignment\s@tt@b\let\nxt}%
  \else\let\nxt=\s@tcols\fi \let\next=\relax \nxt} !lnl[nextrelax]
\def\s@tt@b{\let\nxt\relax \us@false \m@ketabbox}
\def\tabalign{\us@true \m@ketabbox} % non-\outer version of \+
\outer\def\+{\tabalign}
\def\s@tcols#1\columns{\count@=#1 \dimen@=\hsize
  \loop \ifnum\count@>\z@ \@nother \repeat}
\def\@nother{\dimen@ii=\dimen@ \divide\dimen@ii by\count@
  \setbox\tabs=\hbox{\hbox to\dimen@ii{}\unhbox\tabs}%
  \advance\dimen@ by-\dimen@ii \advance\count@ by-1 }
\enduk

Vid�me, �e "\cleartabs" ma�e boxy v~"\tabsyet", ale nikoli v~"\tabsdone".
To znamen�, �e u� zpracovan� polo�ky budou m�t tabul�tory zachov�ny, ale
n�sleduj�c� budou nov� nastaveny. Makro "\settabs" nuluje v�echny
tabul�tory (v~"\tabs") a d�le se pomoc� |\futurelet| pt�, zda n�sleduje
token "\+". Pokud ano, provede se zpracov�n� ��dku ("\m@ketabbox") 
s~parametrem \uv{netiskni v�sledek} ("\us@false"). Pokud ne, makro se chov�
jako "\s@tcols", tj.~�te <number> p�ed separ�torem "\columns" a vkl�d� jej
do "\count@". V~"\@nother" se postupn� v~cyklu ulo�� do "\tabs" pr�zdn�
boxy o~���ce |\hsize|/<number>. Promyslete si, pro�.

D�le�itou vlastnost� makra "\+" je, �e je definov�no prefixem |\outer|. To
zamez� chyb� typu "\+<obsah ��dku> \+" (tj. zapomenut� "\cr"). Na druh�
stran� s~t�m m�me v~makru trochu probl�my a mus�me se s~t�m vyrovnat.
N�sleduj�c� rozbor makra je tedy mo�no ch�pat t� jako uk�zku r�zn�ch
nebezpe��, ��haj�c�ch p�i definov�n� jak�hokoli makra prefixem
|\outer|.

V~t�le definice makra "\setb@x" je pou�it token "\+", a proto v~tu chv�li
nesm� b�t typu |\outer|. Z~toho d�vodu je p�ed t�m �e�eno "\let\+=\relax",
abychom zru�ili mo�n� p�vodn� v�znam tokenu "\+". To m��e b�t u�ite�n� p�i
opakovan�m �ten� souboru {\tt plain.tex}.

V~makru "\settabs" se m��e pomoc� |\futurelet| ztoto�nit v�znam "\next"
s~tokenem "\+". Pak ov�em m� "\next" typ |\outer| a u� nikdy by nebylo mo�n�
jej pou��t v~t�le definice. P�itom sl�vko "\next" pou��v�me v~t�lech
definic r�di. Proto na ��dku~\lnr[nextrelax] d�v�me tokenu "\next" v�znam
|\relax|.

Vlastn� makro "\+" m� verzi bez |\outer| s~n�zvem "\tabalign". Tato verze
se d� pou��t v~na�ich vlastn�ch definic�ch. Makro "\tabalign" expanduje
nakonec na "\m@ketabbox" p�i "\us@true", tj.~bude se tisknout v�sledn�
<obsah ��dku>.

Kone�n� uvedeme makra, kter� zpracov�vaj� <obsah ��dku>.

\beguk Plain
\def\m@ketabbox{\begingroup
  \global\setbox\tabsyet=\copy\tabs
  \global\setbox\tabsdone=\null
  \def\cr{\@crtrue\crcr\egroup\egroup     !lnl[dvaegroup]
    \ifus@ \unvbox0\lastbox \fi\endgroup  !pgl[lasttrik]!lnl[lasttrik]
    \setbox\tabs\hbox{\unhbox\tabsyet\unhbox\tabsdone}}%!lnl[obnovatabs]
  \setbox0=\vbox\bgroup\@crfalse             !lnl[zahajtab]
    \ialign\bgroup&\t@bbox##\t@bb@x\crcr}
\def\t@bbox{\setbox0=\hbox\bgroup}
\def\t@bb@x{\if@cr\egroup % now \box0 holds the column
  \else\hss\egroup                                 !lnl[za�niat]
     \global\setbox\tabsyet=\hbox{\unhbox\tabsyet
          \global\setbox1=\lastbox}% now \box1 holds its size
     \ifvoid1 \global\setbox1=\hbox to\wd0{}%
     \else \setbox0=\hbox to\wd1{\unhbox0}\fi
     \global\setbox\tabsdone=\hbox{\box0\unhbox\tabsdone} !lnl[konecat]
  \fi \box0}
\enduk

Nejprve v~"\m@ketabbox" otev�eme skupinu a v~r�mci n� nastav�me v�choz�
hodnoty pro \uv{p�erovn�vac� �ady} vzorov�ch box� "\tabsyet" a "\tabsdone".
P�edefinujeme "\cr", tak�e v�ude v~souvislosti s~|\halign| budeme
pou��vat n�hradn� |\crcr|. Do definice "\cr" se pod�v�me a� nakonec. Nyn�
za�neme ��st makro od ��dku~\lnr[zahajtab]. Tam otv�r�me |\vbox| a do n�j
(jak uvid�me pozd�ji) postupn� vlo��me v�sledek jedno��dkov�ho |\halign|.

Makro "\ialign" je ekvivalent k~|\halign| s~nastaven�m nulov�ho |\tabskip|.
Zde m�me v~deklaraci ��dku jedin� sch�ma polo�ky s~p��znakem n�vratu
(terminologie k~|\halign|, viz n�sleduj�c� sekci).
P�i zah�jen� polo�ky se expanduje "\t@bbox", tj.~provede se
\uv{|\setbox|"0=\hbox{"}. Jakmile naraz�me p�i zpracov�n� polo�ky na
znak~\uv{"&"}, box~0 se uzav�e (viz "\t@bb@x"). M�me tedy v~boxu~0 pr�v�
na�tenou polo�ku. Pokud je polo�ka ukon�ena znakem~\uv{"&"}, d�v� "\if@cr"
hodnotu \uv{false}, nebo� jsme zat�m nedos�hli konce ��dku pomoc� "\cr".
Pov�me si, co se v~tomto p��pad� odehr�v� (��dky~\lnr[za�niat] a�
\lnr[konecat]):

P�edn� polo�ka se uzav�e s~p�ipojen�m |\hss| na konec textu polo�ky.
Pak se do boxu~1 vlo�� z~"\tabsyet" box, kter� by m�l svou ���kou
ud�vat ���ku pr�v� zpracov�van� polo�ky. P�itom se z~"\tabsyet" tento box
zru��. Pokud se odtud nepoda�ilo z�skat informaci o~���ce polo�ky
(|\ifvoid|{\tt1}), budeme tabul�tor nastavovat. Proto nastav�me v~boxu~1
���ku pr�v� na�ten� polo�ky (|\wd|{\tt0}). Pokud informace o~tabul�toru
existuje (|\else|), nebude se tabul�tor nastavovat, ale uprav� se ���ka
boxu~0 s~na�tenou polo�kou na po�adovanou ���ku |\wd|{\tt1}. Nakonec se do
"\tabsdone" ulo�� (p��padn� nov�) box ud�vaj�c� ���ku polo�ky, neboli polohu
tabul�toru. Ven z~makra ke zpracov�n� v~polo�ce |\halign| vystupuje v�dy
box~0.

Ukon��-li u�ivatel ��dek pomoc� |\cr|, toto makro expanduje na "\@crtrue"
n�sledovan� |\crcr| (tj.~skute�n�m ukon�en�m ��dku v~|\halign|). Nyn� u� 
v~z�v�re�n� ��sti sch�matu polo�ky nen� ��dn� rozs�hl� �innost, pouze se
text z~boxu~0 dost�v� do sazby polo�ky, jak j� rozum� primitiv |\halign|.

Prvn� |\egroup| na ��dku~\lnr[dvaegroup] uzav�r� |\halign|. Tento primitiv
u� nem� co na pr�ci. Jeden ��dek \uv{tabulky} s~rozm�ry polo�ek tak, jak je
p�ipravilo makro, vlo�� do vertik�ln�ho seznamu. Druh� |\egroup| uzav�r�
|\vbox| otev�en� na ��dku~\lnr[zahajtab]. Tento box tedy nyn� vstupuje do
pracovn�ho boxu~0. V~tomto boxu m�me jedin� ��dek odpov�daj�c�
<obsahu ��dku>, kter� jsme pr�v� zpracovali. M�-li b�t tento ��dek ti�t�n
("\ifus@"), vr�t�me jej do vn�j��ho vertik�ln�ho seznamu pomoc�
|\unvbox|{\tt0}. Zde stoj� za pozornost trik s~|\lastbox|
z ��dku~\lnr[lasttrik]. Tento trik je rozebr�n u hesla |\unvbox| v ��sti~B.

Nakonec na ��dku~\lnr[obnovatabs] obnov�me stav tabul�tor� udr�ovan� 
v~"\tabs". Nejprve vkl�d�me nevy�erpan� tabul�tory z~"\tabsyet" a za nimi
pou�it� a p��padn� nov� zpracovan� tabul�tory z~"\tabsdone". \endpar



\sub Tabulky pomoc� \tt\char`\\halign                      [halign]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Algoritmy, kter� souvisej� s~primitivem |\halign|, jsou pom�rn� komplikovan�.
Za�neme proto zlehka, jednoduch�m p��kladem:

\beguk �vodn� p��klad na \halign
\tabskip=2em plus 5em
\halign{{\bf Polo�ka:} #\hfil & \hfil#\hfil \quad konec\cr !lnl[defradku]
  prvn� & toto bude na st�ed \cr \noalign{\hrule\smallskip}!lnl[mezerypol]
  druh� & dal�� text \cr
  t�et� \cr}          !lnl[t�et�]
\enduk

Tento k�d vyprodukuje n�sleduj�c� tabulku:

$$\vbox{\tabskip=2em
\halign{{\bf Polo�ka:} #\hfil &\hfil#\hfil \quad konec\cr
  prvn� & toto bude na st�ed \cr \noalign{\hrule\smallskip}
  druh� & dal�� text \cr
  t�et� \cr}}\pgl[prvnitab]
$$

"\halign" m� (zhruba) tuto strukturu z�pisu:

\beguk
\halign{<deklarace ��dku> \cr
  <polo�ky tabulky prvn�ho ��dku> \cr
  <polo�ky tabulky druh�ho ��dku> \cr
  ...    
  <polo�ky tabulky posledn�ho ��dku> \cr}
\enduk

Pojmem {\it t�lo tabulky\/}\inl[telotab]
ozna�ujeme v�e, co je zaps�no mezi
z�vorkami "{...}" za primitivem |\halign|.
T�lo tabulky se d�l� na dv� ��sti: {\it deklaraci ��dku\/}\inl[deklradku]
ukon�enou prvn�m "\cr" a {\it datovou ��st\/}\inl[datacast]
tabulky.
V datov� ��sti jsou {\it polo�ky\/}\inl[polozka]
tabulky, kter� jsou od sebe
odd�leny tokenem kategorie~4 (ASCII k�d
nehraje roli, obvykle se pou��v� \krab[\&]4.). Jednotliv� ��dky jsou
v datov� ��sti odd�leny od sebe sekvenc� "\cr".
Za sekvenc� "\cr" m��e b�t primitiv |\noalign| a za n�m
pak "{<vertik�ln� seznam>}". Pokud se tak stane, \TeX{} zat�m neotv�r�
dal�� polo�ku, ale akceptuje <vertik�ln� seznam>, kter� ulo�� pod pr�v�
ukon�en� ��dek. Pokud je |\noalign| hned za prvn�m |\cr|, kter� ukon�uje
deklaraci ��dku, seznam se ulo�� nad tabulku p�ed prvn� ��dek tabulky.

Primitiv |\cr| mus� b�t uveden i za posledn�m ��dkem tabulky, jinak
se do�k�me chyby. Pokud si konstrukci |\halign| p��eme sami, pak toto
omezen� nen� probl�mem, proto�e si na to d�me pozor. Pokud ale vytv���me
makro pro u�ivatele, kter� jednou pou�ije |\cr| na konci sv� tabulky a
podruh� ne, pak mohou nastat probl�my. Proto existuje primitiv |\crcr|,
kter� je po sekvenci |\cr| (a p��padn� za konstrukc� |\noalign|) ignorov�n,
zat�mco v�ude jinde se chov� jako |\cr|. V~makrech tedy doporu�ujeme ps�t
pro uzav�en� konstrukce tabulky |\crcr|"}".

Deklarace ��dku se �len� na {\it sch�mata polo�ek},\inl[schema]
kter� jsou od sebe
odd�lena tokenem kategorie 4 (\krab[\&]4.). Ka�d� sch�ma polo�ky {\it
mus�\/} obsahovat pr�v� jeden token kategorie 6 (obvykle se pou��v�
\krab[\#]6.). Samoz�ejm�, pokud je sch�ma sou��st� t�la n�jak� definice,
znak \krab[\#]6. mus� b�t zdvojen�. S~t�mto probl�mem jsme se u� setkali
v~sekci o~definov�n� maker~\rsec[def].

P�i �ten� obsahu jedn� polo�ky \TeX{} otev�e |\hbox| a t�m t� vstoup� do
nov� �rovn� skupiny. V~tomto boxu za�ne nejprve zpracov�vat tokeny
uveden� v~odpov�daj�c�m sch�matu polo�ky a� po znak \krab[\#]6. mimo n�j.
P�itom prov�d� expanzi maker. V~na�em p��klad� se t�eba |\bf| expanduje
na |\fam||\bffam||\tenbf|.  Pot� p�ejde \TeX{} do datov� ��sti a �te
(a expanduje) tokeny odtud a� po token uzav�raj�c� polo�ku (\krab[\&]4. nebo
|\cr|). Pak se vr�t� k~druh� ��sti sch�matu polo�ky za znakem \krab[\#]6. a
dokon�� zpracov�n� polo�ky. T�m vytvo�� horizont�ln� seznam a uzav�e
|\hbox| polo�ky. Takto postupn� proch�z� v�echny polo�ky v~datov� ��sti
|\halign|. Pro ka�dou z~nich vytvo�� speci�ln� |\hbox|.

Pozn�mka k~mezer�m. P�i zah�jen� �ten� polo�ky z~datov� ��sti jsou
ignorov�ny v�echny mezery a� po prvn� token r�zn� od mezery. Dal��
(p��padn�) mezery v~datov� ��sti u� jsou v�znamn�. V~na�em p��klad� na
��dku~\lnr[mezerypol] je p�ed slovem {\tt toto} ve druh� polo�ce mezera
ignorov�na, ale za slovem {\tt st�ed} mezera z�st�v�.
Rovn� v~deklaraci ��dku se ignoruje mezera za znakem \krab[\&]6., tak�e
nap��klad na ��dku~\lnr[defradku] je mezera za t�mto znakem nev�znamn�.

Je-li v~datov� ��sti v~r�mci jednoho ��dku m�n� polo�ek, ne� je
sch�mat polo�ek v~deklaraci ��dku, boxy zb�vaj�c�ch polo�ek
z�stanou pr�zdn�~--- tj.~nebudou obsahovat ani materi�l ze sch�matu polo�ek.
Viz ��dek~\lnr[t�et�] v~na�� uk�zce, kde chyb� druh� polo�ka v~datov�
��sti, a tud�� se nevyprodukuje ani slovo \uv{konec}, spole�n� v�em
ostatn�m ��dk�m.

Pokud je v~datov� ��sti na jednom ��dku v�ce polo�ek, ne� je sch�mat
polo�ek v~deklaraci ��dku, do�k�me se chybov�ho hl�en� {\tt Extra
alignment tab has been changed to |\cr|}. V~deklaraci ��dku ale m��eme
definovat jednoduchou smy�ku, kter� pracuje takto: Po vy�erp�n� sch�mat
polo�ek se \TeX{} vrac� na sch�ma
s~tzv.~{\it p��znakem n�vratu\/}\inl[priznaknavratu]
a od n�j znovu
postupuje a� k~posledn�mu sch�matu. Pak se p��padn� znovu vrac� na tot�
sch�ma s~p��znakem n�vratu, atd. Sch�ma s~p��znakem n�vratu se zna�� znakem
kategorie 4 na jeho za��tku. Syntakticky to znamen�, �e znak \krab[\&]4. se
vyskytuje t�sn� za otev�rac� z�vorkou \krab[\char`\{]1. konstrukce
|\halign| (tj. hned prvn� sch�ma m� p��znak n�vratu) nebo se sejdou dva
znaky \krab[\&]4. vedle sebe. To nezna�� pr�zdn� sch�ma, n�br� se t�m prav�,
�e n�sleduj�c� sch�ma m� p��znak n�vratu. V~deklaraci ��dku m��e m�t
p��znak n�vratu nejv��e jedno sch�ma, ke kter�mu se pak cyklus vrac�.
Nap��klad:

\beguk Opakov�n� sch�mat v deklaraci ��dku
\halign{1:# & 2:# && 3:# & 4:# \cr
  a & b & c & d & e & f & g & h \cr
  i \cr
  j & k~& l & m & n \cr}
\enduk

d�v� na v�stupu:

$$\vbox{
\halign{1:# & 2:# && 3:# & 4:# \cr
  a & b & c & d & e & f & g & h \cr
  i \cr
  j & k~& l & m & n \cr}} \qquad \endpar
$$

Nyn� p�ejdeme k~v�kladu nejd�le�it�j�� vlastnosti primitivu |\halign|.
Tabulka je sestavov�na ve dvou pr�chodech. V~prvn�m pr�chodu se
vytvo�� boxy jednotliv�ch polo�ek zp�sobem popsan�m v��e, p�i�em� se na
tyto boxy neklade ��dn� po�adavek na sta�en� nebo rozta�en�. Pak \TeX{}
spo��t� maxim�ln� ���ku takov�ch box� v~ka�d�m sloupci polo�ek. Pro
$i$-t� sloupec budeme zna�it toto maximum znakem~$w_i$.

V~druh�m pr�chodu sestavuje \TeX{} jednotliv� ��dky tabulky tak, �e do
vn�j��ho vertik�ln�ho seznamu nejprve zavede <vertik�ln� materi�l>
sestaven� z~p��padn�ho |\noalign|, kter� byl hned za prvn�m |\cr|. D�le
vlo�� prvn� ��dek tabulky jako |\hbox| obsahuj�c�: \uv{$t_0$, box prvn�
polo�ky upraven� na ���ku $w_1$, d�le $t_1$, pak box druh� polo�ky
upraven� na ���ku $w_2$, $t_2$ atd. a� po box posledn� polo�ky upraven� na
���ku $w_n$ a kone�n� $t_n$}. Znaky $t_0$ a� $t_n$ zde znamenaj� v�pl�ky
typu <glue> odpov�daj�c� hodnot� |\tabskip| p�ed tabulkou, mezi polo�kami a
za tabulkou. Podrobn�ji o~nich viz n��e. T�m je prvn� ��dek tabulky
zaveden do vn�j��ho vertik�ln�ho seznamu. Pak se vlo�� do tohoto
seznamu p��padn� <vertik�ln� materi�l> z~|\noalign| uveden�ho za prvn�m
��dkem, pak se analogicky vlo�� |\hbox| s~druh�m ��dkem tabulky apod. Proto�e
jsou $t_0$ a� $t_n$ a $w_1$ a� $w_n$ v~ka�d�m ��dku stejn�, budou
jednotliv� polo�ky l�covat pod sebou.

P�i nov�m stanoven� ���ky boxu polo�ky na ���ku $w_i$ je potla�eno hl�en�
{\tt Underfull hbox}. M��e se tedy st�t, �e \TeX{} nap��klad vytvo�� 
{\it bez varov�n�\/} polo�ku s~obludn�mi mezislovn�mi mezerami.
Obvykle ale b�vaj� v~boxech polo�ek pru�n� v�pl�ky typu <glue>, kter�
jsou �asto specifikov�ny ve sch�matu polo�ky a kter�mi program�tor maker ��d�
zp�sob um�st�n� polo�ky. Nap��klad na ��dku~\lnr[defradku] je �e�eno, �e na
konci ka�d� polo�ky z~prvn�ho sloupce bude |\hfil|, tak�e polo�ky budou
zarovn�ny na levou zar�ku. V~druh�m sloupci je prom�nliv� text obehn�n
v�pl�kem |\hfil| z~obou stran, tak�e tento text se bude centrovat, zat�mco
opakovan� text \uv{konec} bude usazen p�esn� pod sebou. \endpar

{\subpar Registr |\tabskip|.}
Jak jsou stanoveny hodnoty mezisloupcov�ch v�pl�k� typu <glue> ozna�ovan�
v��e jako $t_0$ a� $t_n$\.? Tyto hodnoty se z�skaj� z~hodnoty registru
|\tabskip| v~dob� �ten� deklarace ��dku. V~na�em p��klad� na
��dku~\lnr[defradku] je tato hodnota rovna {\tt 2em plus 5em}, to znamen�,
�e $t_0$, $t_1$ i $t_2$ budou m�t tuto hodnotu. Primitiv |\halign| m��e
p�ed otev�rac� z�vorkou m�t ur�enu ���ku tabulky kl��ov�m slovem
{\tt to} nebo {\tt spread}, jak to zn�me ze specifikac� box�. Pokud je tato
specifikace uvedena, pak za�ne pracovat roztahovatelnost nebo
stahovatelnost p��slu�n�ch mezisloupcov�ch v�pl�k� $t_i$ tak, aby nap��klad
p�i |\halign|" to10cm{...}" byla celkov� ���ka ka�d�ho ��dku (a~t�m i cel�
tabulky)~10\,cm.

Zb�v� ot�zka, jak za��dit, aby se jednotliv� hodnoty $t_0$ a� $t_n$ od sebe
li�ily. K~tomu si budeme muset up�esnit algoritmus �ten� 
deklarace ��dku v~okam�iku, kdy \TeX{} zahajuje zpracov�n� |\halign|.
P�i tomto �ten� se {\it neprov�d� expanze\/} a jednotliv� �ady token�
odpov�daj�c� jednotliv�m sch�mat�m polo�ek si \TeX{} uchov�v� ve vyhrazen�
pam�ti pro pou�it� p�i pozd�j��m �ten� datov� ��sti.
P�i �ten� deklarace ��dku si \TeX{}
speci�ln�m zp�sobem v��m� pouze t�chto token�: "\cr" pro konec �ten�
deklarace ��dku, "&" pro odd�len� jednotliv�ch sch�mat polo�ek (token
kategorie 4), "#" pro m�sto, kam vlo�it prom�nliv� text polo�ky (token
kategorie 6), |\tabskip| pro zm�nu registru |\tabskip| mezi jednotliv�mi
polo�kami a kone�n� |\span|\pgl[spantoken]\inl[span], pokud je nutno
n�sleduj�c� token v~tuto chv�li expandovat. Za tokenem |\tabskip| v�jime�n�
prob�h� expanze tak dlouho, a� hlavn� procesor z�sk� celou hodnotu podle
syntaktick�ho pravidla <glue>, kterou p�i�ad� do registru. Cel� ��st tvaru
|\tabskip|<equals><glue> je ze sch�matu polo�ky vyhozena jako zbyte�n�.
Nicm�n� vnit�n� registr |\tabskip| u� byl zm�n�n a o~to �lo. Hodnota $t_0$
je pak rovna hodnot� |\tabskip| v~okam�iku vstupu do konstrukce |\halign| a
hodnota $t_i$ je rovna hodnot� |\tabskip| v~okam�iku ukon�en� �ten�
$i$-t�ho sch�matu polo�ky.  Uvedeme si p��klad:

\beguk Parametr \tabskip v \halign
\tabskip=0pt % to je sice implicitn�, ale jistota je jistota.
        % (pro tyto ��ely lze pou��t zkratku v plainu: \ialign)
\halign to\hsize{\tabskip=0pt plus1fil       #\hfil
                &\tabskip=0pt          \hfil #\hfil \cr
   toto bude  & a toto bude zase\cr
   vlevo      & vpravo\cr
   na str�nce & na str�nce\cr}
\enduk

Uveden� k�d n�m d�:
\bigskip

\tabskip=0pt % to je sice implicitn�, ale jistota je jistota.
\halign to\hsize{\tabskip=0pt plus1fil       #\hfil
                &\tabskip=0pt          \hfil #\hfil \cr
   toto bude  & a toto bude zase\cr
   vlevo      & vpravo\cr
   na str�nce & na str�nce\cr}

V tomto p��klad� je $t_0${\tt=0pt}, $t_1${\tt=0pt plus1fil} a
$t_2${\tt=0pt}. Poznamenejme, �e po sestaven� tabulky se hodnota |\tabskip|
vrac� do hodnoty $t_0$, proto�e v�echny ostatn� zm�ny tohoto registru
prob�hly lok�ln� v~r�mci skupiny |\halign|"{...}". \endpar

Uvedeme si n�kolik p��klad�, kter� jsou zaj�mav�m d�sledkem skute�nosti, �e
v~dob� �ten� deklarace ��dku se neprov�d� expanze. Chceme za�adit
pod sebe desetinn� ��sla, aby byla zarovn�na podle desetinn� ��rky:

\beguk Desetinn� ��rky budou pod sebou
\halign{\catcode`\,=4\hfil #,&#\hfil &\quad --- #\hfil \cr !inl[licuj]
  127,34    & tady je text, kde ��rka nevad� \cr
    3,1415  & vid�me, �e ��sla maj� ��rku pod sebou \cr}
\enduk

A~na v�stupu skute�n� m�me:

$$
\vbox{\halign{\catcode`\,=4\hfil #,&#\hfil &\quad --- #\hfil \cr
  127,34    & tady je text, kde ��rka nevad� \cr
    3,1415  & vid�me, �e ��sla maj� ��rku pod sebou \cr}}
$$

Uk�eme si, jak to funguje. P�i �ten� deklarace ��dku se
do prvn�ho sch�matu ulo��

\beguk
!krab[catcode].!krab[`]12.!krab[,].!krab[=]12.!krab[4]12.!krab[hfil].!krab[#]6.!krab[,]12.
\enduk

��rka m� ve sch�matu kategorii 12, proto�e se zat�m neprovedlo
p�i�azen� |\catcode|. K~tomuto p�i�azen� dojde, a� \TeX{} otev�e |\hbox|
prvn� polo�ky a zpracuje uvedenou sadu token� ze sch�matu. Proto
u�ivatelova ��rka v~datov� oblasti m� stejnou funkci, jako separ�tor mezi
polo�kami. Prvn� polo�ka m� tedy prom�nliv� text \uv{{\tt 127}} a druh�
\uv{{\tt 34}}. Dal�� ��rky uveden� ve t�et� polo�ce (a~p��padn� i ve druh�)
u� maj� zase kategorii 12, proto�e se uzav�en�m boxu prvn� polo�ky ukon�ila
skupina.

Stejn� v�sledek bez zm�ny kategori� m��eme dos�hnout t� n�sleduj�c�m
trikem:

\beguk Desetinn� ��rky budou pod sebou, jin� �e�en�
\def\cislo#1,{#1,&}
\halign{\hfil\cislo#&#\hfil &\quad --- #\hfil \cr
  127,34    & tady je text, kde ��rka nevad� \cr
    3,1415  & vid�me, �e ��sla maj� ��rku pod sebou \cr}
\enduk

Makro "\cislo" bude expandovat a� p�i sestavov�n� polo�ky a
nikoli v~dob� na��t�n� deklarace ��dku. \endpar

V~dal��m p��klad� budeme ve sch�matu polo�ky znovu p�ep�nat kategorie a
umo�n�me u�ivateli ps�t v~rovnic�ch pouze znak {\tt =}, kter� bude zarovn�n
pod sebou. Nepot�ebujeme pou��vat \LaTeX{}ovsk� konstrukce typu
"&=&". P��klad n�sleduje i s~uk�zkou, jak to dopadne, ov�em u� bez
vysv�tlov�n�. V�imn�te si, �e je zde pou�ita smy�ka v~deklaraci ��dku
(p��znak n�vratu m� prvn� sch�ma), tak�e u�ivatel m��e ps�t vedle sebe
libovoln� mno�stv� rovnic (pokud se mu ov�em vejdou na ��dek).

\beguk Znak "=" jako odd�lova� v tabulce
\let\eq== \thickmuskip=10mu % aby kolem bin.rel. bylo v�ce m�sta!inl[rovnice]
$$\vbox{\halign{&\catcode`\==4 \hfil$#$&${}=#$\hfil\qquad\cr
      z^2 =  x^2+y^2      & a+b    = c+d+e          & \sigma\cr
\sum_{i\eq0}^\infty x_i=T & \alpha = \beta = \gamma & \tau \cr}}
$$
\enduk

\bigskip
\hbox to\hsize{\hfil
\let\eq== \thickmuskip=10mu
\vbox{\halign{&\catcode`\==4 \hfil$#$&${}=#$\hfil\qquad\cr
        z^2 =  x^2+y^2      & a+b    = c+d+e          & \sigma \cr
\sum_{i\eq0}^\infty x_i = T & \alpha = \beta = \gamma & \tau   \cr}}
\hfil}

Vid�me, �e ka�d� legrace n�co stoj�. Nemus�me sice ps�t "&=&", zato ale
v~p��pad� pot�eby symbolu {\tt=} v~jin�m
smyslu, ne� pro zarovn�n� (viz index sumy), mus�me pou��t n�hradn� symbol.
Zde jsme zavedli symbol "\eq". Kdybychom pou�ili �e�en� bez zm�ny kategorie
(podobn� jako v~p��klad� se zarovn�v�n�m podle desetinn� ��rky), pak m��eme
ps�t i "\sum_{i=0}". Zase ale budeme m�t probl�my se sloupcem "\sigma" a
"\tau". \endpar

{\subpar P��klad na automatick� generov�n� sch�mat polo�ek.}\inl[genschema]
V~tomto p��klad� uk�eme makra, kter� umo�n� jist� pohodl� p�i
zad�v�n� matic. U�ivatel nap��e:

\beguk
$$\matice{cc|r}{1&p& -1\\ p-1&2& 0} \sim
  \matice{cc|c}{1&p& -1\\ 0&(p-2)(p+1)& 1-p}. $$
\enduk

a na v�stupu dostane:

\begingroup
\catcode`\|=12
\newtoks\schemata \newdimen\tbs
\def\addschema#1{\schemata\expandafter{\the\schemata#1}}
\def\addseparator{\ifx\params\empty \else \addschema&\fi}
\def\vemznak#1#2;{\def\params{#2}\csname P:#1\endcsname}
\expandafter\def\csname P:c\endcsname{%
   \addschema{\hfil$##$\hfil}\addseparator}
\expandafter\def\csname P:r\endcsname{%
   \addschema{\hfil$##$}\addseparator}
\expandafter\def\csname P:|\endcsname{%
   \addschema{\vrule\hskip2\tbs}}
\def\genschemata{\ifx\params\empty
   \else\expandafter\vemznak\params;\expandafter\genschemata\fi}
\tbs=.4em  \let\\=\cr
\def\matice#1#2{\left(\vcenter{\offinterlineskip
   \schemata={\tabskip=2\tbs \strut}
   \def\params{#1}\genschemata \tabskip=\tbs
   \halign{\span\the\schemata \tabskip=\tbs \cr #2\crcr}}\right)}
$$\matice{cc|r}{1&p& -1\\ p-1&2& 0} \sim
  \matice{cc|c}{1&p& -1\\ 0&(p-2)(p+1)& 1-p}. $$
\endgroup

Vid�me, �e u�ivatel stanov� v~jednoduch� hlavi�ce vlastnosti sloupc�
({\tt c}:~centruj, {\tt r}:~zarovnej doprava a {\tt\char`\|}: nakresli
svislou ��ru). To zn�me z~\LaTeX{}u. Na��m �kolem bude p�e��st tyto �daje a
vygenerovat odpov�daj�c� sch�ma pro |\halign|. Navrhneme proto n�sleduj�c�
makro:

\beguk Automatick� generov�n� sch�mat polo�ek pro \halign
\newtoks\schemata \newdimen\tbs
\def\addschema#1{\schemata\expandafter{\the\schemata#1}}
\def\addseparator{\ifx\params\empty \else \addschema&\fi}
\def\vemznak#1#2;{\def\params{#2}\csname P:#1\endcsname} !lnl[vemznak]
\expandafter\def\csname P:c\endcsname{%
   \addschema{\hfil$##$\hfil}\addseparator}
\expandafter\def\csname P:r\endcsname{%
   \addschema{\hfil$##$}\addseparator}
\expandafter\def\csname P:|\endcsname{%
   \addschema{\vrule\hskip2\tbs}}
\def\genschemata{\ifx\params\empty
   \else\expandafter\vemznak\params;\expandafter\genschemata\fi}
\tbs=.4em  \let\\=\cr  !lnl[tbs]
\def\matice#1#2{\left(\vcenter{\offinterlineskip
   \schemata={\tabskip=2\tbs \strut} !lnl[prvnischema]
   \def\params{#1}\genschemata \tabskip=\tbs
   \halign{\span\the\schemata \tabskip=\tbs \cr #2\crcr}}\right)}!lnl[uzijschema]
\enduk

<Deklaraci ��dku> pro |\halign| postupn� vytvo��me v~prom�nn� "\schemata".
P�itom u�ivatelovy parametry m�me v~makru "\params". Pomocn� makro
"\addschema" p�id� do prom�nn� "\schemata" co pot�ebujeme a "\addseparator"
p�id� odd�lova� \krab[\&]4.. Makro "\vemznak" z~��dku~\lnr[vemznak] vezme
z~parametr� "\params" dal�� znak a expanduje na \krab[P:<znak>].. Pr�v�
tato makra ud�laj� pot�ebnou pr�ci; nap��klad \krab[P:c]. p�id� do prom�nn�
"\schemata" text:~\uv{"\hfil$#$\hfil&"}.

Makro "\genschemata" opakovan� bere token z~"\params" a p�id�v�
odpov�daj�c� �seky do prom�nn� "\schemata". Na ��dku~\lnr[uzijschema]
je obsah prom�nn� "\schemata" pou�it primitivem "\halign".
V�choz� hodnota t�to prom�nn� (��dek~\lnr[prvnischema]) obsahuje vertik�ln�
podp�ru (|\strut|), proto�e jednotliv� ��dky budou na sebe t�sn�
navazovat. Zm�nou definice |\strut| m��eme zm�nit ��dkov�n� v~matici.
Kone�n� zm�nou �daje "\tbs" (��dek~\lnr[tbs]) m�n�me polovi�n�
vzd�lenost mezi sloupci. Registr |\tabskip| je toti� na okraj�ch matice
roven "\tbs" a mezi sloupci m� hodnotu "2\tbs". \endpar

{\subpar V�jimky z pravidel dan�ch sch�maty polo�ek.}
V~datov� ��sti pot�ebujeme ob�as
vlo�it polo�ku, kter� nepodl�h� form�tov�n� podle sch�matu polo�ky.
V~jednoduch�ch p��padech sta��, kdy� do m�sta polo�ky vlo��me v�pln�k typu
<glue>, kter� spolupracuje s~v�pl�ky, pou�it�mi ve sch�matu polo�ky.
Nap��klad, pokud ve sch�matu polo�ky m�me zarovn�v�n� nalevo implementov�no
jako "#\hfil", pak polo�ka |\hfil|" A" bude v�jime�n� centrovan� a polo�ka
|\hfill|" A" n�m odcestuje doprava.

Mocn�j��m n�strojem je primitiv |\omit|, kter� mus� po expanzi prom�nliv�
��sti polo�ky p�ich�zet (po ignorov�n� mezer) jako prvn�. Pokud je tomu
tak, pak se box polo�ky vypln� pouze materi�lem z~datov� ��sti a
odpov�daj�c� sch�ma polo�ky je ignorov�no.

Nejmocn�j��m n�strojem je primitiv |\span|.\inl[span]
S~n�m jsme se u� setkali p�i
v�kladu zp�sobu �ten� sch�mat polo�ek na stran�~\pgr[spantoken]. Jeho
v�skyt v~datov� ��sti |\halign| m� ale docela jin� (a~pro n�s podstatn�
zaj�mav�j��) v�znam. Sekvence |\span| zde m��e nahradit libovoln� separ�tor
typu "&". Tiskov� materi�l pro sousedn� polo�ky spojen� primitivem |\span|
pak m� spole�n� sd�len� box. V~p��pad�, �e nen� pou�it |\omit|, obsahuje
materi�l spole�n�ho boxu nejen datovou ��st polo�ek, ale i sch�mata
p��slu�n�ch polo�ek. B�v� obvykl� spojit |\span| s~|\omit|. Nap��klad:

\beguk
.. & \omit \span \omit \span \omit Tento text obsazuje prostor
 t�� za sebou jdouc�ch polo�ek, jsou ignorov�na sch�mata& ..\cr
\enduk

M�sto |\omit||\span|"...\omit" lze pou��t stru�n�j�� z�pis pomoc� makra
plainu |\multispan| (viz ��st~B).

\TeX{} m��e m�t jist� pot��e vlo�it materi�l polo�ky vytvo�en� pomoc�
|\span| do struktury box� zarovnan�ch pod sebou o~���k�ch
$w_1$ a� $w_n$. P�edpokl�dejme nap��klad, �e materi�l ze |\span| nahrazuje
polo�ky druh�ho a� �tvrt�ho sloupce, tedy nahrazuje boxy o~���k�ch $w_2$,
$w_3$ a $w_4$. D�le nech� $g_2$ a $g_3$ jsou z�kladn� rozm�ry (tj. bez
rozta�en� a stla�en�) z~|\tabskip| bran� z~hodnot $t_2$ a $t_3$.
Spo��tejme si ���ku m�sta, kam by m�l b�t vlo�en box s~materi�lem ze
|\span| v~na�em p��klad� (polo�ky 2 a� 4):

$$ W = w_2 + g_2 + w_3 + g_3 + w_4 $$

Pokud p�irozen� ���ka boxu s~materi�lem z~na�eho |\span|
je men�� nebo rovna hodnot� $W$, pak se do v�sledn�ho ��dku tabulky
za�ad� tento box, ale p�epo��t�n na ���ku~$W$ (pracuj� pru�n� v�pl�ky
uvnit� boxu). Tento box nahrazuje v~��dku tabulky obvykl� materi�l typu: 
\uv{box $w_2$, $t_2$, box $w_3$, $t_3$ a box $w_4$}. 
Pokud d�le dojde ke stla�en� �i rozta�en�
v�pl�k� |\tabskip| v~m�st� $t_2$ a $t_3$ (proto�e je pou�it |\halign|" to"
nebo |\halign|" spread"), pak se dodate�n� uprav� nov� ���ka na�eho boxu ze
|\span| a ke slovu se znovu dostanou pru�n� v�pl�ky uvnit� tohoto boxu.

V��e popsan� chov�n� je v~souladu s~t�m, co od konstrukc� |\span|
m��eme o�ek�vat. Probl�my ov�em nast�vaj�, pokud p�irozen� ���ka materi�lu
ze |\span| je {\it v�t��\/} ne� rozm�r $W$.\pgl[wnasili]
Pak toti� dojde k~nejhor��mu a \TeX{} zv�t�� n�jakou hodnotu $w_i$ tak, aby
rozm�r $W$ byl roven p�irozen� ���ce materi�lu ze |\span|. Zjistit, na
kter�m sloupci bude toto ukrutn� n�sil� provedeno, je mo�n� prostudov�n�m
pom�rn� slo�it�ho algoritmu z~\TeX{}booku ze strany 245.\inl[texbook]
V�t�inou n�s to
ale neuklidn�, proto�e ten sloupec obvykle za nic nem��e.
\TeX{} prov�d� popsanou zm�nu hodnoty $w_i$ d��ve, ne� za�ne vkl�dat
prvn� ��dek tabulky do v�sledn�ho vertik�ln�ho seznamu. T�m nen� naru�en
z�kladn� po�adavek, aby polo�ky jednotliv�ch sloupc� l�covaly pod sebou.
S~probl�mem se je�t� setk�me n��e v~na�ich uk�zk�ch. \endpar

{\subpar �ten�, expanze a zpracov�n� polo�ek v~datov� ��sti.}
Ne� \TeX{} za�ne expandovat prvn� ��st sch�matu
polo�ky, vy��d� si z~datov� ��sti polo�ky (po p�esko�en� mezer) jeden
token od expand procesoru. Z~tohoto tokenu se m��e vyklubat (po
expanzi) |\omit| nebo |\noalign|. V~takov�m p��pad� v�me, �e se \TeX{}
bude chovat jinak.  Pokud se tak nestalo, \TeX{} za�ne expandovat a
v~hlavn�m procesoru prov�d�t prvn� ��st sch�matu, pak nav�e na ji�
expandovan� token z~datov� ��sti a d�le se pust� do �ten� a expanze
p��padn�ho dal��ho obsahu polo�ky.

Jakmile se p�i zpracov�n� datov� ��sti polo�ky objev� token kategorie
4 nebo |\cr| nebo |\span|, \TeX{} {\it okam�it�\/} nahrad� tento token
druhou ��st� sch�matu.  K~t�to ud�losti
m��e doj�t na r�zn�ch �rovn�ch zpracov�n� vstupn� informace. Nap��klad
pokud se makro v~datov� ��sti polo�ky expanduje na token \krab[\&]4., pak
\TeX{} p�ejde k~druh� ��sti sch�matu po expanzi tohoto makra.
Pokud je ale na��t�n text parametru makra a v~tomto textu se
vyskytne \krab[\&]4., pak je u� v~pr�b�hu na��t�n� parametru provedena
z�m�na za druhou ��st sch�matu a �ten� parametru pokra�uje z~druh� ��sti
sch�matu. Do parametru tedy token \krab[\&]4. nevstupuje. Tuto skute�nost
ilustrujeme na p��klad�:

\beguk Ilustrace expanze sch�mat a datov�ch ��st� tabulky
\def\a#1\zarazka{\message{#1}} \let\zarazka=\relax
\halign{\a X#Y\zarazka & #Z\zarazka\cr
  abc& de\cr
  fgh& i\a jkl\cr
  mno& \a pqr\cr
  stu& xyz\cr}
\enduk

Prvn� sloupec je bezprobl�mov�. Tam se p�i �ten� parametru makra "\a"
(zapsan�ho v~prvn� ��sti sch�matu) 
plynule p�ejde na datovou ��st polo�ky a po dosa�en� tokenu
\krab[\&]4. zp�t na druhou ��st sch�matu. 
Tak�e do parametru "#1" vstupuje nap��klad z~prvn�ho ��dku 
text \uv{{\tt XabcY}}.
Druh� sloupec je podstatn� zaj�mav�j��. V~prvn�m ��dku druh�ho sloupce se
je�t� ned�je nic neobvykl�ho a "\zarazka" ve sch�matu pracuje jako |\relax|.
V~druh�m ��dku druh�ho sloupce se p�i na��t�n� parametru makra "\a" prom�n�
token |\cr| v~druhou ��st sch�matu, tak�e do "#1" vstupuje \uv{{\tt jklZ}}.
Ve t�et�m ��dku druh�ho sloupce n�m to havaruje. Je to t�m, �e prvn�
token z~datov� ��sti (v~tomto p��pad� se jedn� o makro "\a") 
je expandov�n d��v, ne� v�bec za�ne zpracov�n�
polo�ky. V~t� chv�li je�t� nen� |\cr| ani \krab[\&]4. nijak
interpretov�no. Do parametru "#1" se tedy dost�v� "pqr\cr stu& xyz\cr}"
a obdr��me chybu {\tt Argument of "\a" has an extra~"}"}. Abychom tento
probl�m odstranili, definujme makro "\a" jinak:

\beguk
\def\a{\relax\A} \def\A#1\zarazka{\message{#1}} !endpar
\enduk

P�i na��t�n� parametru makra v datov� ��sti polo�ky se p�i v�skytu "&" nebo
"\cr" provede p�echod do z�v�re�n� ��sti sch�matu polo�ky jen
za podm�nky, �e se nezpracov�v� vno�en� skupina. Smysl
t�to dodate�n� podm�nky osv�tl� p��klad:

\beguk Zna�ky & a \cr v parametrech maker
$$\matrix{\pmatrix{1&2\cr 3&4}\cr \pmatrix{5\cr 6}}$$
%                   ^  ^   ^                 ^
% Ozna�en� "&" a "\cr" neukon�� polo�ku vn�j�� \matrix, proto�e
% uvnit� skupiny je potla�eno ukon�en� �ten� polo�ky.
\enduk

Vid�me, �e d�ky potla�en� konce polo�ky uvnit� skupiny je mo�no
jako text parametru makra |\pmatrix| zav�st \uv{"1&2\cr 3&4"}. Lze tedy
ps�t vno�en� tabulky typu |\halign| i prost�ednictv�m maker, kter� si do
parametru na�tou datovou ��st v�ech polo�ek sou�asn�.
V~na�em p��klad� je takov�m makrem |\pmatrix| z~plainu. \endpar

{\subpar Tabulky s linkami |\vrule|, |\hrule|.}
V~z�v�ru t�to sekce se zam���me na zp�soby, jak�mi se do
tabulek |\halign| zav�d�j� linky. Uvid�me, �e v�c nen� na prvn�
pohled v�bec jednoduch�. Dovednost vytv��et takov� tabulky je prvn�m
stupn�m um�n� makrojazyka \TeX{}u. Vrcholn�m um�n�m pak je dovednost
vytv��et makra tvo��c� rozhran� mezi primitivem |\halign| a u�ivatelem,
kter� nechce nebo nem��e p�em��let v~ka\-te\-go\-ri�ch \uv{box, kern,
glue}. P��kladem takov�ho um�n� je makro pro prost�ed� "tabular"
v~\LaTeX{}u nebo je�t� propracovan�j�� makra pro tabulky od Michaela
Spivaka.

Nejprve uvedeme pravidla, podle kter�ch \TeX{} zach�z� s~linkami
|\hrule| a |\vrule| p�i sestavov�n� tabulky. Pokud se v~boxech polo�ek
vyskytovaly v~prvn� hladin� (tj. nikoli uvnit� dal��ch box�) linky
|\vrule| s~neur�itou v��kou nebo hloubkou, jsou tyto �daje dopo��t�ny na
v��ku a hloubku ��dku tabulky jako celku.

Pokud se vyskytovaly ve <vertik�ln�m materi�lu> z~|\noalign| linky
|\hrule| s~neur�itou ���kou, pak po kompletaci tabulky z�skaj� tyto linky
definitivn� ���ku rovnou ���ce tabulky a dal��mu p��padn�mu prodlu�ov�n� do
���ky vn�j��ho |\vbox|u nepodl�haj�. \endpar

Svisl� linky se v�t�inou do tabulek za�azuj� jako |\vrule| uvnit�
sch�mat polo�ek. Vodorovn� linky se do tabulek obvykle vkl�daj� pomoc�
|\noalign|"{\hrule}". To n�m ov�em zcela rozhod� ��dkov�n�~--- viz n� prvn�
p��klad na stran�~\pgr[prvnitab]. Vkl�dat do |\noalign| je�t� dal�� mezery
(jako ve zm�n�n�m prvn�m p��klad�, ��dek~\lnr[mezerypol]) nen� vhodn�
�e�en�, proto�e bychom nem�li napojeny vertik�ln� linky nad sebou
vytvo�en� v~jednotliv�ch polo�k�ch pomoc� |\vrule|. Z~tohoto d�vodu je
bezpodm�ne�n� nutn� pou��t p�i sazb� tabulek s~��rami makro
|\offinterlineskip|, kter� nastavuje |\baselineskip| na nulu a d�le je
nutno vypodlo�it ka�d� ��dek tabulky neviditelnou podp�rou typu |\strut|.
Takovou podp�ru za�ad�me do sch�matu n�kter� polo�ky. Bez t�to podp�ry
bychom m�li ��dky tabulky (1) velmi n�zk�, (2) byly by p�ilepeny jeden na
druh� a (3) nebyly by stejn� vysok�. \endpar

Tabulka vytvo�en� pomoc� |\halign| m��e b�t zlomena \uv{v~p�li}
str�nkov�m zlomem. Je to z~toho d�vodu, �e v�sledek pr�ce |\halign| jsou
jednotliv� ��dky vkl�dan� do vertik�ln�ho seznamu, p�i�em� tyto ��dky maj�
mezi sebou <glue> z~|\baselineskip| nebo z~|\lineskip|.
V~t�chto m�stech m��e doj�t ke str�nkov�mu zlomu. Abychom tomu zabr�nili,
d�me obvykle celou tabulku do |\vbox|u.

Jestli�e vkl�d�me za ka�d� ��dek "\noalign{\hrule}", tabulka se nikdy
nezlom�. V~takov�m p��pad� toti� mezi ��dky chyb� zm�n�n� v�pln�k <glue>, ve
kter�m by se mohla tabulka zlomit. Chceme-li dovolit str�nkov� zlom, pi�me
t�eba |\noalign|"{"|\hrule||\penalty|"50}".
%
Pokud dovol�me str�nkov� zlom uvnit� tabulky, m�me vodorovnou ��ru obvykle
za posledn�m ��dkem p�edchoz� strany, ale u� ne nad prvn�m ��dkem strany
n�sleduj�c�. A~u� v�bec se n�m na n�sleduj�c� stran� neopakuje hlavi�ka.
�e�en� tohoto probl�mu uv�d�me na jin�m m�st� t�to knihy (viz
sekci p��klad� v�stupn�ch rutin~\rsec[exoutput], strana~\pgr[longtable]).
\endpar

P�jdeme rovnou na v�c a uk�eme si sazbu tabulky s~jednoduch�mi i dvojit�mi
linkami.

$$
\vbox\bgroup\offinterlineskip
\def\vvrule{\vrule \kern1.4pt \vrule}
\def\\{\crcr\omit\vvrule\hrulefill\vvrule&
            \multispan2\hrulefill\vvrule\cr}
\def\vkern{\multispan3\vrule height1.2pt \hfil \vrule}
\def\strut{\vrule height11pt depth 5pt width0pt }
\halign {\vvrule\quad#\hfil\quad\vvrule &\quad\hfil#\quad\vrule
       &\quad\hfil#\quad\vvrule\strut \cr  % konec deklarace
\noalign{\hrule} \vkern\\
& % prvn� polo�ka (vlevo od "Prodej zbo��") je pr�zdn�
\multispan2\hfil\quad\bf Prodej zbo��\quad\hfil \vvrule\strut\cr
\hfil\vbox to0pt{\vss\hbox{\bf M�s�c}\vss}%
        &\multispan2\hrulefill \vvrule\cr
% Vlastn� data -------------------
           & \bf A\hfil & \bf B\hfil \\ \vkern\\
% --------------------------------
    Leden  &         865&    16\\
    �nor   &         917&     8\\
    B�ezen &        1036&    18\\
\vkern\cr\noalign{\hrule}}\egroup \pgl[linkytab]
$$

Tato tabulka byla vytvo�ena takto:

\beguk Uk�zka tabulky s ��rami
\bgroup\offinterlineskip !inl[carovatab]
\def\vvrule{\vrule \kern1.4pt \vrule}
\def\\{\crcr\omit\vvrule\hrulefill\vvrule&
            \multispan2\hrulefill\vvrule\cr}
\def\vkern{\multispan3\vrule height1.2pt \hfil \vrule}
\def\strut{\vrule height11pt depth 5pt width0pt }
\halign {\vvrule\quad#\hfil\quad\vvrule &\quad\hfil#\quad\vrule
       &\quad\hfil#\quad\vvrule\strut \cr  % konec deklarace
\noalign{\hrule} \vkern\\
& % prvn� polo�ka (vlevo od "Prodej zbo��") je pr�zdn�
\multispan2\hfil\quad\bf Prodej zbo��\quad\hfil \vvrule\strut\cr!lnl[vvrulecr]
\hfil\vbox to0pt{\vss\hbox{\bf M�s�c}\vss}%
        &\multispan2\hrulefill \vvrule\cr
% Vlastn� data -------------------
           & \bf A\hfil & \bf B\hfil \\ \vkern\\
% --------------------------------
    Leden  &         865&    16\\
    �nor   &         917&     8\\
    B�ezen &        1036&    18\\
\vkern\cr\noalign{\hrule}}\egroup
\enduk

Makro "\vvrule" je pou�ito pro dvojitou vertik�ln� linku, kter� je v ka�d�m
��dku tabulky pou�ita vlevo, vpravo a mezi prvn�m a druh�m sloupcem.
Za pozornost stoj� makro "\\", kter� ukon�� ��dek a vytvo�� pod n�m
horizont�ln� linku. Tato linka nen� vedena p�es celou ���ku tabulky~--- to
by sta�ilo pou��t "\cr\noalign{\hrule}". M�sto toho je horizont�ln� linka
p�eru�ena v m�st� dvojit�ch vertik�ln�ch �ar. Proto je definov�na jako
samostatn� ��dek tabulky, ve kter�m je vodorovn� ��ra vykreslena po �sec�ch
jako |\hrulefill|. V�imneme si, �e tento ��dek tabulky m� v��ku pouze
0,4\,pt, tak�e makra "\vvrule", kter� jsou v n�m pou�ita, vykresl� jen
miniaturn� �tvere�ky. Makro "\vkern" pou�ijeme pro mezeru ve dvojit�ch
horizont�ln�ch link�ch. Zde po�adujeme, aby se nakreslily krati�k�
vertik�ln� linky na lev�m a prav�m okraji tabulky a nic v�c. Kone�n�
"\strut" vytv��� neviditelnou podp�ru v~ka�d�m ��dku a volbou v��ky a
hloubky t�to podp�ry regulujeme velikosti v�ech ��dk� tabulky.

Vlastn� tabulka se skl�d� ze t�� sloupc�. Ke sch�mat�m polo�ek jednotliv�ch
sloupc� asi nen� co dodat. Pon�kud komplikovan�j�� je ov�em sazba z�hlav�,
proto�e zde m�me m�n� standardn� strukturu, kter� nen� p��mo implementov�na
do |\halign|. Z�hlav� sest�v� ze t�� ��dk�, a�koli �ten�� vys�zen� tabulky
vid� ��dky dva. V~prvn�m ��dku je sloupec \uv{M�s�c} pr�zdn� a text
\uv{Prodej zbo��} je zaveden jako |\span| p�es dva n�sleduj�c� sloupce.
Proto�e v~pou�it�m |\multispan| je skryto i |\omit|, je pot�eba postarat se
ru�n� o~koncov� "\vvrule\strut", viz ��dek~\lnr[vvrulecr] v~k�du. Druh�
��dek tabulky m� pouze v��ku vodorovn� linky (tj.~0,4\,pt) a obsahuje
v~prvn� polo�ce text \uv{M�s�c} centrovan� vertik�ln� na st�ed tohoto
��dku. Dal�� dv� polo�ky tohoto ��dku jsou vypln�ny jako |\span| obsahuj�c�
natahovac� vodorovnou linku |\hrulefill|. Tento trik u� zn�me z~makra~"\\".
Na t�et�m ��dku tabulky je znovu p�esko�ena oblast \uv{M�s�c} a pokra�uje
z�hlav� A~a~B. Pak u� n�sleduj� data zapsan� b�n�m zp�sobem.

Zkus�me nyn� nat�hnout tabulku na ���ku sazby, tak�e pi�me
|\halign|{\tt~to}|\hsize|. Hodnoty $t_0$ a $t_n$ nech�me
nulov�, zat�mco ostatn� hodnoty |\tabskip| mezi jednotliv�mi sloupci budou
natahovac�. Pokud to ud�l�me bez dal�� �pravy, do�k�me se nep��jemn�ho
v�sledku: \bigskip

\vbox\bgroup\offinterlineskip
\def\vvrule{\vrule \kern1.4pt \vrule}
\def\\{\crcr\omit\vvrule\hrulefill\vvrule&
            \multispan2\hrulefill\vvrule\cr}
\def\vkern{\multispan3\vrule height1.2pt \hfil \vrule}
\def\strut{\vrule height11pt depth 5pt width0pt }
\halign to\hsize{\tabskip=0pt plus 1fil\vvrule\quad#\hfil\quad\vvrule
       &\quad\hfil#\quad\vrule
       &\quad\hfil#\quad\vvrule\strut\tabskip=0pt \cr  % konec deklarace
\noalign{\hrule} \vkern\\
& % prvn� polo�ka (vlevo od "Prodej zbo��") je pr�zdn�
\multispan2\hfil\quad\bf Prodej zbo��\quad\hfil \vvrule\strut\cr
\hfil\vbox to0pt{\vss\hbox{\bf M�s�c}\vss}%
        &\multispan2\hrulefill \vvrule\cr
% Vlastn� data -------------------
           & \bf A\hfil & \bf B\hfil \\ \vkern\\
% --------------------------------
    Leden  &         865&    16\\
    �nor   &         917&     8\\
    B�ezen &        1036&    18\\
\vkern\cr\noalign{\hrule}}\egroup

Vid�me, �e n�kter� ��ry kreslen� pomoc� |\hrulefill| n�m nezasahuj� do
prostoru, ve kter�m pru�� |\tabskip|. D�le ���e prvn�ho sloupce z�stala
stejn�, zat�mco ostatn� sloupce se vizu�ln� prot�hly. �ten�� si s�m
rozmysl�, pro� se tak stalo.

Abychom p�ekonali tento probl�m, mus�me vnit�n� koncepci na�� tabulky zcela
p�epracovat. M�sto t�� sloupc� budeme pracovat s~osmi sloupci podle
n�sleduj�c�ho n��rtu:

$$
\vbox{\halign{&\hbox to2em{\hss#\unskip\hss}\cr
& 1.      && 2.    && 3.&& 4.      && 5.&& 6.      && 7.&& 8.      &\cr
& $\Vert$ && M�s�c &&   && $\Vert$ && A && $\vert$ && B && $\Vert$ &\cr
0   &&   hfil  && hfil  &&  0 &&hfil&&hfil &&  hfil  && hfil &&   0 \cr}}
$$

V prvn�m ��dku tohoto n��rtu je vyzna�eno ��slo sloupce, ve druh�m
je zakreslen charakteristick� obsah odpov�daj�c�ho sloupce a ve t�et�m ��dku
jsou uvedeny velikosti |\tabskip| mezi jednotliv�mi sloupci. Vid�me, �e
vlastn� data budeme zapisovat do druh�ho, p�t�ho a sedm�ho sloupce.
V~prvn�m, �tvrt�m a osm�m sloupci bude kreslena dvojit� vertik�ln� ��ra a
v~�est�m sloupci ��ra jednoduch�. Ve t�et�m sloupci nebude nikdy kresleno
nic~--- tento sloupec bude pou�it jako z�chytn� bod pro horizont�ln� linky
|\hrulefill|. Tyto linky budou toti� v~m�st� \uv{M�s�c} implementov�ny jako
|\span| p�es 1.~a� 3.~polo�ku a v~m�st� \uv{Prodej zbo��} budou kresleny
pomoc� |\span| p�es 4.~a�~8.~polo�ku. Takto definovan� linky budou
obsahovat v�echny pru�n� ��sti tabulky, poch�zej�c�
z~mezisloupcov�ch~|\tabskip| a budou se tedy spr�vn�m zp�sobem natahovat.
Makro pro na�i tabulku nyn� vypad� takto:

\beguk Tabulka pracuj�c� i s pru�n�m \tabskip
\bgroup\offinterlineskip !lnl[beghalign]!inl[tabskipcary]
\def\vvrule{\vrule \kern1.4pt \vrule}
\def\\{\crcr\multispan3\vvrule\hrulefill&
            \multispan5\vvrule\hrulefill\vvrule\cr}
\def\vkern{\multispan8\vrule height1.2pt \hfil \vrule}
\def\strut{\vrule height11pt depth 5pt width0pt }
\halign to\hsize{\tabskip=0pt plus 1fil\vvrule#&\quad#\hfil\quad
   &\tabskip=0pt#&\vvrule#\tabskip=0pt plus1fil&\quad\hfil#\quad
   &\vrule#&\quad\hfil#\quad &\vvrule#\strut\tabskip=0pt\cr
\noalign{\hrule} \vkern\\
&&&&\multispan3\hfil\quad\bf Prodej zbo��\quad\hfil &\cr !lnl[zbo��]
&\hfil\vbox to0pt{\vss\hbox{\bf M�s�c}\vss}%
        &&\multispan5\vvrule\hrulefill\vvrule\cr
% Vlastn� data -------------------
&           &&& \bf A\hfil && \bf B\hfil &\\ \vkern\\
% --------------------------------
&    Leden  &&&         865&&    16&\\
&    �nor   &&&         917&&     8&\\
&    B�ezen &&&        1036&&    18&\\
\vkern\cr\noalign{\hrule}}\egroup   !lnl[endhalign]
\enduk

%A~v�sledek vypad� n�sledovn�:

\bigskip
\vbox\bgroup\offinterlineskip
\def\vvrule{\vrule \kern1.4pt \vrule}
\def\\{\crcr\multispan3\vvrule\hrulefill&\multispan5\vvrule\hrulefill\vvrule\cr}
\def\vkern{\multispan8\vrule height1.2pt \hfil \vrule}
\def\strut{\vrule height11pt depth 5pt width0pt }
\halign to\hsize{\tabskip=0pt plus 1fil\vvrule#&\quad#\hfil\quad
    &\tabskip=0pt#&\vvrule#\tabskip=0pt plus1fil&\quad\hfil#\quad &\vrule#&\quad\hfil#\quad
    &\vvrule#\strut\tabskip=0pt \cr  % konec deklarace
\noalign{\hrule} \vkern\\
&&&&\multispan3\hfil\quad\bf Prodej zbo��\quad\hfil &\cr
&\hfil\vbox to0pt{\vss\hbox{\bf M�s�c}\vss}%
        &&\multispan5\vvrule\hrulefill\vvrule\cr
% Vlastn� data -------------------
&           &&& \bf A\hfil && \bf B\hfil &\\ \vkern\\
% --------------------------------
&    Leden  &&&         865&&    16&\\
&    �nor   &&&         917&&     8&\\
&    B�ezen &&&        1036&&    18&\\
\vkern\cr\noalign{\hrule}}\egroup

Mysl�m, �e teprve v~t�to uk�zce si �ten�� pov�iml dal�� z�ludnosti.
Nadpis~{\bf B} nen� uprost�ed sloupce\.! Je to t�m, �e p�irozen�
���ka polo�ky \uv{Prodej zbo��} je v�t��, ne� sou�et p�irozen�ch ���ek
sloupc� A~a B a hodnot |\tabskip| mezi nimi. P�irozen� ���ka |\tabskip| je
toti� 0\,pt. Jak jsme uvedli na stran�~\pgr[wnasili], \TeX{} v~takov�ch
situac�ch pozm�n� n�jakou hodnotu $w_i$. V~na�em p��pad� zm�nil hodnotu
$w_7$ odpov�daj�c� ���ce sloupce~B. Zat�mco v~uk�zce na
stran�~\pgr[linkytab] n�m to v�bec nevadilo a dokonce n�m tato zm�na ���ky
sloupce~B p�ipadala p�irozen�, zde to bije do o��, proto�e prostor
v~tabulce je opticky v�t��. Abychom p�ekonali tento posledn� probl�m,
pou�ijme na ��dku~\lnr[zbo��] makro plainu |\hidewidth| n�sleduj�c�m
zp�sobem:

\beguk
&\multispan3\hfil\hidewidth\bf Prodej zbo��\hidewidth\hfil&\cr
\enduk

T�m bude m�t n� |\span| p�irozenou ���ku z�pornou a probl�m odpadne.
Jin�m �e�en�m je vlo�it |\tabskip| s~dosta�uj�c� p�irozenou ���kou, aby
���ka |\span| byla men�� ne� napo��tan� hodnota $W$. V~na�� uk�zce sta��
volit |\tabskip|{\tt=20pt~plus1fil}. \endpar

V~\TeX{}u je mo�n� tak� vkl�dat v�ce konstrukc� typu |\halign| do sebe.
Jinak �e�eno: ka�d� polo�ka tabulky m��e obsahovat libovoln� mno�stv�
dal��ch tabulek. Aby toho nebylo dost, existuje je�t� primitiv
|\valign|,\inl[valign]
kter� se chov� stejn�, jako |\halign| na vstupu, ale vyr�b� transponovanou
tabulku. Jednotliv� polo�ky se vkl�daj� do |\vbox|�, |\cr| ukon�uje sloupce
a |\vbox|y polo�ek se p�epo��taj� na maxim�ln� v��ku v~ka�d�m ��dku.
Hloubky t�chto box� jsou nulov�, proto�e se nejprve provede posun ��a�� na
spodn� ��st ka�d�ho boxu (to je jedin� algoritmus, kter� nem� v~p��pad�
|\halign| obdobu). Kone�n� |\valign| vrac� hotov� sloupce do horizont�ln�ho
seznamu odd�len� od sebe materi�lem z~|\noalign|. P�itom polo�ky ve
sloupc�ch jsou od sebe odd�leny v�pl�ky typu <glue> podle |\tabskip|.

V~posledn�m p��klad� t�to sekce uk�eme pou�it� |\valign|. Z�staneme
u~na�� obl�ben� tabulky a p�id�me j� je�t� jeden pon�kud v�t�� ��dek. Ka�d�
polo�ka tohoto ��dku bude obsahovat krat�� vodorovnou linku a nad n� i pod
n� bude samostatn� odstavec. Odstavce budou m�t centrovan� ��dky, ba co
v�c, horn� odstavce budou centrov�ny pod�l vodorovn� osy jako celek a
spodn� odstavce budou m�t na vodorovn� pomysln� lince spole�n� prvn� ��dek.
P�itom chceme tuto konstrukci ud�lat nez�vislou na mno�stv� textu, kter� se
v~odstavc�ch m��e vyskytnout. K~tomu se hod� |\valign|. Tabulka: \bigskip

\vbox\bgroup
\def\setparams{\parindent=0pt \hsize=.27\hsize
  \baselineskip=12pt \lineskiplimit=-10pt \parskip=0pt
  \leftskip=0pt plus3em \rightskip=0pt plus3em
  \parfillskip=0pt}
\let\hi=\hidewidth
\offinterlineskip
\def\vvrule{\vrule \kern1.4pt \vrule}
\def\\{\crcr\multispan3\vvrule\hrulefill&\multispan5\vvrule\hrulefill\vvrule\cr}
\def\vkern{\multispan8\vrule height1.2pt \hfil \vrule}
\def\strut{\vrule height11pt depth 5pt width0pt }
\halign to\hsize{\tabskip=0pt plus 1fil\vvrule#&\quad#\hfil\quad
       &\tabskip=0pt#&\vvrule#\tabskip=0pt plus1fil&\quad\hfil#\quad &\vrule#&\quad\hfil#\quad
       &\vvrule#\strut\tabskip=0pt \cr  % konec deklarace
\noalign{\hrule} \vkern\\
&&& % prvn� polo�ka (vlevo od "Prodej zbo��") je pr�zdn�
&\multispan3\hfil\hidewidth{\bf Prodej zbo��}\hidewidth\hfil &\cr
&\omit \hfil\vbox to0pt{\vss\hbox{\bf M�s�c}\vss}\hfil
       &&\multispan5\vvrule\hrulefill\vvrule\cr
% Vlastn� data -------------------
&           &&& \bf A\hfil && \bf B\hfil &\\ \vkern\\
% --------------------------------
&    Leden  &&&         865&&    16&\\
&    �nor   &&&         917&&     8&\\
&    B�ezen &&&        1036&&    18&\\
\hbox{\setparams \valign{\vfil\noindent\strut#\strut\vfil
                    &\hrule\bf\noindent\strut#\strut\vfil\cr
      \bf Shrnut� & Z�v�r\cr
       V~p��pad� zbo��~A~vid�me pom�rn� rychl�
          n�rust obratu zvl�t� v~b�eznu. Zd� se, �e
          to bude t�m, �e se v~tuto dobu oteplilo.&
          Ponechat a d�le sledovat v�voj.\cr
       Pokud jde o~zbo��~B, je to mizern�.&
          Zru�it v�robu\cr }%
  \global\setbox3=\lastbox \global\setbox2=\lastbox
  \global\setbox1=\lastbox}%
& \hi\box1\hi &&& \hi\box2\hi && \hi\box3\hi &\\
\vkern\cr\noalign{\hrule}}
\egroup

byla vytvo�ena stejn�m zp�sobem, jako je uvedeno na
��dc�ch~\lnr[beghalign]--\lnr[endhalign], jen p�ibyla nov� definice
pro form�tov�n� jednotliv�ch odstavc�:

\beguk Form�tov�n� odstavc� v tabulce
\def\setparams{\parindent=0pt \hsize=.27\hsize
  \baselineskip=12pt \lineskiplimit=-10pt
  \leftskip=0pt plus3em \rightskip=0pt plus3em
  \parfillskip=0pt}
\let\hi=\hidewidth
\enduk

a m�sto ��dku \lnr[endhalign] je naps�no:

\beguk Uk�zka \valign uvnit� \halign
\hbox{\setparams \valign{\vfil\noindent\strut#\strut\vfil !inl[vhalign]
                    &\hrule\bf\noindent\strut#\strut\vfil\cr
      \bf Shrnut� & Z�v�r\cr
       V~p��pad� zbo��~A~vid�me pom�rn� rychl�
          n�rust obratu zvl�t� v~b�eznu. Zd� se, �e
          to bude t�m, �e se v~tuto dobu oteplilo.&
          Ponechat a d�le sledovat v�voj.\cr
       Pokud jde o~zbo��~B, je to mizern�.&
          Zru�it v�robu\cr }% konec \valign
  \global\setbox3=\lastbox \global\setbox2=\lastbox
  \global\setbox1=\lastbox}%
& \hi\box1\hi &&& \hi\box2\hi && \hi\box3\hi &\\
\vkern\cr\noalign{\hrule}}\egroup % konec \halign a cel� skupiny
\enduk

Zde se nejprve nane�isto vyrob� |\hbox| se sloupe�ky tak, jak je vytvo�il
|\valign|. Pak se tyto sloupe�ky posb�raj� do box� "\box1" a� "\box3"
a tyto boxy se um�st� do polo�ek hlavn� tabulky |\halign|.
Kolem ka�d� polo�ky jsme vlo�ili "\hi", co� jsme definovali jako
zkratku za |\hidewidth|. T�m m�me zaru�eno, �e tyto polo�ky budou m�t
z�pornou p�irozenou ���ku a neovlivn� v�po�et maxima ���ky boxu ve sloupci.
Kdybychom to neud�lali, ��seln� �daje, kter� jsme s�zeli na pravou zar�ku
ve sloupc�ch A~a B, by byly posunuty doprava podle prav� hrany odstavce. N�m
se v�c l�b�, �e jsou uprost�ed sloupce, i kdy� na pravou zar�ku.
\endpar


