diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2009-08-23 11:11:32 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2009-08-23 11:11:32 +0000 |
commit | 8fc3039c82d48605b5ca8b2eda3f4fdd755681e1 (patch) | |
tree | 3cd9bbdd599bc4d1ac0409e167fee2136e4c0ec9 /Master/texmf-dist/tex/context/base/m-datastrc.tex | |
parent | 850fc99b7cd3ae7a20065531fe866ff7bae642ec (diff) |
this is context 2009.08.19 17:10
git-svn-id: svn://tug.org/texlive/trunk@14827 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/m-datastrc.tex')
-rw-r--r-- | Master/texmf-dist/tex/context/base/m-datastrc.tex | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/m-datastrc.tex b/Master/texmf-dist/tex/context/base/m-datastrc.tex new file mode 100644 index 00000000000..4a6faa66b28 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/m-datastrc.tex @@ -0,0 +1,228 @@ +%D \module +%D [ file=m-datastrc, % was: core-dat % was core-02a +%D version=1999.08.10, % 1997.03.31, +%D title=\CONTEXT\ Modules, +%D subtitle=Database Support, % 2A +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Core Macros / Database Support} + +\unprotect + +%D This module is a (limited) rewrite of the original \type +%D {core-02a} module, the module that dealt with managing a +%D database of addresses. The principles and methods have not +%D changed; they are only generalized. +%D +%D A database file |<|in most cases such a base is generated +%D from another one|>| is structured as follows: +%D +%D \starttyping +%D \startrecord{tag} +%D \memberofgroup{grouplist} +%D \setrecordentry{name}{...} +%D .... +%D \stoprecord +%D \stoptyping +%D +%D The interface to such a database is defined as follows: +%D +%D \starttyping +%D \definerecord[class][settings] +%D \setuprecord[class][settings] +%D \definerecordentry[class][name] +%D \stoptyping +%D +%D and processed by +%D +%D \starttyping +%D \processrecords[file list][tag and/or group list] +%D \stoptyping +%D +%D The actual processing is done by a macro assigned to \type +%D {command}: +%D +%D \starttyping +%D \setuprecord[class][command=\DoWithRecord] +%D \stoptyping +%D +%D Given that one can ask for a field with +%D +%D \starttyping +%D \getrecordentry{name} +%D \stoptyping +%D +%D such a command can look like: +%D +%D \starttyping +%D \def\DoWithRecord#1% +%D {\startpacked +%D \let\\=\quad +%D name: \getrecordentry{name}~\getrecordentry{family name}\par +%D address: \getrecordentry{postal address}\par +%D \stoppacked} +%D \stoptyping +%D +%D The argument passed is the tag. The database can look like: +%D +%D \starttyping +%D \startrecord{hagenj} +%D \memberofgroup{a,b} +%D \setrecordentry{naam}{Hans} +%D \setrecordentry{family name}{Hagen} +%D \setrecordentry{postal address}{J. Hagen\\Ridderstraat 29\\Hasselt NL} +%D \stoprecord +%D +%D \startrecord{ottenaf} +%D \memberofgroup{a} +%D \setrecordentry{name}{Ton} +%D \setrecordentry{family name}{Otten} +%D \setrecordentry{postal address}{A.F. Otten\\Prinsengracht 17\\Hasselt NL} +%D \stoprecord +%D \stoptyping +%D +%D The definition of this database looks like: +%D +%D \starttyping +%D \definerecord[address][command=\DoWithRecord] +%D +%D \definerecordentry[address][name] +%D \definerecordentry[address][family name] +%D \definerecordentry[address][postal address] +%D \stoptyping +%D +%D The actual processing is now done by (for instance): +%D +%D \starttyping +%D \processrecords[datafile][hagenj] +%D \processrecords[datafile][hagenj,offenaf] +%D \processrecords[datafile][all] +%D \processrecords[datafile][a] +%D \processrecords[datafile][b] +%D \stoptyping +%D +%D Of course one can reassign the command used to handle the +%D records in between. + +% \??kt -> +% \??kw -> + +\def\??db {@@db} +\def\c!velden{velden} + +%\newevery \everyrecord \EveryRecord + +\def\definerecord + {\dodoubleempty\dodefinerecord} + +\def\dodefinerecord[#1][#2]% + {\getparameters + [\??db#1] + [\c!velden=, + \c!command=\gobbleoneargument, + #2]} + +\def\setuprecord + {\dodoubleargument\dosetuprecord} + +\def\dosetuprecord[#1][#2]% + {\getparameters[\??db#1][#2]}% + +\def\definerecordentry[#1][#2]% + {\edef\recordentries{\getvalue{\??db#1\c!velden}}% + \addtocommalist{#2}\recordentries + \letvalue{\??db#1\c!velden}\recordentries} + +%D Watch out: the entries are defined global! While +%D processing a record, no grouping is applied. + +\def\getrecordentry #1{\getvalue {\??db:#1}} +\def\resetrecordentry #1{\letgvalueempty{\??db:#1}} +\def\assignrecordentry#1{\setgvalue {\??db:#1}} + +\long\def\skiprecord#1\stoprecord + {\egroup} + +\newif\ifrecordok + +\newtoks\resetrecordlist + +\def\processrecords + {\dotripleargument\doprocessrecords} + +\def\doprocessrecords[#1][#2][#3]% + {\bgroup + \ifx\\\undefined\let\\\relax\fi + \def\docommand##1% + {\resetrecordentry{##1}% + \appendtoks\resetrecordentry{##1}\to\resetrecordlist}% + \processcommacommand[\getvalue{\??db#1\c!velden}]\docommand + \let\setrecordentry\skiprecord + \the\resetrecordlist + \doifelse{#2}\v!all % 't Is nu eenmaal alles + \recordoktrue + {\doifelsenothing{#2} % of niets + \recordoktrue + \recordokfalse}% % zullen we maar zeggen. + \ifrecordok + \let\askedrecords\v!all + \else + \makerawcommalist[#2]\askedrecords + \fi + \def\checkrecord##1% + {\rawdoifinsetelse{##1}{\askedrecords}{\recordoktrue}{}}% + \def\presetrecord##1% + {\let\setrecordentry\assignrecordentry + \let\memberofgroup\gobbleoneargument + \the\resetrecordlist + \def\stoprecord{\dostoprecord{##1}}}% + \def\memberofgroup##1% + {\doifsomething{##1} + {\rawprocesscommalist[##1]\checkrecord}% + \ifrecordok + \presetrecord{##1}% + \else + \expandafter\skiprecord + \fi}% + \def\startrecord##1% + {\bgroup + \ifrecordok + \presetrecord{##1}% + \else + \checkrecord{##1}% + \ifrecordok + \presetrecord{##1}% + \fi + \fi}% + \def\dostoprecord##1% + {\relax + \egroup + %\the\everyrecord + \getvalue{\??db#1\c!command}{##1}}% + \showmessage\m!databases1\askedrecords + \def\doprocessrecords##1% + {\readjobfile{##1} + {\showmessage\m!databases2{(job)}} + {\readsysfile{##1} + {\showmessage\m!databases3{(sys)}} + {\showmessage\m!databases4{}}}}% + \processcommalist[#3]\doprocessrecords + \egroup} + +%D While writing the original implementation, I did some +%D experiments with \type {%} before each entry and changing +%D the category code of the comment char. Because \TEX\ scans +%D the line anyway |<|this is needed because the end of line +%D character can be non standard|>| this is not faster. +%D +%D Although this mechanism could have been combined with the +%D block moving mechanism, the current implementation is +%D prefered out of speed reasons. + +\protect \endinput |