momente şi schiţe de informatică şi matematică
To attain knowledge, write. To attain wisdom, rewrite.

Metafont pentru lemniscata lui Bernoulli (partea a doua)

LaTex | Metafont | lemniscată
2018 jun

"bernu.pdf" testează cele 4 simboluri definite prin Metafont mai jos (şi totodată, dar mai puţin important - sugerează motivaţia şi ideile pe care am bazat construcţia acestora):

Am obţinut pagina PDF redată mai sus compilând cu xelatex fişierul "bernu.tex", în care avem în preambul şi declaraţia:

\usepackage{bernu}  % 'bernu.sty'  (plus 'Ubernu.fd' şi 'bernoulli.mf')

Executând această comandă, xelatex a depistat şi a încărcat fişierul "bernu.sty" (încercând apoi să interpreteze conţinutul respectiv):

\DeclareSymbolFont {bernu} {U}{bernu}{}{}
\DeclareMathSymbol \bernoulli {\mathord}{bernu}{"00}
\DeclareMathSymbol \bernoullirot {\mathord}{bernu}{"1E}
\DeclareMathSymbol \circrot {\mathord}{bernu}{"10}
\DeclareMathSymbol \circrotz {\mathord}{bernu}{"11}
\endinput

Aici este declarat un font cu cel puţin patru simboluri, anume pe intrările de index 0, 16 (notat în hexazecimal, prin "10), 17 şi 30 (=16+14="1E în hexazecimal). Intrările în tabelul caracterelor acestui font corespund codificării "U" (particulară, sau "Unknown"; în codificarea standard "OT1", pe intrarea 0 am găsi 'Γ '). Familia acestui font este desemnată prin "bernu" (iar aici nu prea este cazul de a lărgi familia, încât am indicat "{}{}" pentru atributul de grosime –"normal", "bold", etc.–  şi cel de formă –"normal" sau "roman", "italic", etc.).

Prin comenzile introduse de "DeclareMathSymbol" vom putea accesa caractere din acel font; astfel, prin comanda boldată pe linia următoare (care corespunde în LaTeX primului rând din pagina PDF redată mai sus):

{\em lemniscata lui Bernoulli} $\bernoulli$ are centru de simetrie

va fi accesat simbolul de cod "00 (intrarea 0 din tabelul caracterelor fontului "bernu"); acesta a fost declarat ca simbol matematic ordinar (nu relaţional, sau alfabetic, ci din categoria "\mathord") şi trebuie folosit în context matematic - comanda respectivă trebuind să fie încadrată de câte un simbol "dollar".

Întâlnind această declaraţia de font, xelatex (ca şi alte compilatoare de LaTeX) va verifica întâi dacă sunt prezente deja, elementele necesare folosirii fontului respectiv - caz în care va începe să formateze pagina (conform comenzilor LaTeX intercalate în textul propriu-zis al documentului, interpretate în contextul creat prin specificaţia iniţială documentclass{article}), constituind în final documentul PDF corespunzător.

Compilatorul TeX (fie xelatex, fie pdflatex, etc.) caută două elemente: un fişier TFM ("TeX font metrics") şi un fişier PK ("packed font", "bitmap"); pe baza informaţiilor metrice, TeX creează o matriţă a paginii (conţinând boxe dreptunghiulare pentru fiecare caracter, cuvânt, linie de text şi paragraf, aliniate şi spaţiate pe orizontală şi pe verticală corespunzător informaţiilor metrice din fişierele TFM asociate fonturilor implicate); apoi, matriţa creată este "umplută" cu formele grafice ("bitmap") indicate în fişierele PK (eventual, aceste forme grafice vor fi necesare programelor de vizualizare sau tipărire a documentului produs de TeX; "eventual" - pentru a avea în vedere şi fonturile rezidente pe imprimată, caz în care nu mai sunt utilizate fişierele PK).

Dacă TeX nu reuşeşte să depisteze aceste elemente –cum este cazul la prima compilare a fişierului "bernu.tex"– atunci TeX va lansa programul mf (compilatorul de MF - Metafont) pentru a constitui ad-hoc fişierul TFM şi apoi va lansa mktexpk pentru a constitui fişiere PK.

Desigur, aceste construcţii ad-hoc sunt posibile numai dacă TeX are de unde lua numele fişierului pe care să-l remită compilatorului mf; procedura adoptată este următoarea: TeX alipeşte "U" şi "bernu" (atributele de codificare şi de familie specificate în declaraţia \DeclareSymbolFont, din fişierul citit iniţial "bernu.sty") şi caută fişierul "Ubernu.fd" ("font definition"):

\DeclareFontFamily{U}{bernu}{}
\DeclareFontShape{U}{bernu}{}{}{<-> [3.5] bernoulli}{}

De aici se găseşte numele de transmis compilatorului MF - anume, "bernoulli.mf"; de regulă, se includ şi informaţii de mărime (sub forma "{<12-14.4> bernoulli12 <17-25> bernoulli17}" - prevăzând câte un fişier MF pentru fiecare caz, evitând scalarea mecanică), dar aici am indicat doar un "factor de scalare" (alegând [3.5]), lăsând TeX să facă ce ştie…

Programele angajate în mediul LaTeX operează în mod transparent (eventual, chiar şi interactiv), informând (pe ecran şi în fişiere ".log") asupra acţiunilor întreprinse; citind ce afişează xelatex (dar desigur, nu ajunge; mai trebuie parcurse şi anumite documentaţii, accesibile la CTAN de exemplu), putem sesiza cam toate lucrurile evidenţiate mai sus. Transcriem aici –cu mari omisiuni şi simplificări, marcând itemurile care ne interesează– ceea ce afişează TeX pe parcursul primei compilări a fişierului "bernu.tex":

vb@Home:~/4_art/Latex/aVB/7$ xelatex bernu.tex
...
(./bernu.tex
    ...
    ( /usr/share/texlive/texmf-dist/tex/latex/base/article.cls
        Document Class: article 2014/09/29 v1.4h Standard LaTeX document class
        ... )
    ...
    ( ./bernu.sty )    No file bernu.aux.
    ...
    ( ./Ubernu.fd )

    ... Font shape `U/bernu//' will be scaled to size 42.0pt on input line 14.
    ... Running mf-nowin ... \mode:=ljfour; mag:=1; ... input bernoulli
    This is METAFONT, Version 2.7182818 ... (preloaded base=mf)
    ( /home/vb/4_art/Latex/aVB/7/bernoulli.mf [0] [30] [16] [17] )
    Font metrics written on bernoulli.tfm. 
    Output written on bernoulli.600gf (4 characters, 12280 bytes).
    mktexpk: /home/vb/4_art/Latex/aVB/7/bernoulli.600pk: successfully generated.
    ... ... ...
    [1] ( ./bernu.aux )
    ... ... ...
)
Output written on bernu.pdf (1 page).    Transcript written on bernu.log.

Afişarea foloseşte (eventual, imbricat) sintaxa "(<nume_fişier> <prelucrări>)" - însemnând că TeX citeşte un anumit fişier şi face prelucrările impuse de conţinutul acestuia (iar o variantă de genul "[1] (./bernu.aux)", înseamnă că TeX scrie ceva în fişierul respectiv). Vedem că secvenţa "(./bernu.tex ... ... )" încorporează toate prelucrările - deci, după ce TeX încarcă în memorie 'bernu.tex' (din directorul curent), toate acţiunile sale (până la ultima linie) decurg interpretând pas cu pas conţinutul acestui fişier (încheind cu scrierea finală în "bernu.pdf").

Întâi sunt desfăşurate operaţiile asociate declaraţiei "\documentclass[12pt]{article}" (prima linie din "bernu.tex"); aceste operaţii –foarte numeroase, omise mai sus– sunt prespecificate într-un anumit "format" (depinzând de compilator: "format=xelatex" diferă de "format=pdflatex").

Prima operaţie care ne interesează aici este "(./bernu.sty)". După ce este încărcat în memorie "bernu.sty", Tex constată că nu există un fişier "bernu.aux"; dacă ar fi depistat acest fişier, atunci TeX ar fi dedus că "a mai trecut pe aici", încât ar putea evita repetarea unor operaţii (ocupându-se atunci numai de modificările de text efectuate între timp de către autorul documentului).

Mai departe (înţelegând că este vorba de prima compilare), Tex caută fişierul "Ubernu.fd" (al cărui nume îl constituie plecând de la "\DeclareSymbolFont" pe care a citit-o din "bernu.sty" - cum am arătat deja mai sus) şi îl încarcă în memorie; urmând apoi declaraţia "\DeclareFontShape" din acest fişier, TeX lansează compilatorul de Metafont asupra fişierului "bernoulli.mf" - rezultând fişierul metric "bernoulli.tfm" şi fişierul grafic "bernoulli.600gf" (care va fi compactat ulterior în "bernoulli.600pk", prin invocarea programului mktexpk). Această secvenţă de operaţii se încheie scriind în directorul curent fişierul "bernu.aux" (conţinând comanda "\relax", încât la o compilare ulterioară a fişierului "bernu.tex" - presupunând că n-a fost şters fişierul "bernu.aux" - TeX nu va mai repeta operaţiile tocmai descrise).

Fiindcă în "bernu.tex" am folosit simbolurile respective şi sub comenzi de scalare (cum ar fi "\hbox\Large{...}") şi pe de altă parte, fiindcă am prevăzut factorul de scalare "[3.5]" în declaraţia "\DeclareFontShape" - TeX apelează iarăşi mf şi mktexpk, producând încă două-trei fişiere grafice ("bitmap") care scalează (şi ajustează corespunzător noii rezoluţii) simbolurile respective (de regulă, versiunile scalate ale unui font partajează fişierul metric ".tfm" al fontului, dar au asociate fişiere grafice ".pk" diferite).

În cele de mai sus am presupus existenţa fişierului "bernoulli.mf"; acesta reprezintă codul-sursă esenţial (celelalte fişiere-sursă din pachetul "bernu" au în fond un conţinut standard) şi preferăm să amânăm pentru partea a treia, constituirea lui (experienţa expunerii minuţioase a lucrurilor după ce le vei fi terminat –nu doar o simplă revedere– ne-a învăţat mereu că partea esenţială a acestora trebuie eventual regândită şi rescrisă…).

vezi Cărţile mele (de programare)

docerpro | Prev | Next