summaryrefslogtreecommitdiff
path: root/macros/latex/exptl/delimtxt/delimtxt.dtx
blob: 28b11ed95a2f783ac2d226946423cca2508c5331 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
% \iffalse
%<*drv>
\documentclass{ltxdoc}
\usepackage{doc}
\usepackage[T1]{fontenc}
\usepackage[ansinew]{inputenc}
\CodelineIndex
\parindent0pt
\setcounter{IndexColumns}{2}
\begin{document}
%\OnlyDescription  %Comment out for Desription only
\setlength\hfuzz{15pt}
\sloppy
\DocInput{delimtxt.dtx}
\end{document}
%</drv>
%\fi
% \MakeShortVerb{\|}
% \CheckSum{270}
% Copyright  1999 Bjoern Pedersen
% This program can be redistributed and/or modified under the terms
% of the LaTeX Project Public License Distributed from CTAN
% archives in directory macros/latex/base/lppl.txt; either
% version 1 of the License, or any later version.
%
%
%% This is heavily based on:
%% textmerg.dtx  (with options: `textmerg')
%% 
%% Copyright (C) 1992,1994 Mike Piff, University of Sheffield, England
% \section{Intro}
% This package tries do deal with single character delimited table
% files. It was mainly inspired and is heavily based on Mike Piff's
% textmerg package.
%
% Note for package writers:
% As this package is still under development, the interface is not g
% guaranteed to be stable. Please consider this if you want to use this
% package in your style files 
%
% \section{Description}
% \DescribeMacro{\SetDel}
% The |\SetDel<charactertoken>| set the character used as 
% a delimiter in the input file. The default is \texttt{\char126}.
% If the character does not have |\catcode=12|, you should adjust this
% before setting it as in this example:
% \begin{verbatim}
% {\catcode`\^^I=12
% \SetDel^^I}
% \end{verbatim}
% This would set  del to the <tab>-character 
%
% \DescribeMacro{\Fields}
% The |\Fields| macor takes a list of control sequence, which will be
% assigned during the read in process. 
% Example:
% \begin{verbatim}
% \Fields{\Title\Forenames\Surname\Address\Grade}
% \end{verbatim}
% 
% \DescribeMacro{\DelimRead}
% After defining the |\Fields|, a file is read in with
% |\DelimRead{File}{Template}|,
% where |File| is the filename of the data file, and |Template| is the
% text, in which occurences of the csnames in the |\Fields|-macro
% should be replaced by text from the data file.
%
% \StopEventually
% \section{Code}
% \subsection{Header}
% Announce the file.
%    \begin{macrocode}
%<*delimtxt> 
\def\fileversion{1.02}
\def\filedate{1999/05/03}
\def\filename{delimtxt.dtx}
\def\Copyright{Copyright 1999 Bjoern Pedersen}
\NeedsTeXFormat{LaTeX2e}[1998/06/01]
\ProvidesPackage{delimtxt}[\filedate]
\typeout{Package `delimtxt´ <\filedate>.}
\typeout{\Copyright}
%    \end{macrocode}
% \subsection{Utility macros}
%    \begin{macrocode}
\def\glet{\global\let}

%    \end{macrocode}
%\subsection{File Handling}
% This opens a file and reads it line by line into |\InputBuffer|.
%    \begin{macrocode}
\newread\DelimFile

\def\InputFile#1{%
   \openin\DelimFile=#1
   \ifeof\DelimFile
   \errmessage{Empty Delim file}%
   \closein\DelimFile
   \long\def\MakeTemplate##1{%
      \def\Template{}}%
   \else\GetInput
   \fi}
%    \end{macrocode}
%
% Adjust the catcode of the delimiter temporarily, and read one line
% of input.
%    \begin{macrocode}
\def\GetInput{{
 \global\LF@false
 \endlinechar=-1%
 \expandafter\catcode\expandafter`\the\Del=12
   \global\read\DelimFile to\InputBuffer}}
%    \end{macrocode}
%
%  Check, if there is anything left in the Input file. If not, stop
%   Iterating. Empty lines in the file are silently skipped.
%
%    \begin{macrocode}
\def\SeeIfEof{%
   \let\NextLook\relax
   \ifeof\DelimFile
   \else
      \ifx\InputBuffer\empty
         \LookAgain
      \fi
   \fi
   \NextLook}

\def\LookAgain{\GetInput
   \let\NextLook\SeeIfEof}
%    \end{macrocode}


%    \begin{macro}{\ifNonBlank}
%    \begin{macro}{\AllowBlank}
%    \begin{macro}{\DontAllowBlank}
%We can now prepare to read actual fields from the merge file. A conditional
%is used to indicate whether or not the field we are about to read is
%allowed to be blank. We also set up a mechanism for changing its value.
%    \begin{macrocode}
\newif\ifNonBlank \NonBlankfalse
\def\AllowBlank{\global\NonBlankfalse}
\def\DontAllowBlank{\global\NonBlanktrue}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}



% \subsection{Parsing the Input Buffer}
% This is the difficult part of the processing.
% \subsubsection{Helper macros and registers}
% We need some token registers to save the Input, the delimiter, and
% some of the definitions for dynamic parameter lists
%    \begin{macrocode}
\newif\ifLF@
\def\mark{\relax}
\newtoks\InPutField
\newtoks\Del
\newtoks\StripT@k
\newtoks\NextFieldT@k
%    \end{macrocode}
%\subsubsection{Strip mark helper}
% A helper macro to strip of a marker, we placed in the input
% stream. It is put in |\StripT@k| and the actual definiton will take
% place on execution of |\SetDel| as we need to know what the
% delimiter actually is.
%
%    \begin{macrocode}  
\StripT@k={%
{%
\aftergroup\gdef%
\aftergroup\StripMark%
\aftergroup#\aftergroup1%
\expandafter\aftergroup\the\Del%
\aftergroup\mark%
}{\gdef\InputBuffer{#1}}}
%    \end{macrocode}
% \subsubsection{Get the next Field value from the input stream }
% On execution of |\SetDel| this mess will define a macro
% |\GetNextInputField#1<expanded \del>#2\lineend|.
% This will perform somthing similar to the C language |strtok| function.
% This macro gets the contents of the |\InputBuffer| plus an extra
% delimiter, a mark and a lineend marker.
% On Exit |\InputBuffer| is reassigned with one less Field after
% stripping of all markers. 
% If nothing is left, a flag is set and |\InputBuffer| is set empty.
% This flag is currently unused, but could be used for better error
% handling in case of missing fields in the input.
%    \begin{macrocode}

\NextFieldT@k={%
{%begin of aftergroup group
\aftergroup\gdef%
\aftergroup\GetNextInputField%
\aftergroup#\aftergroup1%
\expandafter\aftergroup\the\Del%
\aftergroup#\aftergroup2%
\aftergroup\lineend}%end of aftergroup group
{%
 \if\mark #2% 
    \global\LF@true% 
     \glet\InputBuffer=\empty% 
  \else%
     \global\LF@false% 
     \StripMark#2% 
  \fi%
  \InPutField={#1}%
  \if!#1!% check if Field is empty (Ref: D.Carlise in comp.text.tex)
      \ifNonBlank%
         \MissingField%
         \InPutField={???}%  
      \else%
         \InPutField={#1}%
      \fi%
      \else
      \relax	
  \fi%
}}
%    \end{macrocode}
%
%  This macro sets the Delimiter. As this may be called at any time,
%  we need  to redefine the macros |\GetNextInputField|
%  and |\StripMark|. The definitions have been stored in two token
%  registers, so we have just to execute them. The trickery with
%  |\aftergroup| in the token list enables expansion of |\the\Del| in
%  the macro parameter list.
%
%
%    \begin{macrocode}
\def\SetDel#1{\global\Del={#1}%
\the\StripT@k%
\the\NextFieldT@k%
}
\SetDel|


%    \end{macrocode}
% \subsection{Parsing the fields}
% Here we parse the inout fields as in the textmerg package, but
% getting values from our new parser. Probably, the treatment of
% missing items is not very good( in fact it is completly missing)
% We have to put a |\mark| and |\lineend| in the stream, do detect
% the end of the input line.
%
%    \begin{macrocode}

\def\ReadIn#1{%
     \expandafter\expandafter\expandafter%
     \GetNextInputField%
     \expandafter\InputBuffer\the\Del%
     \mark\lineend%
      \global\edef#1{\the\InPutField}%
}
%    \end{macrocode}
% This is not used yet. 
%    \begin{macrocode}
\def\MissingField{%
  \message{Missing field in file}}
%    \end{macrocode}
%
% Here begins the field parsing, as in the textmerg-package.
%
%    \begin{macrocode}

\newtoks\GlobalFields
%
\def\Fields#1{\GlobalFields{#1}}
%
\def\ParseFields#1{%
  \ifx#1\EndParseFields%
  \let\NextParse\relax%
      \ifLF@% 
        \message{ Line was OK}%
      \else%
        {\message{ There were more items than fields on line
        \the\Iteratecounter.  They will be skipped.}
        \glet\InputBuffer=\empty}%
      \fi%
  \else%
      \let\NextParse\ParseFields%
      \ifx#1+\DontAllowBlank%
      \else%
         \ifx#1-\AllowBlank%
         \else\ReadIn#1%
         \fi%
      \fi%
  \fi\NextParse}%

\let\EndParseFields\ParseFields%
%    \end{macrocode}
%    \begin{macrocode}
\def\ReadFields#1{
\ifeof\DelimFile%
  \else%
\expandafter\ParseFields%
  \the#1\EndParseFields%
\fi}%
%    \end{macrocode}
%\subsection{The iteration code}
%    \begin{macrocode}
\long\def\DelimRead#1#2{\begingroup%
   \InputFile{#1}%
   \def\Fields##1{%
      \ParseFields##1\EndParseFields}%
   \MakeTemplate{#2}\Iterate}%
%    \end{macrocode}
%    \begin{macrocode}
\long\def\MakeTemplate#1{\def\Template{#1}}
%    \end{macrocode}
%    \begin{macrocode}
\countdef\Iteratecounter=1%

\Iteratecounter=0
\def\Iterate{%
   \global\advance\Iteratecounter by1%
   \ReadFields\GlobalFields%
   \Template%
   \SeeIfEof%
   \ifeof\DelimFile%
      \def\NextIteration{%
         \endgroup\closein\DelimFile}%
   \else%     
      \let\NextIteration\Iterate%
   \fi%
   \NextIteration}
\endinput
%    \end{macrocode}
%</delimtxt>
%\Finale