| |||
Původní verze LaTeXu poskytovala příkaz
V případě, že použijete
TeX při uspořádávání textu nepracuje tak, že by bral slovo za slovem, či řádku za řádkou. Nejmenší jednotkou, kterou TeX formátuje, jsou celé odstavce. Odstavec je načten celý do paměti a není dále zpracováván, dokud není načtena značka konce odstavce. Právě v ten okamžik se uplatní parametry odstavce. Chyby použití parametrů formátování odstavce často vznikají právě proto, že se zapomíná na to, v jaké posloupnosti se odstavec zpracovává. Předpokládejme následující větu v LaTeXu:
{\raggedright % zarovnávání textu vlevo Tento text by měl být na výstupu zarovnán pouze vlevo. Chceme, aby se tak stalo pouze v~tomto odstavci, a~ proto zde ukončíme skupinu.}
TeX otevře skupinu a nastaví parametry formátování odstavce tak,
aby byl text uvnitř této skupiny zarovnáván pouze vlevo, poté uloží
dvě věty textu, uzavře skupinu a nastaví původní parametry
odstavce.
Poté načte prázdný řádek, který je zpracován stejně jako
příkaz Aby nastavené parametry zůstaly v platnosti po celou dobu zpracovávání odstavce, je třeba ukončit odstavec uvnitř skupiny. Nahradíme-li poslední tři řádky v předchozím příkladě za: ukončíme skupinu.\par} Další text je zpracován normálně...ukončí se odstavec ve chvíli, kdy jsou parametry odstavce nastavené v uzavřené skupině stále v platnosti. Další alternativa spočívá v tom, že si můžete definovat nové prostředí, které udělá příslušnou práci za vás. Pro příklad, který byl zmiňován výše, je již v LaTeXu definováno takovéto prostředí: \begin{flushleft} Tento text by měl být... \end{flushleft}
LaTeX si ukládá některá data, jež bude zpracovávat až později. Těmito daty jsou zejména argumenty některých příkazů, takzvané pohyblivé argumenty. Pohyblivé, protože se s daty nějakým způsobem manipuluje. Jedná se o argumenty těch příkazů, které zapisují do obsahu, seznamu tabulek atd., tj. data, která jsou zapisována do pomocného souboru, z něhož jsou později opět čtena. Jinými daty jsou ta, která se mohou objevit v záhlavích. Nejvýznamnějšími příkazy tohoto typu jsou popisy obrázků a tabulek (captions) a veškeré nadpisy. Úplný seznam lze najít v Lamportově manuálu (viz Knihy o TeXu a příbuzná literatura).
Co se za tím vším skutečně skrývá? Příkazy, jež se použijí
v pohyblivých argumentech, jsou v průběhu ukládání
plně expandovány.
Někdy je výsledkem takového rozvoje špatný
TeXovský kód, což se projeví až při jeho následném čtení.
Příkazem Co je to „křehký příkaz“ (fragile command)? To je příkaz, který je během ukládání rozvinut do chybného TeXovského kódu. Co je to „robustní příkaz“ (robust command)? To je příkaz, který je během ukládání rozvinut do správného TeXovského kódu. Nikdo se (samozřejmě) z takto nepřehledné situace neraduje. Skupina projektu LaTeX3 při práci na LaTeXu 2e odstranila potřebu některých ochran, avšak techniky, které jsou jim dostupné v současném LaTeXu, činí věc poměrně složitou. Dlouhodobým cílem této skupiny zůstává odstranění všech ochran.
Funkce příkazu LaTeXu pro sazbu textu v tom tvaru, v němž je uveden ve
zdrojovém souboru ( \verb+\error+bude fungovat (vysází se „ \error “), ale
\newcommand{\unbrace}[1]{#1} \unbrace{\verb+\error+}fungovat nebude (pokusí se spustit příkaz \error ). Další chyby, se
kterými se můžete setkat jsou „\verb ended by end of line“ nebo
„\verb illegal in command argument“.
Proto se také v manuálu LaTeXu tolik naléhá na to, aby se příkaz verbatim neobjevil v argumentu žádného jiného příkazu. Tyto příkazy jsou nejen křehké (fragile), ale dokonce zcela nepoužitelné jako parametr jiných příkazů, bez ohledu na ochranu pomocí Proč se v LaTeXu užívá ochran (protection). Jako první by jste si měli položit otázku, jestli je csx{verb} skutečně nezbytné.
Jinak jsou zde tři částečná řešení tohoto problému:
Chyba
! LaTeX Error: There's no line here to end.je reakciou LaTeXu na príkaz \ {}\ tam, kde to nečaká. Najčastejším
prípadom je, keď chcete mať návestie položky zoznamu na samostatnom riadku:
\begin{description} \item[Veľmi dlhý popisok] \\ Text... \end{description} \ {}\ je vlastne v tomto prípade dosť zlý príkaz (aj keby fungoval), pretože
by donútil odstavec tvorený textom položky, aby ukončíl riadok, na ktorom
nie je nič okrem návestia. Toto by viedlo k varovnej hláške
„Underfull \hbox “ (obvykle s „nekonečnou“ nevhodnosťou hodnoty 10000);
táto správa síce okrem spomalenia behu LaTeXu neškodí, ale každá správa,
ktorá neprináša žiadnu informáciu, zbytočne odvracia pozornosť uzívateľa.
Správnym riešením je napísanie nového druhu prostredia Jednoduchým a rýchlym riešením, ktoré sa vyhne varovaniam, je napísať:
\begin{description} \item[Veľmi dlhý popisok] \hspace*{\fill} \\ Text... \end{description}čo vyplní podtečený (under-full) riadok predtým, než si vynúti jeho uzavretie. Balík expdlist poskytuje rovnakú funkčnosť svojím príkazom
csx{breaklabel}, mdwlist ju poskytuje príkazom csx{desclabelstyle}.
Ďalším častým prípadom správy je používanie prostredia
\begin{center} Prvý riadok (nadpisu)\\ \\ telo centrovaného textu... \end{center}Riešenie je prosté: použite príkaz \ {}\ spôsobom, akým sa používať má, aby
poskytol viac priestoru než jeden riadkový zlom. \ {}\ akceptuje voliteľný
parameter špecifikujúci, koľko priestoru naviac pridať; požadovaný efekt
v hore uvedenom príklade docielite takto:
\begin{center} Prvý riadok (nadpis)\\[\baselineskip] telo centrovaného textu... \end{center} expdlist.sty : CTAN: expdlistmdwlist.sty : distribuované ako súčasť CTAN: mdwtools
TeX poskytuje dva primitivní příkazy umožňující konverzi
textu do malých písmen,
Oba příkazy nerozvíjejí text, který je jejich parametrem —
výsledkem příkazu \uppercase{About $y=f(x)$}dává ABOUT $Y=F(X)$což zřejmě není to, co jsme původně zamýšleli. csx{uppercase} a csx{lowercase} navíc špatně pracují s neamerickými znaky, např. csx{uppercase{csx{ae}}} je to samé jako csx{ae}. LaTeX poskytuje příkazy csx{MakeUppercase} a csx{MakeLowercase}, které opravují posledně zmíněný problém. Tyto příkazy jsou používány ve standardních třídach k vytvoření verzálkových hlaviček kapitol a sekcí.
csx{MakeUppercase} a csx{MakeLowercase} bohužel neřeší další problémy
csx{uppercase}, takže například titulek sekce obsahující
\newcommand{\mytable}{\begin{tabular}... \end{tabular}} \section{Titulek sekce \protect\mytable{} s~tabulkou}Všimněte si, že csx{mytable} musí být chráněno, jinak bude expandováno a přepsáno do verzálek; stejný výsledek dosáhnete deklarováním s csx{DeclareRobustCommand} (csx{protect} již nebude potřeba).
Balík
Při psaní makra je třeba mít na paměti, že
Definujeme-li a poté použijeme makro: \def\a#1{+++#1+++#1+++#1+++} \a{b}makro po expanzi dává „+++b+++b+++b+++“, což jsme očekávali. Avšak změníme-li nyní část makra: \def\a#1{+++#1+++\def\x #1{xxx#1}} \a{b} se rozvine na „+++b+++\def\x b{xxxb} “.
Definuje se zde makro \x , které je ohraničené znakem
b a které nemá žádný argument. Může se to zdát divné,
ačkoli jde jen o zvláštní případ předchozího příkladu.
Chceme-li, aby v \a
bylo definováno makro \x s jedním argumentem, musíme
upravit předchozí makro takto:
\def\a#1{+++#1+++\def\x ##1{xxx##1}} \a{b} se nyní rozvine do tvaru
„+++b+++\def\x #1{xxx#1} “, neboť #1 bude nahrazeno
znakem `b' a ## bude nahrazeno # .
Pro definici vnořenou uvnitř definice se
použije
Je jednoduché napísať makrá produkujúce medzeru v sádzanom výstupe tam, kde to nie je želané ani očakávané. Medzery vytvorené makrami sú zradné, pretože sa nezdružujú s medzerami okolo makra (na rozdiel od následných medzier, ktoré píšete), takže váš výstup môže mať jednu nafúknutú medzeru zloženú z jednej alebo viacerých medzier, ktoré neboli združené. Výstup môže mať medzeru aj tam, kde ju vôbec nikto nečaká. Medzery vznikajú (vo vnútri makra ako aj inde), znakmi medzery, tabulátoru alebo konca riadku. Pri písaní makier by ste si mali pamätať dve jednoduché pravidlá: pravidlá ignorovania prázdneho miesta (medzier) pri písaní makier sú rovnaké ako pri písaní obyčajného textu a pravidlá ignorovania medzier neplatia na medzery vzniknuté počas expanzie makra.
Medzery sú ignorované vo vertikálnom móde (medzi odstavcami), na začiatku
riadku a po názve príkazu. Kedže postupnosti medzier splývajú do jednej
medzery, vyzerá to, že medzery sú ignorované aj vtedy, ak nasledujú inú
medzeru. Medzery môžu mať po niektorých druhoch nezátvorkovaných parametrov
(napr. priradenie premenným count a dimen v Plain TeXu) a po
určitých kontrolných slovách (napr. v csx{hbox}
Všimnite si nasledujúce makro celkom verne adaptované z makra, ktoré sa
objavilo na
\newcommand{\stline}[1] { \bigskip \makebox[2cm]{ \textbf{#1} } }(originál bol na jeden riadok). Definícia makra obsahuje päť medzier:
Hlavná technika potlačenia medzier je použitie znakov
\newcommand{\stline}[1]{% \bigskip \makebox[2cm]{% \textbf{#1}\relax }% }Uistili sme sa, že každá medzera v upravenej definícii je ignorovaná, takže sa žiadna neobjaví vo výstupe. Upravená definícia sa explicitne vysporiada s každým koncom riadku (hoci, ako sme uviedli vyššie, medzera na konci prvého riadku makra by bola pri použití makra ignorovaná). Toto je v skutočnosti najlepšia technika — je jednoduchšie slepo potlačiť medzery, než v každom bode analyzovať, či to vlastne potrebujete. Na potlačenie medzier boli použité tri techniky:
% : ak to spravíte, môžete úplne vynechať aj
% .
V „skutočnom živote“ sú medzery objavujúce sa v makrách samozrejme záhadnejšie ako v našom príklade. najbežnejšie medzery vznikajú z nechránených koncov riadkov a toto je chyba, ktorá sa občas vyskytne aj v makrách písaných skúsenými programátormi.
Jednotlivé znaky sa môžu správať ako makrá (definované príkazy) a Plain TeX
aj LaTeX definujú znak „
Ľubovolný znak v princípe môže byť týmto spôsobom aktivovaný a definovaný ako makro
(
Pre definovanie znaku `
\catcode`\z=\active \def z{Ahoj}%a každé následné „ z “ v texte sa stane pozdravom. Toto by bolo pre väčšinu
dokumentov zlým nápadom, ale mohlo by to mať špeciálne využitia. (V \def z ,
už „z “ nie je interpretované ako písmeno; medzera teda nie je potrebná —
\defz postačuje; rozhodli sme sa ponechať medzeru aspoň pre malé
zprehľadnenie.) Niektoré balíky LaTeX obsahujú takéto definície. Napríklad
balík shortvrb a jeho príkaz csx{MakeShortVerb}.
TeX Používa kódy kategórií na interpretáciu znakov pri tom, ako sú čítané
zo vstupu.
Zmena hodnoty catcode neovplyvní znaky, čo boli už prečítané.
Z tochto dôvodu je vhodné, ak majú znaky pevný kód kategórie v celom dokumente.
Ak je hodnota catcode zmenená za určitým účelom (toto robí príkaz csx{verb}),
potom upravené znaky nebudú pri výskyte v parametri iného príkazu správne
interpretované (ako napríklad v Otázke Proč Ďalším dôsledkom je, že priradenia catcode uskutočnené v makrách často nefungujú, ako by sa čakalo (viď Otázku Aktívne znaky v parametroch príkazov). Napríklad definícia
\def\mistake{% \catcode`_=\active \def_{\textunderscore\-}% }nefunguje, pretože sa pokúša definovať bežný znak _ :
Keď je makro použité, zmena kategórie neplatí pre znak podčiarknutia
v definícii makra. Namiesto toho môžete použiť:
\begingroup \catcode`_=\active \gdef\works{% všimnite si globálne \gdef \catcode`_=\active \def_{\textunderscore\-}% } \endgroupAlternatívny spôsob vytvorenia takejto izolovanej definície záleží na zvláštnych vlastnostiach csx{lowercase}, ktorý zmení znaky bez zmeny ich hodnoty catcode. Kedže vždy existuje jeden aktívny znak („ textasciitilde “), môžeme oklamať csx{lowercase}, aby zaplátalo
definíciu bez toho, aby sme explicitne zmenili catcode:
\begingroup \lccode`\~=`\_ \lowercase{\endgroup \def~{\textunderscore\-}% }%Tieto dve definície majú rovnaký celkový efekt (znak je definovaný ako príkaz, ale znak nezostáva aktívny) až na to, že prvá definuje príkaz csx{global}. Pre použitie aktívnych znakov v matematickom móde je lepšie nechať znaku bežný catcode a prideliť mu špeciálny aktívny matematický kód:
\begingroup \lccode`~=`x \lowercase{\endgroup \def~{\times}% }% \mathcode`x="8000Špeciálny znak nemusí byť predefinovaný kedykoľvek sa stane aktívnym — definícia príkazu pretrvá aj po návratu catcode na pôvodnú hodnotu; definícia sa stane znova dostupnou, keď sa znak opäť stane aktívnym. doc.sty : distribuované ako súčasť zdrojových súborov CTAN: latexshortvrb.sty : distribuované ako súčasť CTAN: 2etools
Občas je celkom príjemné spraviť jeden alebo dva znaky aktívnymi v parametri príkazu, aby sme uľahčili autorom písanie parametrov. Aktívne znaky môžu byť v takýchto situáciach bezpečne použité, je však treba opatrnosti.
Pri zvažovaní tejto odpovede vyvstal príklad: ašpirujúci programátor makier
na
Prvým problémom je, že Použitím techník diskutovaných v Otázke Definícia aktívnych znakov môžeme definovať:
\begingroup \catcode`\#=\active \gdef#{$\sharp$} \endgroupa:
\begingroup \lccode`\~=`\b \lowercase{\endgroup \def~{$\flat$}% }Druhým problémom je časovanie: príkaz musí spraviť každý zo znakov aktívnym predtým, než sú načítané jeho parametre. Toto znamená, že príkaz samotný nemôže mať parametre, ale musí byť rozdelený na dve časti. Píšeme teda:
\def\chord{% \begingroup \catcode`\#=\active \catcode`\b=\active \Xchord } \def\Xchord#1{% \chordfont#1% \endgroup }a príkaz môžeme použiť ako \chord{F\#} alebo \chord{Bb minor} .
Dôležité sú dve vlastnosti:
Zapamätajte si, že technika použitá v makrách ako csx{chord} je analogická
technike použitej v príkazoch ako csx{verb}; a rovnako ako csx{verb} (viď
Otázku Proč
Je bežné chcieť príkaz na vytvorenie iného príkazu, často je požadované, aby bol názov nového príkazu odvodený z parametru. LaTeX to robí celý čas, napríklad csx{newenvironment} vytvára start- a end-environment príkazy, ktorých názvy sú odvodené z názvu environment príkazu. Zjavný prístup:
\def\relay#1#2{\def\#1{#2}}nefunguje (TeX ho interpretuje ako divnú redefiníciu \# ). Trik spočíva
v použití csx{csname}, čo je TeXovské primitívum na generovanie názvov
príkazov z náhodného textu, spolu s csx{expandafter}. Uvedená definícia by
mala vyzerať:
\def\relay#1#2{% \expandafter\def\csname #1\endcsname{#2}% }S touto definíciou je \relay{blah}{bleah} ekvivalentné
csx{def}\blah{bleah} .
Všimnite si, že definícia csx{relay} vynecháva zátvorky okolo názvu príkazu v spúšťanom csx{newcommand}. Toto je z dôvodu, že nie sú potrebné (to sú v skutočnosti zriedvo) a za týchto okolností robia kód makra mirne nudnejším. Vytvorený názov nemusí byť (samozrejme) iba parameter:
\def\newrace#1#2#3{\expandafter\def \csname start#1\endcsname{% #2% }% \expandafter\def \csname finish#1\endcsname{% #3% }% }S príkazmi
\def\start#1{\csname start#1\endcsname} \def\finish#1{\csname finish#1\endcsname}by sa tieto mohli správať trochu ako LaTeXovské prostredia (environments).
Predpokladajme, že potrebujete vediet, či je parameter vášho príkazu prázdny,
teda rozoznať medzi
\def\cmd#1{% \def\tempa{}% \def\tempb{#1}% \ifx\tempa\tempbPrípad, keď chcete ignorovať parameter pozostávajúci iba z medzier (nemusí byť teda úplne prázdny), je komplikovanejší. Tento prípad je vyriešený vo fragmente kódu ifmtarg definujúcom príkazy csx{@ifmtarg} a csx{@ifnotmtarg},
ktoré rozoznajú (v opačných smeroch) medzi druhým a tretím parametrom. Kód
balíku sa objavuje aj v LaTeXovskej triede memoir .
Mnoho LaTeXovských tried (vrátane štandardnej triedy
Namiesto prepísanie celej triedy je možné použiť balíky \makeatletter \@removefromreset{figure}{chapter}a automatické prečíslovávanie sa zastaví. Potom musíte znovu definovať spôsob, akým sú čísla obrázkov (v tomto prípade) tlačené: \renewcommand{\thefigure}{\@arabic\c@figure} \makeatother(nezabudnite pre každé počítadlo, s ktorým chcete manipulovať, uskutočniť všetky kroky uvedené v csx{makeatletter} ...@ csx{makeatother}).
Technika môže byť použitá aj na zmenu pri resetovaní počítadla
vo viacúrovňovej štruktúre. Predpokladajme, že vaša trieda čísluje stránky ako
\@removefromreset{figure}{section} \@addtoreset{figure}{chapter} \renewcommand{\thefigure}% {\thechapter.\@arabic\c@figure}(príkaz csx{@addtoreset} je súčasť LaTeXu samotného).
Balík
Robustné príkazy LaTeXu sú buď „prirodzene robustné“ — nikdy nepotrebujú csx{protect}, alebo „self-protected“ (chránia sa samy) — majú csx{protect} nejakým spôsobom zabudované do svojej definície. „Self-protected“ príkazy sú robustné iba v kontexte, kde je mechanizmus csx{protect} správne spracovaný. Kedže csx{edef} je TeXovské primitívum a nie príkaz LaTeXu, telo definície csx{edef} nespracúva csx{protect} správne. Tento problém je riešený interným príkazom LaTeXu csx{protected@edef}, ktorý robí prácu csx{edef}, zatiaľ čo udržuje mechanizmus csx{protect} funkčný. Existuje zodpovedajúci príkaz csx{protected@xdef}, ktorý robí to, čo csx{xdef}.
Kedže sú tieto príkazy interné, musia byť samozrejme pozorne sledované (viď
Otázku
Voliteľné parametre v makrách definovaných pomocou csx{newcommand} nepracujú úplne rovnakým spôsobom ako voliteľný parameter csx{section}. Štandardná hodnota voliteľného parametru csx{section} je hodnota povinného parametru, ale csx{newcommand} vyžaduje, aby ste štandardné hodnoty vedeli dopredu. Potrebný trik je použitie makra v štandardnom parametri: \newcommand\thing[2][\DefaultOpt]{% \def\DefaultOpt{#2}% ...% }
Predpokladajme, že máme LaTeXovské počítadlo, ktoré sme definovali pomocou
Existuje interná premenná LaTeXu „aktuálne návestie“, ktorá si pamätá
poslednú vec s možnosťou návestia, ktorú LaTeX spracoval. Mohli by ste
(ak by ste na tom trvali) tú hodnotu nastaviť relevantným príkazom TeXu
(zabezpečiac potrebné opatrenia, aby interný príkaz fungoval) — ale nie je
to potrebné. Ak namiesto hore uvedených metód použijete
Otázka Jak dostat Riešením je použitie nejakej verzie csx{label} mechanizmu na zistenie, na ktorom konci stránky ste. Hodnota počítadla strán objavujúca sa v príkaze csx{pageref} bola vložená do behu výstupnej rutiny a je teda bezpečná. csx{pageref} samotný však bezpečný nie je: môžete dúfať, že \ifthenelse{\isodd{\pageref{foo}}}{odd}{even}spraví potrebné, ale o balíkoch babel aj hyperref sa vie,
že zasahujú do výstupu csx{pageref}; buďte opatrní!
Balík
Štandardne pri vytvorení návestia toto preberie vzhľad označeného počítadla:
konkrétne je nastavené na csx{the}
\ref{parent-item}(\ref{child-item})by bolo nudné a náchylné k chybám. Bolo by naviac nevhodné, kedže by ste konštruovali vizuálnu reprezentáciu, ktorá je neflexibilná (nemohli by ste vôbec zmeniť všetky odkazy na prvky zoznamu jedným ťahom).
LaTeX má v skutočnosti príkaz formátujúci návestia zabudovaný do každej
definície návestia; štandardne je neplatný, ale je užívateľovi dostupný na
programovanie. Pre ľubovolné návestie
\renewcommand*\refstepcounter[1]{% \stepcounter{#1}% \protected@edef\@currentlabel{% \csname p@#1\expandafter\endcsname \csname the#1\endcsname }% }So zmenou na správnom mieste teraz môžete napríklad zmeniť návestia na všetkých vnútorných zoznamoch pridaním nasledujúceho kódu do preambuly:
\makeatletter \renewcommand{\p@enumii}[1]{\theenumi(#1)} \makeatotherToto zabezpečí, že návestia číslovaných zoznamov druhej úrovne vyzerajú ako „1(a)“ (a tak ďalej). Analogická zmena funguje pre ľubovolné počítadlo používané v príkaze csx{label}.
Balík
\labelformat{enumii}{\theenumii(#1)}Uvedený príklad, ktorý môžeme uskutočniť viacerými rozličnými spôsobmi, bol označený zastaralým objavením sa balíku enumitem , ktorý je
diskutovaný v odpovedi o dekorovaní číslovaných zoznamov
(Otázka Pekne číslované zoznamy).enumitem.sty : distribuované ako súčasť CTAN: bezosfncylab.sty : CTAN: fncylab
Ak sa nad tým zamyslíte, zistíte, že Knuthova syntax definície príkazov:
\def\blah#1#2 ... #9{je limitovaná na 9 parametrov. Neexistuje priamy spôsob ako toto obísť. Ako by ste vyjadrili desiaty parameter a zaistili, že syntax nepohltí iné správne použitie? Ak skutočne potrebujete viac než 9 parametrov, správny postup je:
\def\blah#1#2 ... #9{% \def\ArgI{{#1}}% \def\ArgII{{#2}}% ... \def\ArgIX{{#9}}% \BlahRelay } \def\BlahRelay#1#2#3{% % parametre 1-9 sú teraz % \ArgI-\ArgIX % parametre 10-12 sú % #1-#3Táto technika je ľahko rozšíriteľná TeXovskými virtuózmi, ale zle sa odporúča.
Používatelia LaTeXu sa majú o niečo lepšie, kedže im stačí iba zadať počet
parametrov v príkaze csx{newcommand}, ktorý definuje každú časť prevodného
mechanizmu: Knuthove reštrikcie platia pre csx{newcommand} ako aj pre
csx{def}. Používatelia LaTeXu však tiež majú cestu von z takejto
barbarskej syntaxe príkazov – balík
\flowerinstance{species=Primula veris, family=Primulaceae, location=Coldham's Common, locationtype=Common grazing land, date=1995/04/24, numplants=50, soiltype=alkaline }Výhoda takejto „ukecanosti“ je automatická zrozumiteľnosť. Sádzač si nemusí pamätať, že parameter 12 je soiltype atď. Príkazy môžu byť kopírované
z poznámok k políčkam rýchlo a presne.keyval.sty : distribuované ako súčasť CTAN: graphics
Ak ste si už prečítali Otázku Ako prekročiť limit 9 parametrov, môžete zrejme riešenie problému uhádnuť: predávanie príkazov. LaTeX povoľuje príkazy s jediným voliteľným parametrom takto: \newcommand{\blah}[1][Default]{...}
Správne môžete buď s prítomným voliteľným parametrom ( Pre definovanie príkazu s dvoma voliteľnými parametrami použijeme techniku predávania nasledovne: \newcommand{\blah}[1][Default1]{% \def\ArgI{{#1}}% \BlahRelay } \newcommand\BlahRelay[1][Default2]{% % prvý voliteľný parameter je teraz % v \ArgI % druhý je v #1 ...% }csx{BlahRelay} môže mať samozrejme toľko povinných parametrov, koľko je povolených po zabratí jedného „miesta“ vlastným voliteľným parametrom, teda 8.
Varianty csx{newcommand} (a priateľov) s názvami ako csx{newcommandtwoopt}
sú dostupné v balíku
Príkaz s dvomi voliteľnými parametrami sa približuje hranici toho, čo je
ešte rozumné: techniku môžete zjavne rozšíriť tak, aby poskytovala toľko
volteľných parametrov, koľko si viete predstaviť. Pozrite si však poznámky
k použitiu balíku Alternatívnym prístupom je poskytovaný programom newcommand od Scotta Pakina, ktorý vezme názov príkazu a definíciu množiny parametrov príkazu (v celkom zrozumiteľnom jazyku) a ako výstup poskytne TeXovské/LaTeXovské makrá umožňujúce definíciu príkazu. Príkaz vyžaduje, aby bol na vašom systéme nainštalovaný python.
Distribúcia
Obecné problémy úpravy vzhľadu nadpisov sekcií sú dosť komplexné a sú pokryté odpoveďou na Otázku Vzhled nadpisů. Ľudia však často chcú zmeniť iba vzhľad čísla sekcie v nadpise a niektorým z nich nevadí písanie pár makier. Táto odpoveď je pre nich. Spôsob sadzby čísla sekcie určuje príkaz csx{@seccntformat}, ktorý dostane „názov“ (section, subsection, ...) nadpisu ako parameter. Obvykle dá na výstup iba číslo sekcie, a potom csx{quad} medzeru. Predpokladajme, že chcete dať za každé číslo sekcie (subsekcie, subsubsekcie, ...) bodku. Triviálna zmena môže byť implementovanáa jednoduchou modifikáciou príkazu:
\renewcommand*{\@seccntformat}[1]{% \csname the#1\endcsname.\quad } Veľa ľudí (z určitého dôvodu) chce bodku iba za číslo sekcie. Pre dosiahnutie tochto cielu musíme zmeniť chovanie csx{@seccntformat} podľa jeho parametru. Nasledujúca technika je tak trochu plýtvaním, ale stále je dostačujúco efektívna:
\let\@@seccntformat\@seccntformat \renewcommand*{\@seccntformat}[1]{% \expandafter\let\expandafter\@tempa \csname @seccntformat@#1\endcsname \ifx\@tempa\relax \expandafter\@@seccntformat \else \expandafter\@tempa \fi {#1}% }Kód sa pozrie či bol definovaný príkaz druhej úrovne. Ak áno, použije ho, inak použije pôvodný. Príkaz druhej úrovne na zavedenie bodiek (iba) za čísla sekcií má rovnakú definíciu ako pôvodná verzia „všetky úrovne zhodne“:
\newcommand*{\@seccntformat@section}[1]{% \csname the#1\endcsname.\quad }Všimnite si, že všetky definície príkazov v tejto odpovedi sa týkajú interných príkazov LaTeXu (viď Otázku \@ a @ ve jménech maker), takže uvedený kód by mal
byť radšej v súbore balíku.
Triedy
Napísali ste si vlastné prostredie
Mohli by ste vydať obmedzenie, že vaši užívatelia musia vždy umiestniť znak
„ Tajomstvom prostredí LaTeXu je interný príznak spôsobujúci ignorovanie nechcených medzier. Našťastie internú formu používať nemusíte: od roku 1996 obsahuje LaTeX používateľský príkaz csx{ignorespacesafterend}, ktorý interný príznak nastavuje.
Existuje viacero dôvodov, prečo by ste mohli chcieť vedieť definície príkazov LaTeXu: od najjednoduchšej obyčajnej zvedavosti, až po potrebu opraviť niečo, aby to fungovalo tak, ako chcete vy. Nič z uvedeného nie je čistým motívom, ale vedomosť a skúsenosť zriedkakedy prichádzajú prostredníctvom najčistejších motívov. Najjednoduchšou odpoveďou je skúsiť csx{show} v LaTeXovskom behu berúcom príkazy z terminálu:
*\show\protected@edef > \protected@edef=macro: ->\let \@@protect \protect \let \protect \@unexpandable@protect \afterassignment \restore@protect \edef .(Výstup je preusporiadaný z dosť mätúcej verzie, ktorú TeX produkuje.) Teraz sa môžeme zamyslieť nad csx{@unexpandable@protect}:
*\show\@unexpandable@protect > \@unexpandable@protect=macro: ->\noexpand \protect \noexpand .a začíname pozorovať, ako funguje jedna časť mechanizmu csx{protect} (môžeme asi celkom bezpečne uhádnuť, čo robí csx{restore@protect}). Mnoho príkazov jadra je deklarovaných robustne:
*\show\texttt > \texttt=macro: ->\protect \texttt .takže csx{show} veľmi nepomôže. Definujte príkaz csx{pshow} podľa nasledujúcej ukážky a použite ten:
*\def\pshow#1{{\let\protect\show #1}} *\pshow\texttt > \texttt =\long macro: #1->\ifmmode \nfss@text {\ttfamily #1}% \else \hmode@bgroup \text@command {#1}% \ttfamily \check@icl #1\check@icr \expandafter \egroup \fi .Všimnite si, že názov chráneného príkazu je „základný“ príkaz s pripojenou medzerou. Toto je trochu obtiažne viditeľné na pár miestach vyššie. (Výstup bol znova upravený.)
Ak máte flexibilný textový editor, rovnaké zistenie môžete komfortnejšie
uskutočniť prezrením súboru
Súbor Vytlačené jadro je dobrá vec, ale ťažko sa s ním manipuluje a často iba sedí na polici zriedkavo využívaný. Jedným problémom je rozdielna dokumentácia: obsiahnuté sú moduly od veľmi dobre zdokumentovaných, cez moduly obsahujúce iba automatickú dokumentáciu, až po moduly bez akejkoľvek užitočnej dokumentácie.
Každý %%% From File: ltdefns.dtxAk sa na súbor pozrieme, ltdefns.dtx obsahuje obsiahlu rozpravu
o metódach spracovania ochrán (csx{protect}) a obsahuje tiež určitú
automaticky skonvertovanú LaTeX 2.09 dokumentáciu.
Jadro samozrejme nie je celý LaTeX: váš príkaz môže byť definovaný v jednom
zo súborov LaTeXovských tried alebo balíkov. Definíciu
csx{thebibliography} napríklad nájdeme v triede %% This is file `article.cls', %% generated with the docstrip utility. %% %% The original source files were: %% %% classes.dtx (with options: `article')takže potrebujeme formátovať súbor classes.dtx , aby sme videli definíciu
v kontexte.
Všetky tieto .dtx súbory sú na CTANe ako súčasť hlavnej distribúcie
LaTeXu.
Je bežné mať veci číslované po kapitolách (napríklad v štandardných triedach
Ako by ste to spravili sami? Môžete chcieť číslovať napríklad algoritmy po sekciách. Ak tieto veci definujete ručne, vzťah deklarujete pri definícii počítadla:
\newcounter{new-name}[master]Uvedený kód nám hovorí, že pri každom zvýšení počítadle Čo ale v prípade, že máte nespolupracujúci balík definujúci veci za vás, ale tento neposkytuje programátorovi rozhranie na prinútenie počítadiel správať sa tak, ako chce? Príkaz csx{newcounter} používa interný príkaz LaTeXu a vy ho môžete využiť tiež:
\@addtoreset{new-name}{master}(pamätajte si však, že to musí byť medzi csx{makeatletter} a csx{makeatother} alebo vo vašom vlastnom balíku).
Balík
\counterwithin*{corollary}{theorem}spraví z počítadla corollary podriadené počítadlo (slave) počítadla theorem. Príkaz bez hviezdy:
\counterwithin{corollary}{theorem}spraví to isté a zároveň redefinuje csx{thecorollary} ako <číslo teorémy>.<číslo dôsledku>, čo je dobrou schémou, ak sa niekedy chcete odkazovať na dôsledky — môže existovať veľa „dôsledkov 1“ v každom dokumente, takže je dobré zviazať jeho číslo s počítadlom theorem, ku ktorému patrí. Toto platí asi pri každom počítadle vo vnútri iného. Ak nepoužívate chngcntr , pre potrebné techniky si
pozrite Otázku Predefinovanie csx{the-}príkazov počítadiel.
Všimnite si, že postup nefunguje, ak je nadriadené (master) počítadlo
chngcntr.sty : CTAN: chngcntrperpage.sty : CTAN: perpage
Vdovy (posledné riadky odstavcov na začiatku strany) a siroty (prvé riadky
odstavcov na konci strany) prerušujú čitateľa a obecne sú považované za zlú
formu; TeX/LaTeX vykonáva určité opatrenia, aby sa im vyhol, úplne
automatická prevencia je často nemožná. Ak sádzate vlastný text, zvážte miernu
zmenu slov tak, aby zlom dopadol inak.
Rutina pre vytváranie stránky pri jej formovaní berie na vedomie
csx{widowpenalty}
a csx{clubpenalty} (vzťahuje sa k sirotám!). Tieto pokuty (penalties) sú
obvykle nastavené na strednú hodnotu Keď ste už vyčerpali automatické opatrenia a máte konečný návrh, ktorý chcete „vypilovať“, musíte použiť ručné opatrenia. Zbaviť sa siroty je jednoduché: pred odstavec uveďte csx{clearpage} a odstavec nemôže začať na zlom mieste.
Zbaviť sa vdovy je komplikovanejšie. Ak je odstavec dlhý, mohlo by sa dať
vysádzať ho „tesne“: vložte csx{looseness}
\enlargethispage{-\baselineskip}môže vytvoriť (viac-menej) akceptovateľnú „dvojriadkovú vdovu“. (Všimnite si: csx{looseness} =1 zvyšujúc dĺžku strany o jednotku málokedy
funguje — dotyčný odstavec má zvyčajne jednoslovný posledný riadok, ktorý
nevyzerá oveľa lepšie ako priamo vdova.)
LaTeX dělí poznámky pod čarou na více stránek, pokud si myslí, že to je to nejlepší, co může udělat. Typicky se tak stane, pokud poznámka pod čarou vyjde na samotný konec stránky, a tím ji může přeplnit. LaTeX by se mohl pokusit problém vyřešit ochuzením stránky o poznámku a taky řádek obsahující značku poznámky, ale jeho priority mu poradí, že rozdělení rozdélení poznámky je preferováno.
Jako vždy je nejlepším řešením problému změnit váš text tak, aby se v něm
tento problém nevyskytl. Uvažujte, zda by se poznámka ve vašem textu mohla
objevit na předchozí či další stránce. Pokud to není možné, můžete
docílit toho, že LaTeX začne jinak „pohlížet“ na tyto priority:
ty jsou ovládané příkazem
Alternativní technika spočívá v malém podvodu na
LaTeX, kdy pomocí parametrů příkazu
Řešením tohoto problému by mohlo být zapamatování si, na kterou
stranu stránky má být použit
Napísali a spracovali ste zjavne zmysluplný text, ale výsledok neobsahuje ani stopu po niektorých písmenách, ktoré ste napísali. Pravdepodobným dôvodom je, že vybraný font neobsahuje reprezentáciu dotyčných znakov.
Ak napríklad napíšem „that will be GBP{}44.00“ do obyčajného
TeXovského/LaTeXovského dokumentu alebo si vyberiem font
Missing character: There is no ^^a3 in font cmr10! Missing character: There is no 3 in font rsfs10!(prvá demonštruje neochotu môjho TeXu vysporiadať sa so znakmi s osembitovou znakovou sadou, zatiaľ čo príklad rsfs10 ukazuje, že TeX
zaznamenáva dotyčný chybný znak, ak si myslí, že je to možné).
Trochu lepšie pochopiteľné sú diagnostiky, ktoré dostanete z
dvips: Warning: missing glyph `Delta'Proces generujúci metriky pre používanie fontu generuje inštrukciu pre dvips , aby produkovalo tieto diagnostiky, aby ich neprítomnosť
v tlačenom výstupe bola menej prekvapujúca, než by mohla byť. Dosť glyfov
poskytnutých v Knuthovych textových kódovaniach a v Corkovskom kódovaní nie je
v Adobe fontoch dostupných. V týchto prípadoch existuje vysádzaný symbol
týchto znakov: dvips vytvára čierny obdĺžnik veľkosti fontu.
Ľudia sú stále prekvapení, že jednoduché príkazy požierajú medzeru, ktorá za nimi nasleduje: je to jednoducho tak. Efekt vzniká pre spôsob práce TeXu, Lamport popisuje riešenie (umiestnite jedny zložené zátvorky za vyvolanie príkazu) v popise syntaxe LaTeXu. Takže požiadavka je vlastne súčasťou definície LaTeXu. Anglické FAQ je napríklad napísané s definíciami vyžadujúcimi písanie csx{fred{relax}} pre takmer všetky vyvolania makier bez ohľadu na to, či je nasledujúca medzera potrebná: anglické FAQ je však písané veľmi oddanými (a podľa niekoho zvláštnymi) ľuďmi. Mnoho používateľov si myslí, že písanie tých všetkých zložených zátvoriek sa veľmi rýchlo stane veľmi únavným, a radšej by ich vôbec nepísali.
Alternatívnou štruktúrou, ktorá neporušuje návrh LaTeXu, je napísať
csx{fred}csx{ } — príkaz csx{ } je „samoukončovací“ (ako
Ak je aj ten jeden znak priveľa, balík
\usepackage{xspace} ... \newcommand{\restenergy}% {\ensuremath{mc^2}\xspace} ... and we find \restenergy available to us...Príkaz csx{xspace} musí byť poslednou vecou v definícii vášho makra (ako v príklade); nie je to úplne bezchybné, ale poradí si s väčšinou situácii v texte.
Balík
„Veľké“ matematické symboly štandardne zostávajú rovnakej veľkosti nezávisle
na veľkosť fontu textu dokumentu. Existuje pre to dobrý dôvod: fonty
Toto správanie však mätie očakávania používateľov a môže viesť k trochu
zvláštne vyzerajúcim dokumentom. Ak napriek varovanie chcete, aby sa fonty
dali zväčšovať, použite balík
V raných časoch LaTeX 2e bol jediním spôsobom používania T1 kódovania
balík
Napriek tomu tu balík Generovanie takýchto kódov znakov by mohla byť jednoduchá záležitosť, keby T1 kódovanie zodpovedalo ľubovolnému široko podporovanému kódovaciemu štandardu, pretože v takomto prípade by ste mohli očakávať generovanie kódov znakov klávesnicou. T1 kódovanie je však zmesou rôznych štandardných kódovaní a zahŕňa kódové miesta v oblastiach tabuľky, ktoré štandardné kódovanie špecificky vylučujú, takže žiadne T1 klávesnice neboli (a nikdy nebudú) vyrobené.
Balík
Štandardné vstupné kódovanie pre západnú Európu (čakajúc príchod Unicode) je ISO 8859–1 (bežne známe podtitulom štandardu „Latin-1“). Latin-1 je v pokrytí kódových miest pozoruhodne blízko TeXovskému T1 kódovaniu.
Prečo by sme sa mali za týchto okolností trápiť s Nerobí sa to ale pre množstvo drobných dôvodov:
inputenc –fontenc vyzerá pomalá a ťažkopádna,
je však bezpečná.
Prostredie
\begin{eqnarray} a & = & b + c \\ x & = & y - z \end{eqnarray}nie sú rozostupy okolo znakov `=' tie definované v metrike fontu, z ktorého pochádza glyf — sú to csx{arraycolsep}, čo môže byť nastavené na veľmi divnú hodnotu z dôvodov spojených so skutočnými poliami na inom mieste dokumentu.
Používateľa oveľa lepšie obslúži sada AMSLaTeX, ktorá poskytuje prostredie
\begin{align} a & = b + c \\ x & = y - z \end{align} AMSLaTeX : CTAN: amslatex
LaTeX definuje príkazy „inline“ a „display“ matematiky, zjavne analogické k tým, čo sú odvodené z TeXovských príkazov na zátvorkovanie matematických sekvencií so znakmi doláru (alebo dvojicami znakov doláru).
Ako sa ukázalo, LaTeXovské inline zoskupovanie matematiky
csx{(}
Za týchto okolností sa často nájdu používatelia LaTeXu majúci nejaké
skúsenosti s používaním Plain TeXu, ktorí jednoducho predpokladajú, že
LaTeXovské zoskupovanie display matematiky csx{[}
Bohužiaľ sa mýlia: ak LaTeXovský kód bude upravovať display matematiku,
môže tak učiniť iba úpravou csx{[} a csx{]}. Najzjavnejším spôsobom, ako sa
to prejaví, je, že voľba triedy
Existujú aj zákernejšie efekty (hlavne s balíkom
PiCTeX je poměrně náročný na systémové zdroje. Naštěstí většina
moderních TeXových distribucí nabízí poměrně dost prostoru a moderní
počítače již jsou oproti svým předchůdcům o mnoho rychlejší, takže
uživatele tato skutečnost nemusí znervózňovat. Nicméně PiCTeX má
jednu nešťastnou tendenci – rád zaplňuje pole s pevnou délkou alokovaná
TeXem – zvláště 256 „rozměrových“ registrů. To je problém zvláště,
pokud v LaTeXu používáte pictex a další balíky, které
potřebují stejné systémové zdroje. Pokud k tomu dojde, pak vám LaTeX
vypíše chybovou hlášku Když nemůžete použít e-TeX, musíte změnit PiCTeX; bohužel jeho autor není již delší dobu v TeXovém světě aktivní, proto se musíte uchýlit k „patchování“. Dostupná jsou dvě řešení:
| |||
|