% scanbase. tex %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 26. 10. 2002 Petr Olsak % This is a macro for processing the mysql outputs in plain TeX % The input is supposed in the format: % % % arbitrary text before table % it is ignored % +------------+------------+----------------------------+ % | header1 | header2 | header3 ... | % +------------+------------+----------------------------+ % | text 1,1 | text 1,2 | text 1,3 ... | % | text 2,1 | text 2,2 | text 2,3 ... | % | text 3,1 | text 3,2 | text 3,3 ... | % | ... | ... | ... | % +------------+------------+----------------------------+ % % You can process such file by % % \input scanbase.tex % \def\lineaction{...} % \scanbase file % % The macro reads the headres first and then reads the lines % with the text. The contents of each item can be accessed % by full expanable macro \e after each line is read. More preciselly, % \e[header] expands to the body of the appropriate item. % The \lineaction macro is processed after each line is read. % It is supposed that \lineaction is defined by user. % % Next line of the table is read after \lineaction, the \e macros have % a new meaning (items from this next line) and the \lineaction is executed % again. This is repeated until last line of the input table is reached. % Moreower, the \linenum register is available, where the number of the % last scanned line is stored. % % Example: % % \input scanbase % % \newcount \mylines % \def\bb #1 #2/{\hbox to#1{#2\hss}} % % \def\printaction{\global\advance\mylines by1 %% \scanabase works % \hbox{% %% inside the TeX group % \bb 2em \the\numline./ % \bb 26em \e[subject]/ % \bb 10em \e[lastname] \e[firstname]/ % \bb 3em \hfill\e[pay2002]/ % \bb 3em \hfill\e[pay2001]/} % } % \def\lineaction{\if K\e[member_type]% Institutional members % \printaction % \else \if G\e[member_type]% High school % \printaction % \fi\fi % I am printing Institutional mambers and high schools only % } % \scanbase database1 % \scanbase database2 % {\it Number of printed lines: \the\mylines}. % \end % % If the \lineaction macro isn't defined by user then scanbase used % its own (default) macro which prints all items from one line % into the one paragraph in comprimend form (you can try this). % % The \scanbase macro opens the TeX group then runs \beginhook % then reads headers, then reads the lines ans processes \linecation % repeatedly, then runs \endhook and finally closes the group. % Default values for \beginhook and \endhook is \relax but user % can define something else. \newcount\colnum \newcount\numline \font\seventt=cstt10 at7pt \catcode`\^^X=13 \def^^X{} \def\scanfirstline #1-+^^X|{\scanheader} \def\scanheader #1 |{\advance\colnum by1 \expandafter \ifx \csname e:#1\endcsname \relax \expandafter \def \csname c:\the\colnum\endcsname{#1}% \expandafter \def \csname e:#1\endcsname {}% \else \expandafter \edef \csname c:\the\colnum\endcsname{#1:\the\colnum}% \fi \futurelet \nextchar \testnextchar } \def\testnextchar{\ifx\nextchar^^X\let\next=\ignorethirdline \else \let\next=\scanheader \fi \next } \def\ignorethirdline ^^X+-#1-+^^X{\edef\maxcolumn{\the\colnum}\runfirstitem} \def\runfirstitem|{\colnum=0 \runitem} \def\runitem #1 |{\advance\colnum by1 \def\tmp{#1}% \ifx\tmp\empty \else \expandafter \ignorefirstspace \tmp^^X% \fi \expandafter\edef\csname e:\csname c:\the\colnum\endcsname\endcsname{\tmp}% \futurelet \nextchar \testnextitem } \expandafter \def \expandafter \ignorefirstspace \space#1^^X{\def\tmp{#1}} \def\testnextitem{\ifx\nextchar^^X\let\next=\runline \else \let\next=\runitem \fi \next } \def\runline ^^X{\advance\numline by1 \lineaction \futurelet \nextchar \testnextline } \def\testnextline{\ifx\nextchar+\let\next=\endgame \else \let\next=\runfirstitem \fi \next } \def\endgame+-#1-+^^X{\endinput} \def\e [#1]{\expandafter\ifx \csname e: #1\endcsname \relax \message{Warning: the #1 column is not defined in header.}% \else \csname e: #1\endcsname \fi } \def\printall{\colnum = 0 \noindent \hangindent=\parindent \raggedright \loop \advance\colnum by1 {\seventt \ignorespaces \csname c:\the\colnum\endcsname:}\penalty0 \csname e:\csname c:\the\colnum\endcsname\endcsname \ifnum\colnum < \maxcolumn , \repeat .\par } \let\lineaction=\printall \def\scanbase #1 {\begingroup \endlinechar=`\^^X \def\do##1{\catcode`##1=12 }\dospecials \catcode`\ =10 \beginhook \expandafter \scanfirstline \input #1 \endhook \endgroup} \let\beginhook=\relax \let\endhook=\relax \endinput % Makro na zpracovani databasovych vystupu z mysql pro plain % Nacitane soubory se predpokladaji ve tvaru: % % % libovolny text pred tabulkou, % ktery bude ignorovan % +------------+------------+----------------------------+ % | zahlavi1 | zahlavi2 | zahlavi3 ... | % +------------+------------+----------------------------+ % | text 1,1 | text 1,2 | text 1,3 ... | % | text 2,1 | text 2,2 | text 2,3 ... | % | text 3,1 | text 3,2 | text 3,3 ... | % | ... | ... | ... | % +------------+------------+----------------------------+ % % Na takovy soubor je mozno po % % \input scanbase.tex % % aplikovat makro \scanbase takto: % % \scanbase soubor % % Makro nacte zahlavi a zacne cist jednotlive radky. Po precteni % kazdeho radku je obsah polozky pripraven v expanznim makru % \e. Presneji \e[zahlavi] expanduje na text odpovidajici polozky. % V teto situaci \scanbase spusti makro \lineaction, ktere si muze % uzivatel definovat jak chce. % % Po ukonceni makra \lineaction cte scanbase dalsi radek tabulky, naplni % znovu expanzni makra \e texty polozek z tohoto radku a spusti znovu % \lineaction. To se opakuje tak dlouho, dokud neni ukonceno cteni % tabulky. Navic je makru \lineaction k dispozici registr \numline % obsahujici cislo prave precteneho radku. % % Priklad pouziti: % % \input scanbase % % \newcount \mylines % \def\bb #1 #2/{\hbox to#1{#2\hss}} % % \def\printaction{\global\advance\mylines by1 %% \scanabase pracuje % \hbox{% %% uvnitr skupiny! % \bb 2em \the\numline./ % \bb 26em \e[nazev]/ % \bb 10em \e[prijmeni] \e[jmeno]/ % \bb 3em \hfill\e[kc2002]/ % \bb 3em \hfill\e[kc2001]/} % } % \def\lineaction{\if K\e[typ_clenstvi]% Kolektivni clenove % \printaction % \else \if G\e[typ_clenstvi]% Gymnazia % \printaction % \fi\fi % tisknu jen kolektivni cleny a gymnazia % } % \scanbase database1 % \scanbase database2 % {\it Number of printed lines: \the\mylines}. % \end % % Pokud neni uzivatelem definovano makro \lineaction, pouzije % scanbase sve vlastni (defaultni) makro, ktere vytiskne vsechny polozky % jednoho radku do odstavce ve velmi zhustenem tvaru (vyzkousejte si). % % Kazde \scanbase vstupuje do skupiny, pak spusti \beginhook, % pak cte hlavicku a jednotlive radky, jak bylo receno vyse, % pak spusti \endhook a nakonec vyleze ze skupiny. % Sekvence \beginhook a \endhook muze predefinovat uzivatel, defaltne maji % hodnotu \relax