Portál AbcLinuxu, 2. května 2024 06:53

TeX – 4 (kódování znaků)

6. 11. 2013 | Petr Olšák
Články - TeX – 4 (kódování znaků)  

U tak složitého systému, jakým je TeX, se občas bohužel stane, že ne vše funguje jak má. V takovém případě uživatelům asi nepostačí jen znalost autorského značkování a musejí se zanořit poněkud do hloubky mezi nánosy všeho možného, co přinesla dlouholetá historie TeXu. V tomto díle seriálu si ukážeme, jak TeX přistupoval a přistupuje ke kódování znaků textových fontů. Aspoň rámcový přehled v této problematice se jistě vyplatí.

Obsah

Kódování znaků v diluviálním TeXu a nyní

link

Původně Knuth rozhodl, že TeX bude interně pracovat v ASCII kódování. Na 94 viditelných ASCII znaků navázaly pro TeX připravené a zhruba stejně kódované fonty Computer Modern. Co Knuth neměl na své klávesnici a chtěl tisknout, na to si připravil řídicí sekvenci. Například \ae vytisklo æ. Takovéto znaky Knuth vpravil do zbývajících míst 128znakové tabulky fontů Computer Modern. Například znaku æ přidělil pozici 26 a řídicí sekvenci \ae pak deklaroval v makru plainTeX primitivním příkazem \chardef\ae=26. Na některé znaky nezbylo ve fontech místo, takže třeba znak paragrafu (§) byl tištěn makrem \S, které jej dosti nekoncepčně lovilo z doplňkové sady matematických fontů. Můžeme k tomu mít dnes výhrady, ale uvědomme si, že se psal rok 1982.

Další vychytávku Knuth vymyslel pro snadné dosažení střední a dlouhé pomlčky: dvojice -- nebo trojice --- se proměnila na odpovídající pomlčku díky tomu, že byla zanesena v tabulce ligatur fontu Computer Modern. Analogicky se f a i promění automaticky ve fontu na ligaturu fi. Implementace pomlček jako ligatur taky není příliš ideální. Na druhé straně je to ergonomické, účelné a přehledné při psaní zdrojových textů: tyto pomlčky ani nyní na klávesnici přímo přístupné nejsou.

Pro znaky s akcenty měl Knuth připravena další makra, která sestavovala akcentovaný znak z komponent (například z háčku a písmene). Takže „české slovo“ se dalo (a dosud dá) napsat jako \v{c}esk\’e slovo. S takovýmto TeXem jsem se poprvé setkal asi v roce 1990 a prohlásil jsem, že pokud se to má začít používat v češtině, pak takto rozhodně ne. A chopili jsme se společně s ostatními zájemci o TeX z tehdejšího Československa práce...

Dnes existují 16bitové modifikace TeXu (XeTeX a LuaTeX), které pracují interně v Unicode a se stejně kódovanými fonty. Ovšem cesta k tomuto stavu byla dlouhá a vedla různými oklikami. Netradičně začnu od konce a popíšu nejprve možnosti, které nabízejí současné 16bitové TeXy.

UTF-8 kódování na vstupu a Unicode uvnitř

link

Je třeba rozlišovat mezi kódováním vstupního souboru (což musí být UTF-8) a interním kódováním 16bitového TeXu (Unicode). Konverzi mezi prvním a druhým světem zajišťuje v TeXu vestavěný input procesor podle jednoduchého pravidla. V TeXu probíhá i opačná konverze zpět do UTF-8 při ukládání informací do textových souborů (například pro opakované načtení při sestavení obsahu). Dlužno podotknout, že input procesor včetně zpětné konverze měl v daleko jednodušší podobě už Knuth ve svém prvním TeXu: řešil tehdy otázku existence dvou kódování anglické abecedy EBCDIC a ASCII s tím, že interně v TeXu předpokládal vždy ASCII i na mašinách, které pracovaly v EBCDIC.

Input procesor konvertující UTF-8 do Unicode (a zpět) je v XeTeXu implementován „natvrdo“, zatímco v LuaTeXu je řešen pomocí Lua skriptu a je tedy modifikovatelný. Na interní kódování TeXu musejí navázat stejně kódované vzory dělení slov jednotlivých jazyků a fonty. V tomto případě tedy vzory dělení slov a fonty musejí být v Unicode.

Při psaní česky nebo slovensky v 16bitovém TeXu jsme nuceni skutečně užít unicodový font, protože znaky české a slovenské abecedy mají v Unicode přidělena čísla často větší než 255. Na druhé straně naši evropští kolegové na západ od nás používající kódovou sadu ISO-8859-1 (francouzi, němci, španělé, atd.) mohou pro svůj jazyk načíst i starší 8bitový font, protože Unicode se ve znacích jejich jazyka shoduje s ISO-8859-1. Nejsou tedy odkázáni na fonty jen ve formátu OpenType. Mají-li nějaký starší oblíbený font v kódování ISO-8859-1, nemají s tím v XeTeXu ani LuaTeXu (na rozdíl od nás) problém.

Zdrojové dokumenty je potřeba pořizovat za použití vhodného ovladače klávesnice nebo input metody textového editoru. Tím se dá zcela vyhnout původnímu způsobu pořizování textů, při kterém platilo pravidlo, že co není na klávesnici, na to se použije řídicí sekvence. Takže při zapnuté české klávesnici píšeme jednoduše česky. V editoru Emacs je také speciální input metoda, při které uživatel napíše \ae a ono se to okamžitě v textovém editoru promění na UTF-8 kód znaku æ. Nebo zápis --- Emacs promění v UTF-8 kód dlouhé pomlčky. Osobně se domnívám, že nic se nemá přehánět. Tento způsob zápisu totiž svádí používat UTF-8 kódy třeba i v matematických vzorcích. Porovnejte:

$$ \sum_{n=1}^\infty {1\over n^2} = {\pi^2 \over 6} $$
$$ ∑_{n=1}^∞ {1\over n^2} = {π^2 \over 6} $$

Aby druhý řádek fungoval, je potřeba mít použité kódy deklarovány jako odpovídající matematické znaky příkazem \mathcode. V klasickém TeXu jsou deklarovány jen použité řídicí sekvence \sum, \pi, \infty pomocí \mathchardef, jak je možné se přesvědčit například v Knuthově souboru plain.tex.

I formát CSplain je možné vygenerovat s XeTeXem nebo LuaTeXem. CSplain ale z historických důvodů má implicitně vnitřní kódování il2 (viz níže). Ovšem je snadné přepnout na jiné kódování (T1 nebo Unicode). Začátek dokumentu v CSplainu pod 16bitovým TeXem může tedy vypadat třeba takto:

\input ucode   % redefinice maker (závislých na kódování) podle Unicode
\chyph         % vzory dělení češtiny (nyní budou v Unicode)
\input lmfonts % načtení Latin Modern fontů v Unicode
Ahoj světe! Jak se mají žlutí koňové?
\end

Osmibitové období

link

Možnost použít unicodové fonty je poměrně nová. Ještě nedávno TeX uměl pracovat pouze s metrickými údaji fontů s maximálně 256 znaky. Vrátíme se tedy na počátek 90. let a popíšeme, jak vznikala podpora češtiny a slovenštiny. Kvůli častému konzervativnímu přístupu TeXistů se některé tyto věci používají dodnes.

Zhruba v roce 1991 jsme navrhli mírnou modifikaci Computer Modern fontů, tzv. CSfonty. Ty přidávají kompletní akcentované znaky české a slovenské abecedy do druhé poloviny tabulky podle ISO-8859-2. Toto kódování se nazývá il2. Vzory dělení češtiny i slovenštiny jsou do CSplainu načteny v il2 a CSfonty na to navazují. V té době se pro češtinu používalo několik jednobytových kódování vstupních souborů: ISO-8859-2, CP1250, CP852, KOI8-CS, Kamenických atd. Mezi různými prostředími dle použitého kódování a interním kódováním il2 bylo potřeba správně konfigurovat input procesor TeXu, který pro případ překódování tam i zpět na úrovni „byte to byte“ byl připraven již Knuthem. Docela podrobně jsem tuto problematiku popsal v článku Putování písmene ř z klávesy na papír (1997).

Na začátku 90. let na konferenci v Corku se TeXisté dohodli a vymezili evropské kódování fontů. Využili všech tehdy dostupných 256 pozic. První polovina tabulky respektovala viditelné ASCII znaky, druhá ISO-8859-1 a do volných míst byly nacpány ostatní znaky latinkou píšících evropanů, tedy i naše abeceda. Kódování nazvali T1 alias Cork. Jádro LaTeXu bylo Jiřím Zlatuškou upraveno tak, aby dokázalo načíst vzory dělení v obou kódováních (il2 i T1) a tím vznikl CSLaTeX schopný pracovat jak s CSfonty tak s T1 kódovanými fonty. Kresby znaků české abecedy byly v CSfontech vydařenější než v analogickém fontu kódovaném podle T1 a tím se asi vysvětluje, proč CSLaTeX přežíval dvě desetiletí. Já jsem navíc v il2 kódování připravil počeštění základních PostSriptových fontů.

Fonty kódované podle T1 byly většinou z různých zdrojů (třeba i bez akcentovaných znaků) generovány za použití nástroje fontinst, který vytváří virtuální kompozitní znaky, jež může pak přímo používat TeX. Bohužel v tomto nástroji byla a je chyba v konfiguraci znaku ď a ť, takže desítky, možná stovky, takto vytvořených fontů přítomných v TeXové distribuci jsou pro češtinu nepoužitelné. Když jsem to teprve loni objevil (protože vesměs používám il2 kódované fonty), docela jsem se podivil, že toto žádný uživatel za těch 20 let nereportoval. Že by všichni čeští TeXisté užívali výhradně il2?

Kuriózní na T1 kódování je například to, že sice bylo navrženo pro Evropu, ale stalo se tak v roce 1990, kdy ještě nikdo netušil, že bude existovat znak Euro. V T1 tabulce najdeme libru, dolar, ale Euro nikoli. Nicméně TeX umožňuje na úrovni maker snadno připojit ke každému 256znakovému fontu libovolné množství expertních sad tak, že uživatel ani nepozná, že TeX uvnitř přepíná mezi základním řezem a k němu připojenou expertní sadou. Viz například soubor maker exchars.tex. V expertní sadě samozřejmě Euro přítomno je.

Nové fonty například z projektu TeXGyre jsou primárně připraveny v OpenType, ale jsou k nim rovněž vygenerovány klasické metriky pro TeX podle rozličných kódování, která se během osmibitového období narodila a začala v TeXových distribucích přežívat.

UTF-8 na vstupu, osm bitů uvnitř

link

V roce 2000 narůstal požadavek používat UTF-8 kódování vstupních souborů. V té době byla ještě možnost číst unicodové fonty v nedohlednu, formát OpenType (2005) neexistoval. Konverze UTF-8 na 8 bitů uvnitř TeXu byla v LaTeXu řešena na úrovni maker: \usepackage[utf8]{inputenc}. Ovšem takto řešená konverze přináší na nízké úrovni programování maker docela problémy. Proto jsem počátkem milénia rozšířil input procesor TeXu tak, aby dokázal kromě „byte to byte“ konverze provádět i konverzi více bytů na jeden byte nebo na řídicí sekvenci. Počet UTF-8 znaků je sice značný, ale počet řídicích sekvencí, na které se to automaticky může uvnitř TeXu konvertovat, je víceméně neomezený. Každá řídicí sekvence může navazovat na své makro, které vyšťourá znak buď z aktuální základní sady nebo z některé z expertních sad přidružených aktuálnímu fontu. Toto řešení jsem nazval encTeX.

Současný CSplain nad pdfTeXem s UTF-8 kódovaným vstupem využívá encTeX. Implicitně rozumí znakům české a slovenské abecedy a textovým znakům, na které měl Knuth řídicí sekvenci (typu \ae). Po načtení dalších maker rozumí znakům z dalších částí Unicode tabulky. Například po \input utf8math je CSplain schopen interpretovat matematické vzorečky s UTF-8 znaky, jak bylo ukázáno v příkladu v úvodu tohoto článku.

Historický přehled

link
verze rok poznámka
TeX v.<3< 1990ASCII a řídicí sekvence, interně 7 bitů
TeX v. 3.* ≥ 1990 interně 8 bitů a řídicí sekvence, kódování il2, T1, konverze byte to byte
encTeX ∼ 2002 UTF-8 → 8 bitů+řídicí sekvence, kódování il2, T1
XeTeX ∼ 2006 umí číst OpenType fonty, UTF-8 na vstupu, interně Unicode
LuaTeX ∼ 2010 umí číst OpenType fonty, UTF-8 na vstupu, interně Unicode

Seriál TeX (dílů: 15)

První díl: TeX – 1 (seznamujeme se), poslední díl: TeX – 15 (mikrotypografie).
Předchozí díl: TeX – 3 (příklady autorského značkování)
Následující díl: TeX – 5 (příklad makra pro generování HTML)

Další články z této rubriky

Týden na ITBiz: GenAI má na evropském trhu umělé inteligence zatím jen velmi malý podíl
Týden na ScienceMag.cz: Upřesnili limity pro klidovou hmotnost neutrin
Týden na ITBiz: Fotonické čipy ze stolní tiskárny
Týden na ScienceMag.cz: Model Lambda CDM celkem sedí, ale kosmologická konstanta se může měnit
Týden na ITBiz: Vysokoteplotní supravodivá dioda

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.