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

La carte, cu momente şi schiţe de informatică

LaTex
2020 feb

De-a lungul timpului mi-am zis

Acum vreo 10 ani mă apucam de aplicaţiile de şah care se văd pe acest site; am însăilat „povestea” dezvoltării lor în [1] (sintetizând „momente şi schiţe” din mai-august 2012, asupra widget-ului pgnbrw()) şi în [2] (oct.–dec. 2017). Între timp, am aflat şi de la alţii poveşti ("M-a preocupat de a lungul timpului sahul si informatica…") şi am mai citit câte ceva din cărţile lui Knuth.

Având mereu timp şi de învăţat (uneori şi de zis), prin octombrie 2019 mi-am zis două sau trei lucruri: să reiau pgnbrw() – meritând să ţin cont şi de unele aspecte introduse în 2015 de ECMAScript (declaraţia let pentru localizarea variabilelor, „funcţii săgeată”, „şabloane literale”, iterarea for...of); simultan – să scriu o carte în care să reflectez dezvoltarea lucrurilor (evidențiind progresiv și corelând cunoștințele necesare): „Modelarea în browser a partidei de şah”.

Am deja experienţa unor lucrări de mici dimensiuni scriind ca de obicei în gedit şi folosind LaTeX (v. RecMat şi eseu-PS.pdf); dar pentru a face o carte, văd că sunt încă de învăţat multe lucruri (a vedea la CTAN, memoir, scrbook, etc.) – de care chiar n-aveam habar prin 1995 (şi ceva), când scriam în Microsoft-Word "Limbaje şi Calculator" (voi fi avut noroc, s-o public: Ed. PETRION 1998; 288p., ISBN: 9739116450), în care (formulând concis şi general, prin minunatul efect al distanţei temporale intervenite) deduceam valenţele comune de structură şi funcţionare ale microprocesorului plecând de la scopul acestuia de a executa în corelaţie cu sistemul de operare, programe scrise în limbaje de nivel înalt şi constituiam în limbaj de asamblare un model consistent de „numere mari”, cu diverse aplicaţii.

Cu naivitatea obişnuită – amânam pentru sfârşitul lucrului, întrebările esenţiale (de natură practică). De ce scrii mata o carte? Ca s-o publici (fiind ea originală şi poate unică pe acea temă)Cine s-o publice? Investigând în final cum stau lucrurile, am constatat fireşte că peste tot, scopul principal este acela de a vinde; apoi – editurile nu publică pe cheltuială proprie, decât autori consacraţi (sau măcar, oblăduiţi academic); apoi – poţi publica tu însuţi, investind o anumită sumă; iar vânzarea este influenţată decisiv de locul, cantitatea şi calitatea reclamei instituite cărţii respective.

Împărţirea lucrurilor

Ar fi de recunoscut întâi, că m-am apucat să rescriu pgnbrw() numai fiindcă mă gândeam să scriu o carte (zicându-mi că „voi vedea după aceea, ce fac cu ea”); primul lucru clar, a fost titlul cărţii (menţionat mai sus). Al doilea lucru imediat clar, făcut înainte de toate şi dovedit neaşteptat de simplu (pe un sistem Ubuntu-Linux) – am instalat TeX Live 2019 (în $HOME/texlive/2019), pentru a dispune de ultimele versiuni ale pachetelor şi programelor care alcătuiesc ecosistemul LaTeX.

Lucrurile (rămânând în sfera „nepractică”) se împart între: ce are de spus autorul, ce mai trebuie spus pe lângă ce are de spus şi ce nu mai trebuie spus.

Cu privire la „ce are autorul de spus”, Nae Caranfil a introdus o parabolă superbă în filmul său „Filantropica” – anume, în zicerea inimitabilă a lui Gheorghe Dinică (as "Pavel Puiuţ"): „Cine nu spune-o poveste NU-primeşte-pomană!”.

Dar oricine dezvoltă pas cu pas o aplicaţie nebanală, netezind felurite subtilităţi – ar avea deja, o poveste de spus. Se poate evoca un exemplu măiestru: cărţile lui Knuth The TeXbook şi The METAFONTbook – în care autorul explică „pas cu pas” programele sale "TeX" şi "METAFONT" (de la care s-a fundamentat „tipografia digitală”).

Este bine să lămurim ce nu mai trebuie spus. Pe parcursul dezvoltării aplicaţiei avem de folosit HTML, CSS, javaScript, ba chiar şi Bash, AWK sau Perl; ar fi chiar stupid să ne apucăm să expunem (ca într-un manual obişnuit) cunoştinţele de bază despre unul şi altul dintre aceste limbaje – fiindcă oricând este cazul, se poate consulta Wikipedia (cu folos şi deschideri net superioare vreunui "Capitol introductiv").
Implicit, întrezărim răspunsuri la întrebarea omisă mai sus „Cine s-o citească?” – probabil că nu poate fi recomandată de "programa şcolară" curentă, după care: există un singur limbaj, "si plas plas" şi "pseudocod"; dacă ai de scris un program C++ trebuie să deschizi CodeBlocks; dacă ai de scris un text, trebuie să foloseşti Microsoft-Word (şi tot asemenea învăţăminte, de bază pentru formarea competenţelor digitale şi susţinerea bac-ului).

Folosim atâtea limbaje (par multe, într-adevăr) fiindcă este fie necesar, fie util (şi nicidecum, pentru „paradă”). Ca să dăm un exemplu: avem de formulat uneori structuri HTML sau CSS lungi şi cu aspecte repetitive; în loc să ne căznim să le edităm manual – le putem genera „automat” printr-o comandă AWK simplă.

Făcând o aplicaţie pentru browser, avem de folosit împreună HTML, CSS şi JS (capabilităţile specifice browserului) şi avem de subliniat anumite corelaţii – plecând în fond, de la intuiţia legăturilor fireşti între locul de pe fereastra browserului în care postăm o „tablă de şah”, cele 64 de „câmpuri” ale acesteia, piesele de şah pe care le plasăm pe unele câmpuri şi acţiunile care ar trebui cumva „montate” pentru a produce poziţiile corespunzătoare desfăşurării unei „partide de şah”; la bază (în esenţă) – modelăm tabla de şah printr-o anumită structură HTML, asigurând poziţionarea elementelor acesteia unele faţă de altele (prin folosirea anumitor specificaţii CSS) şi înzestrarea lor cu anumite capabilităţi, folosind JS (sau jQuery).

Jocurile sunt probabil „piatra de încercare” pentru orice programator; dar fiind vorba totuşi de şah, avem de lămurit (nu doar trimiţând la Wikipedia) termenii specifici, regulile jocului şi subtilităţile de programare aferente, precum şi reprezentările şi structurile de date consacrate (FEN, PGN, 0x88 – rar audiate şi acestea de către programatori şi deloc, de către „cărţi de informatică”); iar pentru a construi direct un „analizor sintactic” pentru textul unei partide de şah, avem de insistat asupra lucrului cu „expresii regulate”.

Prima formă (când ai noroc)

În mare măsură, angajamentele invocate mai sus sunt reflectate deja în [1] – încât obţinerea unei forme primare a cărţii devine (ce noroc!) o simplă „chestiune tehnică”: folosim Pandoc pentru a transforma fişierul HTML sursă pentru [1], în fişier LaTeX:

pandoc  -s  -f html  -t latex  -o modBook.tex  pgnbrw-widget.html

Am preferat să invocăm pandoc cu cele mai obişnuite opţiuni (evitând de exemplu să angajăm şi fişierul CSS implicat de [1]), fiindcă oricum vor fi de eliminat, de modificat sau de rescris secţiuni de text şi secvenţe de cod sursă intercalate în text.

Bineînţeles că lucrăm într-un director nou (izolat de cel aferent site-ului din care face parte [1]); pentru a compila fişierul .tex rezultat, trebuie rezolvată întâi o problemă legată de fişierele imagine. Tagurile <img> din fişierul HTML, precum:

<img src="/images/test-men32.png" alt="" />

devin după transformarea în LaTeX:

\includegraphics{/images/test-men32.png}

sau (reducând imaginile mai largi decât lăţimea de bază a textului):

\includegraphics[width=0.75000\textwidth]{/images/pgn4web.png}

Pentru browserul în care am încărca [1], /images/ este un anumit subdirector al directorului de bază al site-ului (setat pentru a deservi fişiere-imagine) şi nu are de-a face cu diversele subdirectoare care conţin sursele HTML din care sunt referite prin <img> fişierele imagine; însă pentru compilatorul de LaTeX, /images/ este un subdirector… al directorului rădăcină al discului (ar fi trebuit images/ – fără '/' iniţial – pentru a fi văzut ca subdirector al directorului în care avem sursa LaTeX de compilat).

Scăpăm de micile probleme ca de obicei, prin eliminare. Putem „acoperi” comenzile LaTeX exemplificate mai sus, prin expresia regulată /graphics.*\{\/images\// – în care "/" iniţial şi final delimitează (sau „construiesc”) expresia, "\" comută semnificaţia caracterului următor între „special” şi „obişnuit”, iar ".*\{" acoperă orice secvenţă de caractere care precede caracterul obişnuit '{'; următoarea comandă elimină /images/:

perl -p -i -e 's/graphics.*\{\/images\//graphics\{/g' modBook.tex

Faptul că sunt eliminate şi eventualele opţiuni de scalare [...] nu ne deranjează: oricum va trebui să modificăm sau să redimensionăm diverse imagini.
Vrem totuşi ca fişierele-imagine respective să nu fie chiar „alături” de sursa LaTeX de compilat, ci grupate într-un anumit subdirector – să-i zicem pict/; compilatorul le va putea depista de aici, dacă adăugăm în preambulul fişierului LaTeX declaraţia \graphicspath{{./pict/}}.

Problema constă în a depista în subdirectorul /images/ asociat site-ului, acele fişiere care sunt referite acum din fişierul LaTeX şi a le copia într-un subdirector pict/ al directorului de lucru curent; avem o rezolvare prin următorul program (în Bash):

#!/bin/bash
perl -ne 'if(/graphics\{(.*\.\w{3})?\}/g) {print "$1\n";}' \
         modBook.tex > images.txt  # numele fişierelor-imagine din 'modBook.tex'
src="$HOME/docer/static/images/"  # locul fişierelor imagine ale site-ului
mkdir pict
for file in `cat "images.txt"` 
do
    cp "$src$file" pict/
done

După ce vom fi executat acest program, se poate compila:

xelatex  modBook.tex

obţinând fişierul modBook.pdf; deschizând în evince (sau în browser – tastând pe linia de comandă: firefox modBook.pdf), putem reciti [1] în noua formă (paginată) şi (începând şi lucrul la pgnbrw.js) am putut începe „să scriu” – adică (în cazul de faţă), să editez (elimină/modifică/adaugă) secţiuni de text şi secvenţe de cod, să reorganizez conţinutul, să refac unele figuri etc., recompilând din când în când pentru a vedea cum mai arată lucrurile. Iar lucrul la pgnbrw.js avansa pe măsură ce puneam la punct câte o secţiune şi câte un capitol (cu unele reluări ulterioare).

Producerea secvenţelor de cod

Între timp, pe măsură ce lucrurile progresau, răsfoiam mereu manualul pachetului memoir, pachet pe care-l angajasem de la bun început în fişierul modBook.tex:

\documentclass[a4paper, 11pt, openany, extrafontsizes]{memoir}

Prima problemă cu care ne confruntăm este producerea secvenţelor de cod. Iniţial am folosit pachetul listings, apoi am încercat minted; dar în ambele cazuri, comentariile care conţineau „diacritice” erau redate defectuos după compilarea fişierului (iar „vina” ar pleca de la interacţiunea lui memoir cu aceste pachete, fiindcă anterior – fără a implica memoir – folosisem listings, fără probleme). În loc de a mai căuta vreo îndreptare, am constatat că pot folosi „fără probleme”, pachetul (mai vechi!) verbments; ca şi minted, acesta apelează la modulul Python Pygments (folosit frecvent şi în fişierele HTML de pe acest site, pentru a marca sintactic secvenţele de cod).

Dar nici verbments nu este „fără pată”; experimentul direct pe care îl prezentăm mai jos, dezvăluie treptat cum stau lucrurile.

Următorul fişier LaTeX (să-l numim "vrbm.tex") conţine o secvenţă de cod JS şi prevede verbments pentru marcarea sintactică a ei:

\documentclass{memoir}

\usepackage{verbments}
\plset{texcl=true, fontsize=\small, encoding=utf-8}

\begin{document}

\begin{pyglist}[language=js]
    (function($) {
        /* partea {\upshape{(I)}} - constante şi funcţii auxiliare */
        /* partea {\upshape{(II)}} - defineşte widget-ul vizat mai sus */
    }) (jQuery);
\end{pyglist}

\end{document}

Prima tentativă de compilare (cu xelatex, fără vreo opţiune de compilare) eşuează – motivul fiind grija impusă iniţial compilatorului de a ne feri de surprizele produse prin execuţia vreunui program extern nedorit; pentru a permite invocarea programului extern pygments, compilatorul trebuie moderat, printr-o anumită opţiune de compilare:

xelatex  --shell-escape  vrbm.tex

Filând fişierul informativ lăsat de compilator vrbm.log, constatăm că pygmentize a fost executat de două ori:

runsystem(pygmentize -P encoding=utf-8 -l js -F tokenmerge -f latex -P texcomme
nts -o vrbm.pyg.vrb vrbm.pyg.lst)...executed.

runsystem(pygmentize -S default -f latex > vrbm.pyg.sty)...executed.

(./vrbm.pyg.sty) (./vrbm.pyg.vrb)

Întâi s-a obţinut – din fişierul vrbm.pyg.lst în care compilatorul extrăsese secvenţa de cod respectivă – fişierul vrbm.pyg.vrb, în care pygments a înregistrat secvenţa de cod împreună cu anumiţi termeni de clasificare (pentru cuvintele cheie din limbajul respectiv, pentru comentarii, etc.), formulaţi ca pentru LaTeX. Apoi, s-a obţinut şi fişierul vrbm.pyg.sty, în care pygments a înregistrat (iarăşi, ca pentru LaTeX) stilurile de culoare, formă (de exemplu, italic) şi mărime de caracter care să fie asociate clasificatorilor existenţi. În final, xelatex a citit aceste două fişiere, incluzându-le în „codul-obiect” pe baza căruia va rezulta forma PDF a fişierului LaTeX iniţial.

Dacă ar fi existat mai multe secvenţe de cod (cum şi avem în modBook.tex), atunci pentru fiecare în parte se scria fişierul \jobname.pyg.lst conţinând codul-sursă curent, apoi se lansa pygmentize pentru a obţine fişierele \jobname.pyg.vrb şi \jobname.pyg.sty (unde \jobname păstrează numele fişierului LaTeX de compilat – încât pentru toate secvenţele de cod se rescriu pe disc aceleaşi trei fişiere).

La fel decurg lucrurile şi în cazul când s-ar folosi minted, în loc de verbments – numai că minted permite şi o opţiune prin care putem stabili de la bun început un acelaşi stil de marcare sintactică pentru toate secvenţele de cod, în timp ce verbments pare gândit pentru câte o singură secvenţă de cod (nu permite o opţiune „globală” de stilare).

Este firesc ca indiferent de limbajul subiacent, secvenţele de cod să fie marcate cât mai unitar: cuvintele-cheie să fie boldate şi de o aceeaşi culoare, distinctă de a textului obişnuit, comentariile să fie marcate printr-o anumită altă culoare, folosind caractere înclinate şi de mărime mai mică decât cea normală, etc. Cu alte cuvinte, fişierul \jobname.pyg.sty ar fi trebuit produs o singură dată, la începutul compilării (fiind folosit apoi, pentru toate secvenţele de cod existente); pentru ca aceasta să fie posibil, verbments trebuie modificat.

Având în vedere necesităţile imediate, am evitat să mă ocup „ştiinţific” de modificare şi am procedat oarecum banal (dar tipic). Întâi, am copiat fişierul $HOME/texlive/2019/texmf-dist/tex/latex/verbments/verbments.sty în directorul de lucru curent şi l-am deschis de aici în gedit, de unde l-am salvat imediat sub numele verbments2.sty. Fişierul respectiv este scurt şi n-a fost deloc greu de văzut ce am de anulat; redau aici diferenţele pe care le-am instituit între cele două fişiere:

diff verbments.sty verbments2.sty
17c17
< \ProvidesPackage{verbments}[2011/08/20 v1.2 ...]
---
> \ProvidesPackage{verbments2}[2011/08/20 v1.2 ...]
89,90c89,90
<   \immediate\write18{\pyg@style}
<   \input{\jobname.pyg.sty}%
---
> %  \immediate\write18{\pyg@style}
> %  \input{\jobname.pyg.sty}%
134c134
<   \edef\pyg@style{pygmentize -S \pl@style\space -f latex > \jobname.pyg.sty}
---
> %  \edef\pyg@style{pygmentize -S \pl@style\space -f latex > \jobname.pyg.sty}
-->

Am schimbat numele pachetului (în linia 17) şi am comentat liniile 89, 90 şi 134 – încât compilatorul nu va mai lansa pygmentize pentru a obţine fişierul \jobname.pyg.sty şi nici nu va mai citi acest fişier.

Apoi, am creat următorul fişier pyg_sty.tex:

\documentclass{memoir}

\newcommand{\usestyle}[1]{
    \immediate\write18{pygmentize -S #1 -f latex > pygS.sty}
}
\begin{document}
    \usestyle{default}  % \usestyle{colorful}
\end{document}

La compilarea acestuia (cu --shell-escape) se lansează pygmentize -S pentru a obţine „pachetul” de stilare în LaTeX a secvenţelor de cod, scriindu-l apoi pe disc în pygS.sty; dintre cele câteva stiluri de marcare prevăzute în pygments, am setat ca implicit stilul "default" (pe care îl viza verbments).

Acum, înlocuind în modBook.tex "verbments" cu "verbments2" şi adăugând în preambul \usepackage{pygS} – compilatorul va folosi pygS.sty pentru toate secvenţele de cod (care sunt ambalate fiecare în \begin{pyglist}...\end{pyglist}, cum prevede verbments), apelând pygmentize câte o singură dată (pentru a rescrie \jobname.pyg.vrb corespunzător secvenţei curente), în loc de cele câte două apeluri evidenţiate la început. Această reducere este importantă, având în vedere că în modBook.tex avem multe secvenţe de cod (în plus, trebuie recompilat frecvent, după diversele modificări ale conţinutului).

Clişeele manuscris — produs finit

Am terminat de scris cartea şi de rescris pgnbrw(), undeva prin preajma Crăciunului. Cu pgnbrw() chiar am terminat, postând codul (comentat minuţios) pe Github; însă în privinţa cărţii, ceea ce voi fi terminat este un „manuscris”.

Sunt destule edituri la noi, care aşteaptă să le trimiţi un manuscris (în format Microsoft-Word, sau eventual PDF cu anumite cerinţe de compatibilitate) şi-ţi propun (contra unor anumite costuri) să-ţi editeze cartea ca „produs final”: să-ţi obţină întâi un ISBN şi un CIP (de la Biblioteca Naţională), apoi să se ocupe (împreună cu autorul) de editare – stabilirea formatului cărţii (de exemplu 14x21cm); verificarea corectitudinii gramaticale şi a folosirii diacriticelor; formatarea paginilor (margini, antete, etc.) şi prelucrarea imaginilor; realizarea copertei; etc. În final, trebuie să soliciţi un anumit număr de exemplare (dintre care vreo 7 vor fi trimise la "depozitul legal" al Bibliotecii Naţionale) şi mai departe, editura se oferă eventual să organizeze o „lansare de carte” (la care să-ţi inviţi familia, prietenii, etc.) şi deasemenea, să se ocupe să-ţi posteze cartea pe diverse reţele de distribuţie (inclusiv desigur, în format EBook, pe Amazon).

Cam aşa este de simplu şi cu nişte costuri rezonabile, oricine poate publica o carte!

Eu însă am decis că mă pot lipsi de sprijinul aşa de generos (dar insistent) oferit de vreo editură şi că deocamdată, pot publica direct fie prin Amazon KDP, fie prin Lulu; bineînţeles că şi aici găseşti „sprijin” generos şi ţi se oferă gratuit o groază de template-uri şi tutoriale de formatare în Microsoft-Word.

De la „caiet studenţesc” la formatul A5

Ceea ce aveam deja ca „produs final” (dacă aş fi tipărit) semăna cu obişnuitul „caiet studenţesc” – dată fiind opţiunea [a4paper, 11pt] cu care folosisem memoir; este drept însă că de la sine, memoir aranjase lucrurile în pagină cât se poate de bine: lungimea rândului şi numărul de rânduri pe pagină corespund principiilor tipografice moderne; paginile pare („verso”) au în antet titlul capitolului curent, iar cele impare („recto”) – titlul secţiunii curente; antetele conţin şi numărul paginii şi au deja o formatare care le deosebeşte de restul paginii; ş.a.m.d.

Totuşi, marginile stabilite de la sine de memoir sunt prea generoase: zona acoperită cu cerneală reprezintă cel mult 46% din suprafaţa totală a paginii A4. Există raţiuni pentru aceasta: pe de o parte, marginile laterale pot să fie folosite pentru inserarea unor „note marginale”; pe de altă parte, după tipărirea tuturor paginilor, topul rezultat poate fi tăiat convenabil (micşorând astfel marginile la cât este necesar). În plus, avem şi posibilităţi simple de a fixa din start ce margini dorim – doar că în acest caz, avem de văzut dacă nu cumva lungimea rândului de text devine prea mare pentru fontul folosit (regula este de a nu depăşi 66-72 de caractere).

Ideea la care am ajuns are defectele ei, dar pare acceptabilă. Mai întâi, am înlocuit "a4paper" cu "a5paper"; numărul de pagini s-ar mări considerabil (fiindcă o pagină A5 este jumătate dintr-una A4), aşa că am micşorat mărimea de bază a fontului – specificând "10pt" în loc de "11pt". Numărul de pagini ar fi încă prea mare, aşa că am trecut şi la margini (care oricum, erau prea „generoase”): prin \setulmarginsandblock{0.8in}{*}{1.0} am fixat margini de câte 0.8 inch sus şi jos, iar prin \setlrmarginsandblock{0.8in}{0.5in}{*} am stabilit 0.8in pentru „marginea internă” (cea dinspre cotorul cărţii; o anumită porţiune din această margine este necesară pentru finalizarea cărţii prin lipirea paginilor) şi 0.5in pentru marginea opusă acesteia.
Prin comanda \checkandfixthelayout, am obţinut de la memoir confirmarea faptului că setările făcute astfel se încadrează unor limite şi proporţii tipografice acceptabile; nu mi-a scăpat totuşi un „defect”, anume creşterea spre 78 a numărului de caractere pe rând – dar dificultatea de citire care ar apărea prin aceasta pare a fi compensată prin faptul că între paragrafele respective sunt intercalate secvenţe de cod-sursă (care de obicei au rânduri scurte).

După repoziţionări de imagini, reduceri sau extensii de text (luând în seamă pe cât am putut, obişnuitele atenţionări "Overfull" şi "Underfull", pentru \hbox sau \vbox) şi diverse alte operaţii de editare — ceea ce bineînţeles, mi-a luat zile întregi (dar astfel, am şi revăzut şi revizuit de mai multe ori întregul text) — PDF-ul rezultat avea cam 160 de pagini A5 (faţă de vreo 120 pagini A4 cât aveam iniţial) – avantajul imediat fiind acela că acum se poate folosi pachetul pdfpages, pentru a printa câte două pagini A5 pe o pagină A4:

\documentclass[a4paper]{memoir}
\usepackage{pdfpages}
\begin{document}
    \includepdf[landscape]{cover}  % coperta (PDF)
    \includepdf[nup=1x2, pages=-, landscape]{modBook}  % două A5 pe una A4
\end{document}

Aici am redat doar primele câteva pagini; cele cu număr impar sunt pagini „recto” (apar în dreapta, când ai deschide cartea).

Am inclus şi coperta cover.pdf, pentru realizarea căreia am folosit pachetele bookcover şi wallpaper; editurile recomandă să pui pe coperta a IV-a poza autorului, câteva informaţii despre el şi despre carte, un cuvânt adresat cititorului, etc. — nu zic că nu-i bine aşa, dar eu am preferat să montez (folosind pachetul dirtree) o schemă a desfăşurării lucrurilor dezvoltate „pas cu pas” în carte (iar pe coperta I am preluat din fereastra browserului imaginea unei aplicaţii care foloseşte widget-ul pgnbrw()). Astfel (după mine), coperta sugerează sintetic întreaga carte.

Alegeri finale

Am constatat că Amazon KDP nu suportă şi limba română (în Romanian diacritic marks este expusă foarte clar problema literelor „cu diacritice”, de-a lungul timpului); în plus, nu prevede şi formatul de carte A5. Probabil că aceste două impedimente pot fi cumva depăşite, dar deocamdată am renunţat (învăţând totuşi câte ceva de prin "help"-urile oferite, de exemplu cum am de construit coperta, îmbinând într-o singură pagină PDF coperta I, coperta IV şi cotorul cărţii – ceea ce am „redescoperit” apoi prin pachetul bookcover).

La Lulu apoi, lucrurile au decurs cumva liniar; mi-am creat un cont, am ales "Standard PaperBack" şi "Product Size" A5, apoi am introdus titlul şi autorul şi am upload-at fişierul modBook.pdf (suportând cu stoicism popup-urile insistente de genul "Ai nevoie de ajutor?"). Lulu a prelucrat PDF-ul meu şi m-a atenţionat în privinţa imaginilor, recomandând rezoluţia de 300dpi; n-am considerat necesar să modific (şi nici n-ar fi simplu de făcut), fiindcă nu-i vorba de „poze” (de familie, sau de peisaje) ci de simple copii de ecran. Am upload-at apoi şi cover.pdf şi obţinând validarea necesară, am publicat (întâi ca "private") proiectul constituit astfel şi am solicitat conform recomandării, un exemplar pentru verificare.

Peste chiar numai o săptămână, am primit exemplarul cerut; de pe factura însoţitoare am constatat că a fost tipărit în Anglia, de Printondemand-worlwide, costul fiind 4.20 UKL (căutând "Currency Code", n-am dat de "UKL"; dar este de presupus că este vorba de "GBP" sau "pound sterling" – echivalent deci cu 24.10 lei); bineînţeles că la această sumă s-a adăugat costul poştal (care se putea reduce pe la 7 dolari, dacă aveam inspiraţia să optez pentru trimitere obişnuită, în loc de opţiunea implicită de trimitere cu posibilitatea de urmărire a parcursului coletului).

Exemplarul pe care l-am primit (solicitat în scopul verificării preliminare) arată excelent, pe cât s-a putut de bine. Imaginile sunt "OK", deşi nu respectasem recomandarea de a le reface la rezoluţia de 300dpi; bineînţeles că imaginile (exceptând coperta) şi secvenţele de cod-sursă sunt „alb-negru” (nuanţe de gri) – de vreme ce optasem pentru varianta mai ieftină "Interior Ink: Black & white" (nu "color").

Literele cu „diacritice” sunt OK (nu sar în ochi!) şi… sunt corecte: folosesc virgula şi nu "cedilla". Acesta este un aspect interesant, fiindcă ele au fost produse în PDF-ul meu prin combinaţie – de exemplu 'ș' a fost produs combinând 's' cu virgula:

\usepackage{newunicodechar}
\newunicodechar{ş}{\textcommabelow{s}}

iar explicaţia procedeului pe care l-am folosit decurge din faptul că de foarte mult timp pe sistemul meu tastatura este setată pe "Romanian Cedilla" (şi fiindcă n-am vrut să schimb – având deja multe documente astfel editate – a trebuit să înlocuiesc 'ş' cu \textcommabelow{s} şi la fel pentru "ţ", etc.).

Iar aspectul diacriticelor rămâne în continuare interesant; în pagina de Shop prin care Lulu pune cartea în vânzare, titlul apare astfel:

Investigând în browser (tasta F12, în Firefox), am constatat că pentru titlu au fost alese două fonturi: JosefinSlab şi TeXGyreHeros-Bold, dintre care numai al doilea suportă "Romanian" (şi a fost aplicat pentru a reda 'ş'-ul care „sare în ochi” în imaginea de mai sus). Desigur că, dacă aş fi ghicit o asemenea îmbinare dezastruoasă de fonturi, atunci aş fi indicat ca titlu: "Modelarea în browser a partidei de sah" (cu 's' în loc de 'ş' sau 'ș'); dar puteam ghici? – bineînţeles că da: trebuia ca în prealabil, să investighez ca mai sus, un titlu oarecare dintre cele existente deja la "Shop".

Revenind pe Lulu, aş putea folosi "Revision" pentru a înlocui titlul (eliminând diacriticele) – dar aceasta ar fi încă o dată, un accept tăcut pentru ignorarea şi în continuare a literelor româneşti; dacă se poate, probabil că o să-i atenţionez cumva, urmând să vadă ce font ar mai bine de folosit pentru redarea corectă a titlurilor pe "Shop"-ul dumnealor (altă soluţie ar consta în extinderea fontului "JosefinSlab" – ceea ce de obicei este nefezabil, sau costisitor).

În final chiar, am revenit la "Revision" pentru a rotunji preţul la 6 dolari (încât aş câştiga şi eu din vânzare – cam 5 lei, minus ceva comision şi minus ceva impozit).

Carte versus fişier PDF

Poate că, măcar la urmă sau în trecere, s-ar cuveni să recunoaştem (şi să nu ocolim) încă o chestiune de alegere: ce ar prefera cititorul – un „produs finit” (cartea palpabilă), sau fişierul PDF intermediar? Disecarea comparativă a celor două modalităţi de citire e o treabă de specialişti (a căuta de exemplu, "read versus read from screen") şi nu-mi pot permite decât nişte consideraţii concrete şi poate subiective.

Pentru opere literare, pare clar că un cititor cu gustul lecturii nici nu se va gândi la posibilitatea de a citi de pe ecran (deschizi în browser fişierul HTML de la gutenberg.org şi „citeşti” romanul lui Tolstoi, "Anna Karenina"… nu zău, serios⁈). Însă pentru „literatura ştiinţifică”, chestiunea cititului este mai delicată (ne amintim că problemele puse de accesarea şi citirea de articole şi lucrări publicate în revistele ştiinţifice, au condus prin 1990 la apariţia primului "web browser"; în plus (pe de altă parte), a devenit deja regulă, ca lucrările adresate unei reviste ştiinţifice să fie produse cu LaTeX, nu cu Microsoft-Word).

Eu unul, m-am deprins greu să citesc de pe ecran; a fost o perioadă, acum vreo 20 de ani, când pentru a putea citi vreo documentaţie, trebuia întâi să o printez (e drept că pe atunci abia începusem să mă obişnuiesc cu limba engleză, folosită în documentaţii).

Ca să citeşti cumsecade direct de pe ecran, trebuie întâi să fii „în temă” – măcar să cunoşti limba şi termenii, într-o măsură acceptabilă. Trebuie apoi ca documentul electronic respectiv să fi fost astfel conceput încât atunci când l-ai deschide în browser, să poţi beneficia de un „cuprins clickabil” fixat într-o anumită zonă rezervată în fereastra browserului (pentru aceasta, în fişierul LaTeX din care provine PDF-ul respectiv trebuie inclus pachetul hyperref; nu cred că ai soluţie, dacă PDF-ul provine vulgar dintr-un document Microsoft-Word).

Marele avantaj în cazul fişierului PDF, constă în posibilitatea de a copia direct de pe ecran secvenţe de cod; în compensaţie, se obişnuieşte ca în carte să fie menţionat undeva un loc (de obicei, pe GitHub) în care autorul va fi postat secvenţele de cod (iar cititorul cărţii le va putea copia din acest loc).

Desigur, dacă pui la dispoziţie chiar fişierul PDF, în loc de „produsul final”, atunci îţi tai orice şansă de a câştiga ceva – cine ar fi interesat va downloada gratis fişierul respectiv (iar adevărata problemă şi temerea uzuală este legată de posibilităţile de speculare ulterioară a fişierului download-at); şi aceasta este un motiv, pentru care s-au înfiinţat diverse "formate EBook", prin care se previne „copierea ilegală” (desigur, se invocă raţiuni mai importante decât prevenirea copierii – fiindcă în fond, costul achiziţionării unui EBook este în general „aproape gratis”, faţă de acela corespunzător unei cărţi tipărite).

Poate că voi face mai târziu şi experimentul de a produce un EBook (plecând desigur, de la memoir); dar eu unul prefer totdeauna formatele „clasice” (fişier PDF, sau chiar numai sursa LaTeX), în loc de EBook.

vezi Cărţile mele (de programare)

docerpro | Prev | Next