Hlavní navigace

ConTeXt: makrujeme

18. 6. 2007
Doba čtení: 3 minuty

Sdílet

V dnešním díle seriálu o typografickém systému ConTeXt se naučíme základy psaní maker v TeXu, naučíme se jim předávat argumenty, efektivně předefinovávat již existující struktury a povíme si o problémech a literatuře, již by žádný správný TeXpert neměl přehlížet.

Co to jsou makra?

Jste-li uživatelem nějakého pokročilejšího editoru nebo využíváte-li například makra v OpenOffice.org, pak patrně makra znáte. V opačném případě vězte, že makra jsou posloupnostmi příkazů, činností nebo (v případě editorů) stisknutých kláves, které je možné vyvolat zadáním jediného povelu. Software, který je po stránce maker vyspělejší, umožňuje do maker dávat podmínky a dává k dispozici vlastní makrojazyk. Takové možnosti dává i TeX.

Jednoduchá makra

Základním konstruktorem maker je příkaz \def, za kterým je nutno uvést jméno makra a jeho definici. Zcela jednoduché makro může tedy vypadat například takto:

\def\linkfont{\bf\red}

Právě jsme si nadefinovali makro \linkfont, které bude v textu přepínat řez a barvu písma. Samozřejmě jej budeme chtít použít lokálně, a tak jej uzavřeme do { skupiny }. To je sice hezké, ale rozhodně ne všeobjímající, a proto tady máme makra s argumenty.

Makra s argumenty

Dost často je třeba předat makru nějaké argumenty. TeXnicky to samozřejmě není problém a dělá se to uvedením #cislo_argumentu za název makra, tedy například:

\def\link#1{{\bf\red http://#1}}
\link{www.root.cz}

Máme-li argumentů více, je třeba odlišit, co patří kterému argumentu a kde vůbec argumenty končí. Klasicky se tak děje přes skupiny, tedy \makro{argument 1}{argument 2}, nicméně není to jediná alternativa, je možno použít oddělovací znak. Dejme tomu, že máme tuto definici:

\def\chapter#1:{\par{\bf\red#1}\par}

… pak budeme makro volat takto:

\chapter Makra s argumenty:

Namísto klasického:

\chapter{Makra s argumenty}

Je to užitečnější než se může zdát. Dejme tomu, že načítáme externí soubory, které jsou v pevně daném tvaru a vy je chcete zpracovat TeXem. V mnoha případech mohou TeXová makra odvést práci za skripty, kterými bychom jinak soubory parsovali, což občas není od věci.

Předefinovávání

Občas se nám hodí některou strukturu předefinovat. Dejme tomu, že chceme do definice jen něco přidat, ale nemůžeme měnit vlastní definici, například proto, že je to dílo jiného autora, do kterého nechceme přímo zasahovat, chceme jen něco pozměnit a nepsat kvůli tomu celou definici znovu. Pak je ovšem třeba nejprve nejprve „uložit” tu stávající pod jiným názvem pomocí příkazu \let a teprve poté strukturu dodefinovat. Dejme tomu, že jsme se rozhodli změnit řez písma kapitoly, můžeme zkusit třeba toto:

\let\oldchapter=\chapter
\def\chapter#1{\oldchapter{\bf#1}}

Zmíněný příklad je samozřejmě pouze pro ilustraci, jak lze podobné situace řešit. ConTeXt má pro tento konkrétní případ (a pravděpodobně pro převážnou většinu dalších využití, která vás napadnou) vlastní, jednodušší řešení pomocí \setuphead, které jsem již popisoval v díle o nastavování a definování.

Literatura

Protože je problematika TeXových maker velmi obsáhlá a navíc ne zcela související s naším seriálem (ConTeXt se snaží nabídnout již hotová řešení, aby nebylo třeba se zdržovat tvorbou maker, ale bylo možno se soustředit na vlastní dokument), uvedu alespoň literaturu, na niž případné zájemce odkazuji.

V našich podmínkách lze asi těžko doporučit něco lepšího než perfektní a velmi obsáhlou knihu Petra Olšáka TeXbook naruby, který je na uvedené adrese ke stažení, a to včetně maker, která byla pro jeho tvorbu vytvořena. Chcete-li TeXovým makrům porozumět opravdu do hloubky, jistě si je neopomeňte prohlédnout.

root_podpora

Možné problémy

Relativně častý problém začínajících uživatelů TeXových maker jsou konce řádků. Ty jsou brány jako mezery a mohou dělat v makrech neplechu. Samozřejmě vzhledem k zachování čitelnosti je neakceptovatelné psát delší makra na jeden řádek. Řešení je naštěstí velmi prosté, stačí jednoduše „zamaskovat” konec řádku komentářovým znakem, jímž defaultně je znak procento.

Nedávno proběhl TeXovou konferencí problém, který spočíval v inkompatibilitě některých ConTeXtových příkazů s příkazy plainovskými, kvůli které pak některá makra odladěná pro plain TeX v ConTeXtu nemusí vůbec fungovat. Je to proto, že ConTeXt některé příkazy předefinovává a tedy, i když třeba mají stejný název, se chovají jinak. To je třeba mít na zřeteli a v podobných situacích by první krok měl být právě zjištění, zda příkazy používané v plainovském makru ConTeXt nějak předefinovává či nikoliv.

Byl pro vás článek přínosný?

Autor článku

Jakub Šťastný byl v letech 2007 až 2008 redaktorem serveru Root.cz. Mezi jeho zájmy patří Linux, programování a typografický systém TeX.