[cstex] ScanCSV v ConTeXtu MKIV (by Lua) pro vsechny zajemce

Jaroslav Hajtmar hajtmar at gyza.cz
Wed Mar 31 01:32:34 CEST 2010


Dobrý den.
Jak říká klasik: "Přicházím s nabídkou kvalitního (Lua)TeXu"! :-)

Pomalu jsem se prokousal úvodem do Lua a pokouším se pomocí Lua 
znásilňovat "ConTeXt" (MKIV) .
Vzhledem k tomu, že se mi podařilo dosáhnout toho, že jsem s výsledkem 
relativně sám spokojen, posílám svůj první LuaTeXový pokus do této skupiny.
Snad to bude alespoň trochu použitelné a poučné i pro někoho jiného, než 
pro mne samotného.

Já tuto věc potřebuji docela nutně, a to velmi často, neboť neustále 
zpracovávám v ConTeXtu velmi rozsáhlé textové CSV tabulky (tisk 
mailmerge, vysvědčení, pozvánky, ...).
Udělal jsem to hlavně proto, abych se mohl pomalu oprostit od starých 
záležitostí - tj. kombinace užití Perlu a (nelua)ConTeXtu a využití 
původního makra "scancsv.tex" pana Olšáka, které mi sloužilo dlouhá léta 
k mé velikánské spokojenosti a které mi bylo velikou inspirací pro můj 
první LuaPočin. Tolik na úvod.

Dávám nyní k dispozici soubor scancsv.lua a několik testovacích a 
ukázkových souborů.
Zazipovaný dokument s vším, co je potřeba k testování, je na 
http://public.hajtmar.com/files/tex/luatex/scancsv/scancsv.zip
resp. nezazipováno na 
http://public.hajtmar.com/?cesta=JRsVFQdsBhwIWy8HGAQRO10KExUtEQoG

Soubor scancsv.lua  obsahuje několik Lua funkcí pro práci s CSV 
soubory.  Funkce zpřístupňují ConTeXtu data v CSV tabulkách (kódovaných 
UTF-8).
Data v jednotlivých řádcích CSV tabulky jsou prostřednictvím cyklu v Lua 
předávány ConTeXtu, kde mohou být dle libosti zpracovávána.

Formát CSV souborů (UTF-8), který dokáží skripty zpracovat je standartní 
CSV - textový soubor s položkami oddělenými středníkem, který běžně 
dostanete z Excelu  či jiného tabulkového procesoru. Mírnou 
nepříjemností je to, že Excel uloží CSV soubory v kódování CP1250, takže 
je nutné před zpracováním provést konverzi (s tabulkou v kódování CP1250 
si skripty bohužel neporadí)

Ukázkový example CSV soubor pro testování je csvtable.csv v tomto formátu:
Prijmeni;Jmeno;DatumNarozeni;MistoNarozeni;Pohlavi;Mesto;PSC;Ulice
Pospíšilová;Hana;4.1.1996;Zábřeh;ž;Zábřeh;78901;Studénky 420
atd...

Pro správnou činnost v ConTeXtu musí být názvy polí v záhlaví CSV 
souboru takové, aby splňovaly všechny požadavky na jména TeXovských 
maker. V průběhu zpracování se
totiž pomocí Lua vytvoří ze záhlaví CSV souboru definice TeXovských 
maker, do nichž jsou následně uložena data z jednotlivých řádků CSV 
tabulky. Řádková data jsou ConTeXtu k dispozici v průběhu Lua cyklu a 
jsou přístupna dvěma způsoby:
a) pomocí globálních Lua proměnných označených CSV.Prijmeni, CSV.Jmeno, 
CSV.DatumNarozeni, atd.
b) pomocí TeXovských maker \Prijmeni, \Jmeno, \DatumNarozeni, atd.

Jak Lua proměnné, tak TeXová makra vznikají v průběhu cyklu zcela 
automaticky bez jakéhokoliv přispění uživatele a uživatel je dokonce 
nemusí ani v ConTeXtu definovat (čímž nastává do jisté míry paradoxní 
situace, neboť se ve zdrojovém ConTeXtovém textu objevují makra 
\Prijmeni, \Jmeno, \DatumNarozeni, atd., která nejsou nikde ve zdrojáku 
definovaná). Soubor scancsv.lua je plný mých komentářů a obsahuje i 
"návod k použití".

Na úložišti je ke stažení přiložen i ConTeXtový soubor scancsv.tex - 
jakýsi minimální ukázkový příklad v ConTeXtu.

Pro ty, kteří nepočítají s tím, že by to využívali, ale chtěli by pouze 
vědět jak nakonec výsledek vypadá a jak to vlastně funguje jej zde uvádím:

\setupoutput[pdftex]
\enableregime[utf-8]
\mainlanguage[cz]

\startluacode
     dofile("scancsv.lua") -- načtení "knihovny" funkcí
     OpenCSVFile("csvtable.csv")  -- Otevře vstupní "example" CSV 
soubor, inicializuje proměnné, nadefinuje makra s názvy polí uvedených v 
záhlaví CSV souboru
\stopluacode

% Po načtení knihovny a zavolání funkce OpenCSVFile() se přečte 1. řádek 
(záhlaví) CSV tabulky a z údajů se vyvytvoří makra a názvy Lua proměnných

\startbuffer[uzitibufferu]
     \Jmeno\ \Prijmeni\par % všechna použitá makra jsou nadefinována při 
zavolání funkce OpenCSVFile()
     \Ulice\par
     \PSC\ \Mesto \par\blank[big]
\stopbuffer

\starttext

Ukázka použítí : \par\blank[big]

\startluacode
     while ReadLineFromCSV() do -- dokud není konec vstupního CSV 
souboru dělej tohle :
          tex.sprint("\\getbuffer[uzitibufferu] \\par") -- ukázka 
možnosti užití bufferů (obsahujících TeXová makra vytvořená v Lua.)
         tex.sprint('\\blank[big]')
     end -- of while
\stopluacode

That's all folks!

\stoptext


Výsledek není nijak efektní (viz PDF soubor ke stažení) - snažil jsem se 
tam dát co nejméně balastu a spíš ukázat jednoduchou ukázku toho,  že i 
naprostý Lua začátečník může "vyrobit" užitečnou aplikaci (aspoň pro 
sebe :-))
Pro zájemce o to, jak vypadá "opravdický" finální dokument je přiloženo 
i třístránkové PDFko - informace-4l.pdf s ukázkou informačního dopisu 
rodičům žáků (s fiktivními údaji).

Závěrem bych chtěl jen poznamenat, že jsem sám netušil, jak mocný 
nástroj je Lua a jaké pozoruhodné "kejkle" se s ním dají v ConTeXtu 
dělat! Navíc je moc inspirativní a programuje se v něm jaksi "samo".
Možná v těch skriptech bude i nějaká "muška", nicméně má to za sebou 
první úspěšný ostrý provoz (tisknul jsem před chvílí pozvánky na 
přijímací zkoušky na náš gympl asi pro 120 žáků)

Upozorňuji, že si s Lua hraji pouze pár dní a nemám komu koukat přes 
rameno či si nechat poradit (luštím pořád anglickou dokumentaci), takže 
možná jsou některé obraty příliš neohrabané a Luaista by to asi napsal 
úplně jinak.
Připomínky, náměty a vylepšení jsou velmi vítány.

Na závěr trochu "černého" humorn. Když jsem vykládal u oběda kolegyni 
informatičce to, jak zápasím s Lua, tak se mne jiná kolegyně zeptala, 
kdože to má ten Lues :-)

Zdraví J. Hajtmar

PS:  Zkoušel jsem něco podobného zprovoznit i pod LuaLaTeXem (to by asi 
zaujalo více lídí v konfeře), ale tam jsem si vylámal zuby. Podle 
informací pana Stříže prý v LaTeXu řada věcí nejede. Elie Roux prý 
pracuje na rozšíření  balicku lualatex.




More information about the csTeX mailing list