% macro polyset %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Petr Olsak Sep. 2003 % This macro expands sequences of type "ab{12}c{123}de" to sequences: % "ab1c1de" "ab1c2de" "ab1c3de" "ab2c1de" "ab2c2de" "ab2c3de". % % For more information see end of this file. \newtoks\leftpart \newtoks\rightpart \newtoks\restpart \def\applyset#1{\def\cumuseq{}\letleftseq #1{}\sep{}\sep} \def\letleftseq #1#{\def\tmp{#1}\letrest} \def\letrest #1#2\sep{\edef\oneset{#1} \ifx\oneset\empty \ifx\tmp\empty \ifx\cumuseq\empty \let\next=\relax % finish \else \let\next=\resetseq % next batch of sequences \fi \else \expandafter \runseq \expandafter {\tmp}\let\next=\letleftseq % next sequence \fi \else % expand sequence \leftpart=\expandafter{\tmp}\rightpart={#2} \def\tmp{#2}\ifx\tmp\empty \rightpart={{}}\fi \expandseq \let\next=\letleftseq \fi \next} \def\resetseq{\let\tmp=\cumuseq \def\cumuseq{} \expandafter \letleftseq \tmp {}\sep} \def\expandseq { \ifx\oneset\empty \else \expandafter \letelement \oneset \sep \restpart=\expandafter{\cumuseq} \edef \cumuseq{\the\restpart \the\leftpart \firstelement \the\rightpart \noexpand\sep } \expandafter \expandseq \fi} \def\letelement #1#2\sep{\def\firstelement{#1}\def\oneset{#2}} \def\runseq #1{\message{#1}} \endinput %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% If you type, for example, \applyset{ab{12}c{123}de} then TeX runs \runseq{ab1c1de} \runseq{ab1c2de} \runseq{ab1c3de} \runseq{ab2c1de} \runseq{ab2c2de} \runseq{ab2c3de} Generally: If the argument of \applyset includes "sets" typed by {...}, then each set is replaced by its elements: successively all elements from each set is used. The \runseq macro is invoked to all resulting sequences. The body of each set {...} is expanded before getting the elements. On the other hand, the text surrounded of the sets is not expanded during \applyset is working. An example of an application of this macro follows. It gives the possibility of more powerfull \mubyte ... \endmubyte declarations for encTeX: ------------------------------------------------------------------------ \input polyset \def\setmubyte #1#2{\def\runseq##1{\mubyte #1 ##1\endmubyte}\applyset{#2}} \def\ndigits {123456789} \def\digits {0\ndigits} \setmubyte {\dat ##0} {{\ndigits}.{\ndigits}.} %% needs encTeX v. Feb. 2003 \setmubyte {\dat ##0} {{12}{\digits}.{\ndigits}.} \setmubyte {\dat ##0} {3{01}.{\ndigits}.} \setmubyte {\dat ##0} {{\ndigits}.1{012}.} \setmubyte {\dat ##0} {{12}{\digits}.1{012}.} \setmubyte {\dat ##0} {3{01}.1{012}.} %% total: 372 \mubyte %% declarations \def\dat #1.#2.{#1.\kern.15em #2.} \mubytein=1 This example inserts the little space in (czech) date format automaticaly. Example 24.12. -> 24.\kern.15em 12. (means December 24). \end