% scanbase. tex
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 26. 10. 2002                     Petr Olsak

%  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

\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


