summaryrefslogtreecommitdiff
path: root/macros/generic/midnight/styledef.tex
blob: 8de7650d5e4fd3c17a788cfc0fed7ebc4559b900 (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
\ifx\STYLEDEF\relax\endinput\else\let\STYLEDEF=\relax\fi % \input only once
%
% styledef.tex: Macros to selectively input parts of a file.
% version: 1.0  release: 16 April 1991
%
% copyright (c) 1991 Marcel R. van der Goot
%	You can use these macros to typeset documents. You may
%	distribute this file freely, provided that you also distribute
%	the accompanying documentation.
%	    You may make changes to this file, or extract portions
%	of it for inclusion in other files, provided that
%	    (1) you change the name of the file;
%	    (2) you give proper credit and include copyright
%		information where applicable;
%	    (3) explain how an unchanged version can be obtained; and
%	    (4) document the usage of your macros/changes (if usage
%		of your macros is not worth documenting, they must not
%		be worth using).
%	You are not allowed to use the name ``Midnight Macros'' for
%	any changed files.
%	    The above rules for making changes do not apply where it
%	is explicitly noted in this file that something can be changed
%	to conform to your local installation.
%
% USAGE:
%   See the file styledef.doc.
%   You need Midnight/dolines.tex and Midnight/loop.tex to use these macros.
%
% original: csvax.cs.caltech.edu [131.215.131.131] in pub/tex
%	    (use anonymous ftp). Also in various archives.
%
% Caltech, Pasadena  ---  Marcel van der Goot
%			  marcel@cs.caltech.edu
%			    Caltech 256--80
%			    Pasadena, CA 91125
%			    USA
%			    (818) 356--4603
%

% update history:
% version 1.0: This one.
%	release 16 April 1991: the original (this one)
%

%%%%%% CODE: (you don't need to read this to use the macros)

\edef\next{\the\catcode`\_} % to remember that catcode
\catcode`\_=11 % 11=letter (for private macros)

%%%%%%%%%%%%%%%%%%%% the current style list
% A style list is represented by a token register. The register is either
% empty or contains a sequence of words separated by single commas (no spaces).
% A non-empty list starts with a comma. A list denotation is a list of words
% separated by commas and spaces.
% \setstyle#1#2. makes style list reg #1 equal to #2 (a list denotation),
% \addstyle#1#2. adds the list #2 to the list register #1.

\let\newstyle=\newtoks

\def\setstyle#1#2% #1 a token reg, #2 a list denotation
   {#1={}%
    \make_stylelist#1#2 .% space before the dot
   }

\def\addstyle#1#2% #1 a token reg, #2 a list denotation
   {\make_stylelist#1#2 .% space before the dot
   }

%%%%%%%%%%%%%%%%%%%% reading a style list denotation
% \make_stylelist takes as first argument the name of a token register.
% Following that name there should be a list of words separated by spaces
% and/or commas, terminated by ` .' (a space and a dot). It constructs
% the corresponding style list in #1.
% \make_stylelist takes the sequence up till the first space, calls
% \nocomma_stylelist with that sequence, and recurses with the sequence after
% the first space. \nocomma_stylelist works similarly, but strips a comma
% rather than a space. (Note: separation by single commas without spaces
% is slightly more efficient.)

\def\eat_style#1.{} % skip everything till first dot

\def\make_stylelist#1#2 #3.% #1=name of list; #2#3=list ending in ` .'
   {\if.#2.\else\nocomma_stylelist#1#2,.\fi
    \if.#3.\let\style_tmp=\eat_style
    \else\let\style_tmp=\make_stylelist
    \fi
    \style_tmp#1#3.%
   }

\def\nocomma_stylelist#1#2,#3.% #1=name of list; #2#3=list ending in `,.'
   {\if.#2.\else#1=\expandafter{\the#1,#2}\fi
    \if.#3.\let\style_tmp=\eat_style
    \else\let\style_tmp=\nocomma_stylelist
    \fi
    \style_tmp#1#3.%
   }

%%%%%%%%%%%%%%%%%%%% determining whether lists intersect
% \isect_style is used to check whether two lists have a non-empty
% intersection. The switch \if_style will be set to indicate whether
% the lists intersect.
% \style_member takes two arguments, a style list register and a word.
% It sets the switch if the word is in the style list. This check is done
% by TeX's pattern match mechanism rather than through word-by-word comparison:
% To check for the presence of word `xyz' a macro `\style_tmp#1,xyz,#2.' is
% defined. If it is called as `\style_tmp<list>,xyz,.' where <list> is the
% contents of the style list, then #2 will not be empty if and only if the
% pattern `,xyz,' is part of <list>, i.e., iff `xyz' is in the list.
% \doisect_style calls \style_member repeatedly for each word in the second
% list.

\newif\if_style

\def\style_member#1#2% #1 a style list (token reg), #2 a word
   {\def\style_tmp##1,#2,##2.{\check_style{##2}}%
    \expandafter\style_tmp\the#1,#2,.%
   }

\def\check_style#1% check whether #1 is empty
   {\if.#1.\else\_styletrue\fi
   }

\def\doisect_style#1,#2,#3.%  #1=reg, #2#3=expansion of list reg ending in ,.
   {\if.#2.\else\style_member#1{#2}\fi
    \if_style\let\style_tmp=\eat_style
    \else\if.#3.\let\style_tmp=\eat_style
         \else\let\style_tmp=\doisect_style
    \fi  \fi
    \style_tmp#1,#3.%
   }

\def\isect_style#1#2% two list regs
   {\_stylefalse
    \expandafter\doisect_style\expandafter#1\the#2,,.% extra comma for #2={}
   }

%%%%%%%%%%%%%%%%%%%% including a style
% \readstyle takes a style list register and a filename. It puts the style list
% in \style_list, then inputs the file.
% \skip_style skips everything till the next \endstyle. It uses
% dolines.tex to read the input line-by-line. To make that possible,
% the grouping characters are disabled (because they must balance on a line),
% the comment char is disabled (because it causes wraparound), the argument
% character is disabled (because a macro is defined that has the line as
% body --- it should not have undeclared arguments in the body), and the
% escape character is disabled (not to prevent expansion, but to prevent lines
% containing an `outer' control sequence). Note: If you wanted a real
% ``comment environment,'' you should set all catcodes of all characters to
% 11 or 12.
% \styledef and \negstyledef have list denotations as arguments. They create
% a list \style_other, then skip based on the intersection of \style_other
% and \style_list. If no skip is done, \endstyle is equivalent to \relax.
% \savereadstyle and \setreadstyle serve to access the protected \style_list
% register.

\input Midnight/dolines

\newtoks\style_list
\newtoks\style_other

\def\readstyle#1#2% #1 a token reg, #2 a filename
   {\style_list=#1%
    \input#2 % significant space (sometimes)
   }

\def\savereadstyle#1% a style (token) reg
   {#1=\style_list}

\def\setreadstyle#1% a style reg
   {\style_list=#1}

{\catcode`\/=0 /catcode`/\=12 % see dolines.doc
 /gdef/end_style{\endstyle}
}

\let\endstyle=\relax

\def\skip_style
   {\begingroup
    \let\beforelines=\relax
    \let\afterlines=\relax
    \def\everyline##1{}%
    \let\enddolines=\end_style
    \let\finishdolines=\endgroup
    \catcode`\{=12 \catcode`\}=12 \catcode`\%=12
    \catcode`\#=12 \catcode`\\=12
    \begindolines
   }

\def\styledef#1% #1 a list denotation
   {\style_other={}%
    \make_stylelist\style_other#1 .% space before dot
    \isect_style\style_list\style_other
    \if_style
    \else\expandafter\skip_style
    \fi
   }

\def\negstyledef#1% #1 a list denotation
   {\style_other={}%
    \make_stylelist\style_other#1 .% space before dot
    \isect_style\style_list\style_other
    \if_style\expandafter\skip_style\fi
   }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\catcode`\_=\next