[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