Visici rozdelovnik

Petr Brezina petr-brezina at volny.cz
Tue Dec 14 19:14:10 CET 2004


Dobry den!
 Kdyz jsem si vcera vecer procital konferenci, zaujala me diskuse
o visicim rozdelovniku. Rad bych take prispel svoji troskou do mlyna.
Tvrdim totiz, ze za jistych podminek TeX dokaze vysazet vycuhujici
rozdelovnik a vubec pritom nemusite upravovat font ani nemusite
pouzivat pdfTeX; navic vlastne ani nemusi byt ve fontu pritomen
alternativni rozdelovnik. O tom, ze to skutecne jde, se muzete
presvedcit, kdyz si konec tohoto emailu (od meho podpisu dale)
zkopirujete do souboru a ten soubor pak zpracujete csplainem. Zname
klise prece rika, ze TeX umi vsechno, jen se musi vedet, jak na to.

Me reseni bude fungovat, pokud budou splneny tyto podminky:

1. Chceme, aby napravo vycuhoval rozdelovnik cely.
(To vlastne neni podminka, ale popis toho, co muzete od meho makra
ocekavat.)

2. Ve fontu je alespon jedna pozice, ktera neni obsazena zadnym
znakem. (Pro CS-fonty tato podminka plati.)

3. Cely odstavec je sazen jednim fontem. (Pri sazbe beletrie to je
obvykle. Nemylim-li se, kolega, ktery zadal o pomoc, chtel sazet
povidky.)

4. \brokenpenalty nesmi byt rovna nule. (Plain ji nastavuje na 100.)

Pouziti je jednoduche: Uzivatel napise prikaz \vystrkuj, za nim muze
nasledovat libovolny pocet odstavcu, v nichz ma byt vycuhujici
rozdelovnik; za poslednim odstavcem je treba napsat prikaz
\nevystrkuj.

Jeste se zminim o jedne zaludnosti. Normalne TeX za rozdeleni slova
pricita k demerits hodnotu z registru \hyphenpenalty. V odstavcich
s vycuhujicim rozdelovnikem je to trochu jine - TeX vetsinou pouzije
hodnotu z registru \exhyphenpenalty, nekdy vsak take hodnotu
z registru \hyphenpenalty. Abychom dokazali rozhodnout, zda TeX
v danem pripade pouzije registr \hyphenpenalty nebo \exhyphenpenalty,
musime vedet, co presne do sazebniho materialu vklada algoritmus na
automaticke vyhledavani potencialnich mist deleni slov. Nuze,
vetsinou na prislusne misto vklada
\discretionary{\char\hyphenchar\font}{}{}. Pokud se vsak potencialni
misto deleni objevi v implicitnim kernu nebo uvnitr ligatury, musi
zmineny algoritmus takovy pripad peclive osetrit, aby kern ci
ligatura zustala zachovana, takze kdyz se napr. v anglickem textu
vyskytne slovo "difficult", zmineny algoritmus ho upravi timto
zpusobem: di\discretionary{f\char\hyphenchar\font}{fi}{ffi}cult.
Ponevadz mame pri sazbe vystrcenych rozdelovniku nastaven \hyphenchar
na neexistujici znak, je \discretionary{\char\hyphenchar\font}{}{}
stejne jako \discretionary{}{}{}, takze se pri vypoctu demerits
pouzije \exhyphenpenalty. Je-li vsak slovo rozdeleno v implicitnim
kernu nebo uvnitr ligatury, pouzije se \hyphenpenalty.

S pozdravem

Petr Brezina


% makro na vystrkovani rozdelovniku za pravy okraj radku
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newdimen\hloubka
\newbox\odstavec
\newcount\radek
\newcount\sirotek
\newskip\mezera
\newcount\penalta
\newcount\tempnum
\def\vystrkuj{\par\begingroup
   \hyphenchar\font="90 % tento znak nesmi byt ve fontu pritomen
   \tracinglostchars=0
   \def\par{\ifhmode\ukonciodstavec\fi}
   \global\hloubka=\prevdepth
   \setbox\odstavec=\vbox\bgroup \prevdepth=\hloubka}
\def\ukonciodstavec{%
   \endgraf
   \global\hloubka=\prevdepth
   \setbox2=\lastbox
   \global\setbox1=\vbox{\box2}
   \radek=\prevgraf \advance\radek by-1
   \sirotek=\radek
   \loop
   \ifnum\radek>0
      \mezera=\lastskip \unskip
      \penalta=\lastpenalty \unpenalty
      \tempnum=\penalta
      \advance\tempnum by-\interlinepenalty
      \ifnum\radek=\sirotek \advance\tempnum by-\clubpenalty \fi
      \ifnum\radek=1 \advance\tempnum by-\widowpenalty \fi
      \setbox2=\lastbox
      \ifnum\tempnum=0 \else
         \setbox2=\hbox to\wd2{\unhbox2\rlap{-}}\fi
      \global\setbox1=\vbox{\box2
         \ifnum\penalta=0 \else \penalty\penalta \fi
         \vskip\mezera \unvbox1}
      \advance\radek by-1
   \repeat
   \skip0=\lastskip
   \global\setbox1=\vbox{\vskip\skip0\unvbox1}
   \egroup
   \noindent\endgraf \unvbox1 \endgraf
   \setbox\odstavec=\vbox\bgroup \prevdepth=\hloubka}
\def\nevystrkuj{\par\egroup\prevdepth=\hloubka\endgroup}


% nasleduje ukazka funkcnosti tohoto makra
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\chyph % ceske deleni slov

% nekolik nastaveni, aby se casto delila slova:
\righthyphenmin=2
\hyphenpenalty=-200
\exhyphenpenalty=-200
\pretolerance=-1
\tolerance=5000
\hsize=7cm


\vystrkuj

Byla jedna princezna, ktera nechala po celem kralovstvi rozhlasit, ze
si nikoho jineho za manzela nevezme, lec kdo by tak umel zalhat, ze by
se tomu podivila a nedala mu za pravdu.
Hoj, to bylo pojednou namlouvacu, ze si nestacili dvere podavat! Jeden
kazdy vynalozil vsecku svou chytrost, jak by ji nejlepe obelhal:
lhali, jak by tiskl.

Princezna ale vsem statecne odolavala a nerekla i na ty nejvtipnejsi
lzi nic jineho, lec ze to vsecko muze byt pravda.
Mezi jinymi prisel konecne take jakysi prostacek a zacal lhat takto:
\uv{Mila princezno, ja jsem sil jednou konopi, a jedno z nich vyrostlo
mi az do nebe. Vylezl jsem si po nem nahoru a prochazel jsem se tam po
nebi.}

\uv{To vsecko muze byt pravda!} kyvala princezna.

On ale pokracoval dale:
\uv{Nikde jsem nic nevidel, lec v koutku hromadku psenicnych otrub.
Z tech jsem si upletl provaz a pustil jsem se po nem dolu. Kdyz jsem
uz dolu prichazel, vidim, ze se mi provaz nedostava, a nezbylo mi nic
jineho, nez abych ten ostatek na zem doskocil. Skocim, ale zapadl jsem
az po krk do zeme. Sel jsem domu pro motyku a stastne jsem se vykopal
ven.}

Na to vsechno princezna porad jenom prisvedcovala, rikajic \uv{to
vsechno muze byt pravda}.

\uv{A jeste}~--- di on dale~--- \uv{jak jsem byl v nebi, vas pantata
tam ovce pasl.}

\uv{To nemuze byt pravda!} skocila mu princezna rozhorlene do reci,
a musila si vzit prostacka za manzela.

\nevystrkuj

\bye




More information about the csTeX mailing list