summaryrefslogtreecommitdiff
path: root/macros/generic/olsak-misc/cnv-word.tex
blob: 5a8f3e13a52aefa8e61489b6553aaa5cff503c7e (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
% cnv-word.tex --- an example of the usage of cnv.tex: word to word converting
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% April 2005                                                 Petr Olsak

\input cnv

% This file is a complex example of the usage of cnv.tex macro.
% The macros presented here give the possibility to declare word to word
% conversion a of given string. Each occurence of declared words will be
% converted to the declared outputs.

% Double percent: "%%" is a prefix of technical comments. 
% Please, read the "user" comments (prefixed by one "%") first.

%% \wtest is an internal macro which tests if the given {pattern} matches
%% the begin of the input stream. If it is true then other \wtests
%% are ignored and a given {output} is stored to \cnvout. The input
%% stream is reduced by the pattern. Else input stream is restored 
%% and the next \wtest is run. We suppose the following parameters:
%% \wtest{pattern}{output}\wtest{pattern}{output}...\endwtest{letter}input stream\END

%% The main idea of \wtest is to declare the macro \trywtest by:
%% \def\trywtest #1pattern#2\end and run it by:
%% \trywtest input-stream\END pattern\end. If #1 is empty then pattern
%% matches.

\gdef\wtest #1#2#3\endwtest#4#5\END {\def\wout{#2}\def\otherwtests{#3}%
   \def\inputstream{#5}%
   \def\trywtest ##1#1##2\end {\def\tmp{##1}%
       \def\tmpa{#1}\ifx\tmpa\empty \def\tmp{}\fi % empty pattern
       \ifx\tmp\empty % found!
          \def\next{\cnvstoree{\expandafter \cnvout \wout}%
                    \expandafter \cnvcontinue \inputstream\END}%
       \else          % not found!
          \def\next{\expandafter\otherwtests\expandafter\endwtest
                    \expandafter{\expandafter#4\expandafter}% 
                    \inputstream \END}%
       \fi \next}
   \def\cnvcontinue #1{\cnvnext}%
   \expandafter\trywtest \inputstream \END#1\end
}

%% \stringdef {<letter><pattern>}  {<output>}
%% adds to the internal cnv macro \E:<letter>:<table> the next part of
%% the type "\wtest{pattern}{output}" The \E:<letter>:<table> looks like:
%% \cnvexec \wtest{pattern1}{output1}\wtest{pattern2}{output2}...\endwtest{<letter>}
%% The new "\wtest{pattern}{output}" is added at the end of \wtests
%% string before \endwtest{letter}.

\def\wstringdef #1#2 #3{%
   \expandafter\ifx \csname E:\string#1:\cnvtable\endcsname \relax
      \def\tmp{}%
   \else
      \expandafter\expandafter\expandafter 
      \wstoretmp \csname E:\string#1:\cnvtable\endcsname
   \fi
   \expandafter \def
   \csname E:\string#1:\cnvtable \expandafter\endcsname \expandafter 
       {\expandafter \cnvexec \tmp \wtest{#2}{#3}\endwtest{#1}}
}
\def\wstoretmp \cnvexec #1\endwtest#2{\def\tmp{#1}}
\def\stringdef #1#2{\wstringdef #1 {#2}}

%% If all wtests fail then \endwtest{<letter>} is processed. It adds
%% the <letter> itself to the \cnvout. 

\def\endwtest#1{\def\tmp{#1}%
   \ifx\tmp\inSPACE \cnvstoree{\expandafter \cnvout \space}%
   \else \cnvstore{\cnvout #1}
   \fi\cnvnext}
\def\inSPACE{\SPACE}

%% The \wconvert{<input token list>} does the main conversion. It runs
%% \cnvin twice (with different tables). First conversion converts the
%% spaces to \SPACE tokens and braces to \BGROUP and \EGROUP tokens. The
%% reason is that now we can read \SPACE and converted braces to #1 parameter
%% without changes. This is needed in \wtest macro. No matter that
%% \SPACE is undefined. We never process it by normal \TeX{} expansion.

%% The second conversion (with table 2) does the real word to word conversion and 
%% returns the \SPACE \BGROUP and \EGROUP to the desired output. 

\def\wconvert #1{%
   \def\cnvtable{1}\cnvin{#1}
   \def\cnvtable{2}%
   \expandafter \cnvin \expandafter {\cnvout \END}}

%% Table 1: only converts spaces and braces

\def\cnvtable{1}
\findef { } {\SPACE}

%% Table 2: the \END mark is ignored and \SPACE is converted back to space

\def\cnvtable{2}
\findef \END    {}
\findef \SPACE  { }

%% We have to keep the \BGROUP and \EGROUP unchanged. Unfortunately,
%% the declaration:
%%
%% \let\findefmethod=\edef
%% \findef \BGROUP {{\iffalse}\fi}
%% \findef \EGROUP {\iffalse{\fi}}
%%
%% does not work because the cnv macro fails: the \output macro needs
%% to be balanced text everytime during conversion process. It means 
%% that there is impossible to return the input tokens of catcode 1
%% and 2 to their original maening. We can return them to their original 
%% meaning only if the \cnvout can be normally expanded. In such a case,
%% we can write after \wconvert is done:
%%
%% \bgroup \def\BGROUP {{\iffalse}\fi} \def\EGROUP {\iffalse{\fi}}
%%         \xdef \cnvout{\cnvout} \egroup 

% Users can declare the "word to word" conversion here. Each string declared at
% the left hand side will be converted to the output at the right hand side.
% If there are more left side strings with the same initial letter then
% the table is read in this order during the conversion. It means
% that the last declaration in the following example is irrelevant:
% if the string begins by "th" then the result of conversion is "TH"
% and the last declaration of "the" is ignored.

\stringdef  {input}      {output}
\stringdef  {this}       {THIS}
\stringdef  {test}       {TEST}
\stringdef  {th}         {TH}
\stringdef  {the}        {THE}

% Now, we can try this declaration.

\wconvert {this is a test of the motherboard input}
\message  {"\cnvout"}

% The result is: "THIS is a TEST of THe moTHerboard output".

% Users have to use the \SPACE or \BGROUP or \EGROUP instead of real tokens
% of catcode 10, 1 and 2 at the left hand side of the declaration:

\stringdef {\SPACE the}  { !THE!}

\wconvert {this is a test of the motherboard input}
\message  {output: "\meaning\cnvout"}

\end