\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,xyz,.' where is the % contents of the style list, then #2 will not be empty if and only if the % pattern `,xyz,' is part of , 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 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