[cstex] Trik k vyreseni rozparsovani retezce?

Jaroslav Hajtmar hajtmar at gyza.cz
Mon Aug 20 12:49:50 CEST 2007


Pane Wagnere
Dekuji za reseni i jeho naprosto vycerpavajici popis  Pro mne je to 
velmi cenne, protoze to je ucebnicove vysvetleno.
Je zajimave, ze se opravdu velmi tezce ztotoznuji s lustenim a 
fungovanim TeXovskych maker i kdyz s programovanim v jinych jazycich
nemam naprosto zadny problem a to vcetne Perlu, coz je z meho pohledu 
opravdu sverazny (ale velmi oblibeny) jazyk.
Asi je to principem TeXu nebo spis moji starnouci hlavou ... :-).
Pravdou je, ze jsem toho v plainTeXu uz programoval dost, ale je to 
vetsinou zalezitost metody pokusu a omylu a neustaleho listovani v TBN a 
obraceni se na konferu. Velmi cenne jsou vysvetlivky z konfery, ktere mi 
problizuji filozofii programovani v tomto pro mne fascinujicim 
programovacim jazyku.

S tou mezerou a hlaskou, kterou jsem vlastne mylne uvedl mate naprostou 
pravdu. Dokonale jste ovsem i pri mem velmi spatnem popisu problemu 
vytusil oc mi slo a vyresil jste to zgruntu - jak je vam to vlastni.
Diky za vas cas a rady ... moc si toho vazim...

S pozdravem Jarda Hajtmar


Zdenek Wagner napsal(a):
> 2007/8/20, Jaroslav Hajtmar <hajtmar at gyza.cz>:
>   
>> Dobry den.
>> S ohledem na supertrik, ktery mel v zasobe pan Wagner, bych se pokusil
>> pozadat konferenci jeste o jednu vec, se kterou se casto potykam, nebot
>> vyuzivam plainTeX a ConTeXt velmi casto ke zpracovavani a sazbe
>> databazovych dat (textove databaze z Excelu ve formatu *.CSV).
>> Zajima mne, zda existuje nejaky zpusob ktery by umoznil zpracovat a
>> vyhodnotit  "nevhodne zadane" parametry makra, aniz by doslo k chybove
>> hlasce.
>> Primarne mi jde vlastne o jakesi rozparsovani retezce, ktery neni k
>> rozparsovani vhodny.
>>
>> Ukazal bych to na prikladu :
>>
>> \def\parsuj#1 #2{1. - #1, 2. - #2}
>>
>> \def\testA{123 456}
>> \def\testB{123456}
>>
>> \expandafter\parsuj\testA % je OK, nebot retezec ma spravny format
>>
>> \expandafter\parsuj\testB % Tohle da samozrejme chybu, nebot v retezci
>> neni mezera oddelujici oba parametry
>>
>>     
> Z pohledu TeXu toto neni pravda, mezera tam je. Po provedeni
> \expandafter zbyde na vstupu:
> \parsuj123456<konec radku>
>
> Za cislici 6 byl konec radku, ktery byl pri cteni input procesorem
> promenen na mezeru. Makro \parsuj si tedy vezme jako prvni parametr
> 123456. Nasledujici radek byl nejspis prazdny, takze jej input
> procesor promenil na \par. A prave tohle vadi. Makro \parsuj neni
> \long, takze v parametru nesmi byt \par. To je vyznam chyby "Runaway
> argument". Syntakticky nesouhlas je neco jineho. Predpokladejte, ze
> parametry maji byt oddeleny dvojteckami a z nejakeho duvodu ocekavate
> dvojtecku na zacatku i na konci, tj:
>
> \def\parsuj:#1:#2:{...}
>
> Pouziti \parsuj:123:456: projde, ale pokud vynechate prvni dvojtecku,
> tj. napisete \parsuj 123:456:, pak se TeX zastavi na cislici 1 a
> oznami:
>
> Use of \parsuj does not match its definition
>
>   
>> Chybova hlaska je samozrejme jasna :
>>
>> Runaway argument?
>> 123456
>> ! Paragraph ended before \parsuj was complete.
>> <to be read again>
>>                    \par
>> l.14
>>
>> ?
>>
>> Rad bych vedel, zda existuje nejaky jednoduchy trik, ktery by umoznil
>> obdrzet
>> jako vysledek to, ze v pripade, ze neni predavany parametr ve "vhodnem
>> formatu",
>> vyhodnoti to makro tak, ze vyda jako prvni parametr cely retezec a druhy
>> bude prazdny retezec (nebo retezec nejak predem specifikovany napr.
>> \null atp.).
>>
>>     
> Je to porad stejny trik. Dulezite je, abyste mel na konci "vzoru"
> jednoznacny token, ktery urcite nebude v retezci pouzit, treba \null.
> Pokud chcete mit dva parametry oddelene mezerou, nadefinujete si:
>
> \def\parsuj#1 #2\null{...}
>
> Za predpokladu. ze text k parsovani je v \testX, pouzijeme podobne
> volani, jake jste mel vyse. Potiz je v tom, ze pri chybe nema TeX
> zadny "fallback", ktery by sel ovladat na makro-urovni. Musime tedy
> zajistit, aby vstup byl syntakticky spravny, tedy pred \null pridame
> mezeru a prazdny parametr:
>
> \expandafter\expandafter\expandafter\parsuj\expandafter\testX\space\null
>
> Kdyz nyni makro \parsuj zjisti, ze #2 je prazdny, pak je jasne, ze v
> \testX nebyla mezera a retezec tedy neni formalne spravny. Pokud #2
> neni prazdny, pak ma na konci nadbytecnou mezeru, kterou bude nutno
> dodatacne odstranit (opet pouzijeme koncovy token, aby se retezec
> omylem neprekousl na mezere uprostred):
>
> \def\OdstranKoncovouMezeru#1 \null{#1}
>
> V makru \ifnotfound v odpovedi na minulou otazku jsem pouzil definici
> pomocneho makra a test \ifx. Pokud vite, ze v parametrech nebude
> matematika, muzete pouzit jiny trik:
>
> \ifcat$#2$ Prazdny\else Neprazdny\fi
>
> Primitiv \ifcat provani expanzi tak, aby mohl porovnat kategorie
> (\catcode) dvou nasledujicich znaku. Pokud je #2 prazdny, pak vidi
> \ifcat$$, coz je \iftrue, takze se provedou prikazy pred \else. Pokud
> #2 neco obsahuje, pak z nej \ifcat odebere prvni znak (coz podle
> predpokladu neni dolar ani jiny znak se stejnou kategorii). Podminka
> se tedy vyhodnoti jako \iffalse. Za ni sice zbyde neukoncena
> matematika, ale to nevadi, protoze vsechno az do \else vcetne bude
> ignorovano.
>
> Pokud byste jako argument makra parsuj chtel vlozit strink, ktery
> obsahuje mezeru, pak byste takoy argument musel uzavrit do zavorek.
>
> \parsuj 123 456 789\null vezme jako prvni parametr 123 a jako druhy
> parametr 456 789 (s mezerou uprostred), zatimco \parsuj {123 456}
> 789\null vezme jako prvni parametr {123 456}.
>
> Jeste bych si dovolil jednu poznamku. Je celkem bezne, ze v procesu
> zpracovani dat se postupne pouzije nekolik nastroju. Nebranil bych se
> tedy tomu, aby text byl nejprve zpracovan nejakym skriptovacim jazykem
> (perl, python, ...) a nasledne podstrcen TeXu. Ve svete XML se
> takovemu postupu zpracovani rika pipeline a podobne postupne
> zpracovani resi make, ant a rada jinych nastroju. Zalezi vsak na
> okolnostech. Pokud budu takovou vec delat jen pro sebe, pak pouziju
> vse, co mam ve svem pocitaci, a pujde o to, aby se mi to snadno
> programovalo. A pokud bych zpracovaval opakovane velka mnozstvi dat,
> hledal bych tez efektivni reseni (tyto TeXove triky jsou nekdy
> efektivnejsi nez regularni vyrazy). Pokud bych vytvarel program pro
> nekoho jineho, pak by zalezelo na tom, co ma ten nekdo jiny v
> pocitaci. Pokud se dokument v posledni fazi zpracovava TeXem, pak je
> jiste, ze uzivatel musi TeX mit, ale bezny uzivatel Windows nemusi mit
> perl ani python. V takovem pripade je ciste TeXove reseni vyhodnejsi,
> i kdyby nebylo nejefektivnejsi.
>
>   
>> Takze vysledek vyhodnoceni \testA by vypada takto :
>> 1. - 123, 2. - 456
>>
>> A vysledek vyhodnoceni  \testB by mel vypadat takto :
>>
>> 1. - 123456, 2. -
>>
>> \end
>>
>> Je pravda, ze ted, kdyz mam v ruce moznost testovat vyskyt podretezce v
>> retezci pomoci triku, ktery vcera poslal do konfery pan Wagner (viz. makro :
>>
>> \hledej{jehla}{Je snad jehla v kupce sena?}), muzu samozrejme predem predavany parametr "zkontrolovat" a predat jej pak uz ve spravnem formatu. Taktez bych mohl predem zpracovat a upravit data pomoci PERLu, a pak naservirovat makrum ke zpracovani uz jen "hezky naformatovana" data.
>>
>> Zajimalo by mne ale, zda by se dalo nejakym vtipnym trikem tuto vec vyresit bud primo TeXem nebo pomoci plainTeXu.
>>
>>
>> Pro ty kdo by v budoucnu narazili na tento dotaz v archivu a trik s
>> kupkou sena neznali jej jeste jednou prikladam na zaver, nebot posilam
>> tento mail do konfery s jinym subjectem, takze at je nejaka navaznost)
>>
>> Vsechny konferniky srdecne zdravim
>> Jarda Hajtmar
>>
>>
>>     
>>>> \def\nic{}
>>>> \def\hledej#1#2{%
>>>>   \def\ifnotfound##1#1##2\konec{\def\test{##2}\ifx\test\nic}%
>>>>   \ifnotfound#2#1\konec Nenalezeno!\else Nalezeno!\fi}
>>>>
>>>> \hledej{jehla}{Je snad jehla v kupce sena?}
>>>> \hledej{jehla}{Najdi jehlu v kupce sena!}
>>>>
>>>>         
>>> To je prekrasny trik - bez cyklu, bez \expandafter a cele v cistem TeXu (ani
>>> plain ani LaTeX). Proste skvele.
>>>
>>> Akorat ted uz nemam motivaci vymyslet vlastni reseni. Ja to tusil, ze nemam
>>> otevirat slozku cstex konference do doby nez budu mit cas se nad tim zamyslet -
>>> ale nedalo mi to a ted to mam :-)
>>>
>>> Milan Vancura
>>> _______________________________________________
>>> csTeX mailing list
>>> csTeX at cs.felk.cvut.cz
>>> http://lists.felk.cvut.cz/mailman/listinfo/cstex
>>>
>>>
>>>
>>>
>>>       
>> _______________________________________________
>> csTeX mailing list
>> csTeX at cs.felk.cvut.cz
>> http://lists.felk.cvut.cz/mailman/listinfo/cstex
>>
>>     
>
>
>   




More information about the csTeX mailing list