% mkpatter.tex Version 1.2
%
% This file is part of the program mkpattern, and all files
% that belong to that program must be distributed together.
%
% For this version 1.2, this file mkpatter.tex is the only file
% belonging to the program mkpattern.
%
% The file mkpatter.dvi (or mkpatter.pdf) is a manual for this program.
% It is very likely that you may obtain it at the same place
% where you got this file from.
%
% (c) Javier A. M'ugica, 2006, 2007, 2008
% License: LPPL version 1.3
%
% LPPL maintenance status: maintained
% Current Maintainer: Javier A. M'ugica
%
%       For bug reports and comments:
%
%       Javier M'ugica,   javier at digi21.eu
%
%
\ifnum\catcode`\{=1
\catcode`\$=12 %
\catcode`\&=12 %
\catcode`\^^K=12 %
\catcode`\^^A=12 %
\let\bye\undefined
\fi

\chardef\active=13
\catcode`\{=1
\catcode`\}=2
\catcode`\#=6 % hash mark is macro parameter character
\catcode`\^=7
\catcode`\^^I=10 % ascii tab is a blank space
\catcode`\^^M=9 %We need a \relax after some numbers at the end of a line
\catcode`\^^L=\active \outer\def^^L{\par} % ascii form-feed is "\outer\par"
\catcode`\&=12
\catcode`\_=11
\catcode`\~=11
\catcode`\@=11\relax

%Latex
\catcode`\:=11\relax
\ifx\@@end\undefined\else\let\end\@@end \let\@@end\undefined\fi
\ifx\tex_end:D\undefined\else \let\end\tex_end:D \let\tex_end:D\undefined\fi
\catcode`\:=12\relax

\newlinechar=`\^^J
\message{This is Mkpattern, Version 1.2 JUN 2008^^J}
\let\bgroup={
\let\egroup=}

\def\empty{}
\def\space{ }
\def\qend{\qend}
\countdef\m@ne=10 \m@ne=-1 %
\def\_qlast{?_qlast}
{\escapechar=\m@ne\relax
 \xdef\backslash{\string\\}
 \xdef\percent{\string\%}
}

\count11=9      %Allocates toks registers: 10, 11, ...
\count12=14 %Allocates count registers: 15, 16, ...
\count13=2  %Input streams: 3, ...
\count14=2  %Output streams: 3, ...
\def\wlog{\immediate\write\m@ne}
\countdef\@@count=0
\toksdef\tokscclv=255\relax
\toksdef\toks@=0\relax
\toksdef\toks@ne=1\relax
\toksdef\toksv=5\relax  %It will no be changed by low level macros
\toksdef\toksvi=6\relax %It will no be changed by low level macros
\outer\def\newtoks#1{\advance\count11 1 \toksdef#1=\count11%
 \wlog{\string#1=\backslash toks\the\count11}}
\outer\def\newcount#1{\advance\count12 1 \countdef#1=\count12%
 \wlog{\string#1=\backslash count\the\count12}}
%These two are not used but are provided to the users
\outer\def\newread#1{\advance\count13 1 \chardef#1=\count13%
 \wlog{\string#1=\backslash read\the\count13}}
\outer\def\newwrite#1{\advance\count14 1 \chardef#1=\count14%
 \wlog{\string#1=\backslash write\the\count14}}

%Tracing switches. There isn't actually very much to trace
\newcount\tracingexceptions \tracingexceptions=0\relax

\edef\outputfilename{\jobname.pat}

\def\filename{\bgroup
 \catcode`\|=12
 \count255='176 \@@count=256 \makeothers
 \count255=0 \@@count='173 \makeothers
 \_filename
}
\def\_filename#1{\gdef\outputfilename{#1}\egroup}

\def\iwrite{\immediate\openout0=\outputfilename
       \gdef\filename##1{\errmessage{Too late for changing the output file name}}
       \gdef\iwrite{\immediate\write0 }\iwrite
}

\let\iffound\iffalse

\let\~~end\end
\def\~end{\ifnum\tracingexceptions>0\expandafter\reportmissingexceptios\fi\~~end}
\def\begin#1{\csname#1\endcsname}
\def\end#1{\def\tempa{#1}\ifx\tempa\empty\expandafter\~end\fi\csname end#1\endcsname}

\newtoks\toksnames \toksnames={}
\newtoks\tokslista
\newtoks\linesofar \linesofar={}
\newtoks\toksencoding \toksencoding={}
\newtoks\toksletters \toksletters={}

\def\writeline{\iwrite{\the\linesofar}\global\linesofar={}}
\def\conditwrite{\edef\tempa{\the\linesofar}\ifx\tempa\empty\else\writeline\fi}
\def\newline{\writeline\lee}

%Change of july 2008
\def\newwriteline{\edef\tempa{\the\linesofar}\ifx\tempa\empty\global\linesofar=\expandafter{\percent}\fi\~writeline}
\let\ifoldnewlines\iffalse
\def\newnewlines{\let\ifoldnewlines\iffalse\let\fi\fi}
\def\oldnewlines{\let\ifoldnewlines\iftrue\let\fi\fi}
%

\def\busca#1#2{%        It will usually also work with #1 being lenghtier than one character,
\def\encuentra##1#1##2\quend{%but if the ending can be overlaped with the beginning it may not.
 \def\tempa{##2}
 \ifx\tempa\empty\tokscclv{iffalse}
 \else\tokscclv{iftrue}
 \fi
 \expandafter\let\expandafter\iffound\csname\the\tokscclv\endcsname
}
\encuentra#2#1\quend
}

\def\first#1#2\qend{#1}
\def\second#1#2\qend{#2}

{
\catcode`\&=13
\gdef&#1={
 \catcode`\&=0\relax
 \defineamp{#1}
}
}
\def\defineamp#1#2{
 \expandafter\edef\csname#1\endcsname{#2 }
 \catcode`\&=13\relax
 %Add #1 to the list of names *at the right*; they must be executed in order.
 \toksnames\expandafter{\the\toksnames\\{#1}}
}
\def\makelists{
\def\\##1{\expandafter\makelist\csname##1\endcsname}
\the\toksnames
}
\def\makelist#1{
\tokslista={}
\expandafter\appendtolist#1\qend        %#1 contains at least a trailing space
{\def\\##1{##1 }
\edef\tempa{\expandafter\empty\the\tokslista}
\wlog{\string#1 :->\tempa}}
\edef#1{\the\tokslista}
}
\def\appendtolist#1 #2\qend{
 \def\tempa{#2}
 \ifx\tempa\empty
   \def\next{}
 \else
   \def\next{\appendtolist#2\qend}
 \fi
 \def\tempa{#1}
 \ifx\tempa\empty  %if #2 is not empty we have gobbled a leading space
 \else
   \tokslista\expandafter{\the\tokslista\\{#1}}
 \fi
 \next
}

\def\lee{\gobbles\_lee}
\def\gobbles#1#2{%      this just gobbles up and then executes #1
%Test if #2 is a single token
\def\tempa{#2}
\ifx\tempa\empty\else
\edef\tempa{\second#2\qend}
\fi
\ifx\tempa\empty\def\next{#1#2}
\else\def\next{#1{#2}}
\fi
\next
}

\def\_lee#1{
\edef\tempa{\expandafter\first\string#1a\qend}% The letter a is just in case #1 is empty
\ifx\tempa\backslash\expandafter#1%     Each control sequence that may appear inside pseudopatterns must provide its own \lee at the end
\else\ifx\tempa\percent
 \catcode13=12
 \def\next{\comment#1}
\else
 \def\tempa{#1}%Test if #1 is a single token
 \ifx\tempa\empty\else
 \edef\tempa{\second#1\qend}
 \fi
 \ifx\tempa\empty\def\next{\__lee#1}
 \else\def\next{\__lee{#1}}
 \fi
\fi
\expandafter\next\fi
}

\def\__lee#1 {%Do not remove this space
%Backslash and comment handled above
%\else
 \ifappliedtemplate
   \busca{&}{#1}
   \iffound
     \edef\tempa{\the\linesofar}\ifx\tempa\empty\else\writeline\fi
     \advance\c_amp1 %
     \tokslista={}\procesamacro\tokslista{#1}
     \def\next{\expandafter\lee\the\tokslista%
     \advance\c_amp\m@ne \writeline\lee}
   \else
     \def\texto{#1}
     \edef\tempa{\the\toksexceptions}
     \ifx\tempa\empty\else\substituteifneeded\texto{#1}\fi
     \toks@\expandafter{\texto}
     \edef\tempa{\noexpand\linesofar{\the\linesofar\the\toks@\space}}
     \tempa
     \def\next{\lee}
   \fi
 \else
   \tokscclv{#1}
   \edef\texto{\the\pretemplate\the\tokscclv \the\posttemplate}
   \let\ifappliedtemplate\iftrue\let\fi\fi
   \def\next{\expandafter\lee\texto\let\ifappliedtemplate\iffalse\let\fi\fi \lee}
 \fi
%\fi
\next
}

\def\procesamacro#1#2{
\leemacro#2\qend
\def\\##1{%
 \edef\tempa{\the\tokslista\the\premacro##1\the\postmacro}
 \tokslista\expandafter{\tempa}
}
\csname\macro\endcsname
}
\def\leemacro#1&#2#3\qend{
\premacro={#1}
\def\macro{#2}
\postmacro={#3 }
}

\def\template#1{
 \conditwrite\writeline
 \bgroup
 \savetemplate#1\qend
 \let\ifappliedtemplate\iffalse
 \lee
}
\def\endtemplate{\conditwrite\egroup\lee}

\catcode`\$=6
\catcode`\#=12
\def\savetemplate$1#$2\qend{
\pretemplate={$1}
\posttemplate={$2 }
}
\catcode`\#=6

\newtoks\premacro
\newtoks\postmacro
\newtoks\pretemplate
\newtoks\posttemplate
\newtoks\toksexceptions
\newtoks\substitutions

%Change of july 2008
\def\oldnewstuff{
       \let\ifopened\ifoldnewlines
       \edef\tempa{\the\toksencoding}
 \ifx\tempa\empty\else
       \let\ifopened\iftrue\let\fi\fi
 \fi
 \ifopened
         \iwrite{\string{\iffalse}\fi}
       \fi
 \ifx\tempa\empty\else\writeencodingreplacements \iwrite{}\fi
 \conditwrite
 \ifoldnewlines
         \iwrite{\string\catcode13=10 }
       \else
               \let\~writeline\writeline
               \let\writeline\newwriteline
       \fi
       \def\oldnewlines{\relax\lee}
       \let\newnewlines\oldnewlines
}
%
\def\pseudopatterns{
 \makelists\wlog{}
 \writeletters \iwrite{} %We cannot use newline
 \oldnewstuff
 \iwrite{\string\patterns\string{\iffalse}\fi}
 \bgroup
 \catcode`\#=12
 \catcode`\&=12
 \catcode`\,=12
 \let\ifappliedtemplate\iftrue
 \c_amp=0 %finally not used, but kept updated
 \toksexceptions={}
 \substitutions={}
 \catcode`\^^M=10
 \let\lee\~~lee
 \halfcomments %this itself includes lee
}
\def\endpseudopatterns{\conditwrite\iwrite{\iffalse{\fi\string}}\egroup
 \ifoldnewlines\iwrite{\string\catcode13=5}\fi
 \ifopened\iwrite{\iffalse{\fi\string}}\fi
 \lee
}

\def\~put#1{\expandafter\global\expandafter\linesofar\expandafter{\the\linesofar #1}\egroup\lee}
\gdef\put{\bgroup
 \catcode`\|=12
 \count255='176 \@@count=256 \makeothers
 \count255=0 \@@count='173 \makeothers
 \~put
}

\def\nocomments{\catcode`\%=14 \lee}
\def\keepcomments{\catcode`\%=12 \let\comment\copycomment\lee}
\def\halfcomments{\catcode`\%=12 \let\comment\swallowcomment\lee}
{\catcode13=12 %
\gdef\copycomment#1
{\tokscclv={#1}\conditwrite\iwrite{\the\tokscclv}\catcode13=10 \lee}%
\gdef\swallowcomment#1
{\catcode13=10 \lee}%
}

\def\appendtoks_fromdelimiter#1#2#3{
\toks@=#1
\tokscclv={#2#3?_qlast#3}
\expandafter\ifx\csname _appendtoks_fromdelimiter#3\endcsname\relax             %Don, this should be undefined
 \expandafter\gdef\csname _appendtoks_fromdelimiter#3\endcsname##1#3{
 \def\tempa{##1}
 \ifx\tempa\_qlast
 \else
   \toks@\expandafter{\the\toks@\\{##1}}
   \def\next{\expandafter\gobbles\csname _appendtoks_fromdelimiter#3\endcsname}
   \expandafter\next
 \fi
 }
\fi
\edef\next{\noexpand\gobbles\expandafter\noexpand\csname _appendtoks_fromdelimiter#3\endcsname\the\tokscclv}
\next
#1=\toks@
}

\def\appendtoks_fromspace#1#2{\appendtoks_fromdelimiter#1{#2}{ }}
\def\appendtoks_fromcomma#1#2{\appendtoks_fromdelimiter#1{#2}{,}}

\def\exceptions#1{\catcode`\ =12 \_exceptions{#1}}
\def\_exceptions#1#2{
 \catcode`\ =10 %
 \appendtoks_fromspace\toksexceptions{#1}
 \def\tempa{#2}
 \ifx\tempa\empty
   \tokscclv={#1 ?_qlast }
   \expandafter\gobbles\expandafter\makeemptysubs\the\tokscclv
 \else
   \appendtoks_fromcomma\substitutions{#2}
 \fi
 \lee
}

\def\makeemptysubs#1 {
\def\tempa{#1}
\ifx\tempa\_qlast
\else
 \countchars\@@count{#1}
 \advance\@@count 1 %
 \makeempty\tempa\@@count
 \edef\next{\noexpand\substitutions{\the\substitutions\noexpand\\{\tempa}}}
 \next
 \def\next{\gobbles\makeemptysubs}
 \expandafter\next
\fi
}

\def\countchars#1#2{
\count255=\m@ne
\_countchars#2a\qend    %Ensure that there is at least one token
#1=\count255\relax
}
\def\_countchars#1#2{
\ifx#2\qend\else
\advance\count255 by 1\relax
\def\next{\_countchars#2}
\expandafter\next\fi
}

\def\makeempty#1#2{
\def#1{}
\def\next{\ifnum#2=0 \else\edef#1{#1 }\advance#2 \m@ne \expandafter\next\fi}
\next
}

\def\substituteifneeded#1#2{
 \def\tempb{#2}
 \toks@={} \toks@ne={}
 \def\\##1{\def\tempa{##1}
   \ifx\tempa\qend
     \toksexceptions\toks@
     \toks@={}
     \substitutions\toks@ne
     \toks@ne={}
   \else\ifx\tempa\tempb
       \pop\toksexceptions
     \edef\tempa{\global\noexpand\toksexceptions{\the\toks@\the\toksexceptions}}
     \tempa
     \pushpopmacro#1\substitutions
     \edef\tempa{\global\noexpand\substitutions{\the\toks@ne\the\substitutions}}
     \tempa
     \def\\####1{}     %gobble the remaining \\{...}
     \ifnum\tracingexceptions>0 %
               \wlog{Replacing the pattern {\tempb} with {#1}}
       \fi
   \else
     \let\tempa\\
     \pushpop\toks@\toksexceptions
     \pushpop\toks@ne\substitutions
     \let\\\tempa
   \fi\fi
 }
 \the\toksexceptions\\{\qend}
}

\def\pop#1{
\def\\##1##2//{#1={##2}}
\the#1//
}
\def\pushpop#1#2{
 \def\\##1##2//{
   #1=\expandafter{\the#1\\{##1}}
   #2={##2}
 }
 \the#2//
}
\def\pushpopmacro#1#2{
 \def\\##1##2//{
   \def#1{##1}
   #2={##2}
 }
 \the#2//
}

\def\reportmissingexceptios{
\def\\##1{\wlog{The exception {##1} did not arise.}}
\the\toksexceptions
}

\def\mixtoks#1#2{
\tokscclv=#1
\toks@=#2
#1={}
\def\tempa##1{#1=\expandafter{\the#1\\{##1}}\let\\=\tempb \the#2//}
\def\tempb##1##2//{#1=\expandafter{\the#1{##1}}#2={##2}\let\\=\tempa}
\let\\=\tempa
\the\tokscclv
}

\def\finalreplacement#1#2{#1={#2}}
\def\charreplacement#1#2{
#1={#2} %In case it is not found
\def\tempa{#2}
\let\oldslash\\
\def\\##1##2{\def\tempb{##1}
 \ifx\tempa\tempb
   #1={##2}
   \def\\####1####2{}
 \fi
}
\the\toksencoding
\let\\=\oldslash
}

\def\letters#1{\appendtoks_fromspace\toksletters{#1}}

\def\encodingreplacements#1#2{
\appendtoks_fromspace\toksv{#1}
\appendtoks_fromspace\toksvi{#2}
\mixtoks\toksv\toksvi
\tokscclv=\toksv \toksv={}
\def\\##1##2{\def\tempa{##1}\def\tempb{##2}\ifx\tempa\tempb\else
 \toksv\expandafter{\the\toksv\\{##1}{##2}}\fi}
\the\tokscclv
\edef\next{\noexpand\toksencoding{\the\toksencoding\the\toksv}}
\next
}

\catcode`\/=0
\catcode`\\=12/relax

/def/writeencodingreplacements{
%/def/\##1##2{/iwrite{\def\foo{##2} \catcode`\##1=13 \edef##1{\foo}}}
/def/\##1##2{/iwrite{\catcode`\##1=13 \edef##1{\string ##2}}
 /wlog{Replacement: ##1->##2}}
/the/toksencoding
}

/def/writeletters{
/def/\##1{/charreplacement/toksv{##1}
 /iwrite{\catcode`\/the/toksv=11 \lccode`\/the/toksv=`\/the/toksv}
}
/the/toksletters
}
/catcode`/\=0
/catcode`//=12

\def\makeletters{
 \expandafter\catcode\count255=11\relax
 \advance\count255 1\relax
 \ifnum\count255<\@@count
 \expandafter\makeletters
 \fi
}
\def\makeothers{
 \expandafter\catcode\count255=12\relax
 \advance\count255 1\relax
 \ifnum\count255<\@@count
 \expandafter\makeothers
 \fi
}

\def\code{
\edef\code_percent{\the\catcode`\%}
\catcode`\%=14
\catcode`\#=6
\catcode`\^=7
\count255='50  \@@count='60
\makeothers
\catcode`\_=12
\catcode`\~=12
\catcode`\@=12
\catcode`\!=12
\catcode`\$=12
\catcode`\&=12\relax
}
\def\endcode{
\catcode`\#=11
\catcode`\^=11
\count255='50  \@@count='60
\makeletters
\catcode`\_=11
\catcode`\~=11
\catcode`\@=11
\catcode`\!=11
\catcode`\$=11
\catcode`\&=13
\catcode`\%=\code_percent\relax
\lee
}

\let\if@patternscode\iffalse
\def\patternscode{
\begin{code}
\catcode`\$=6
\catcode`\#=12
\catcode`\&=12
\catcode`\,=12
\let\if@patternscode\iftrue
}
\def\endpatternscode{
\catcode`\,=11
\catcode`\$=11
\let\if@patternscode\iffalse
\endcode
}

\def\templatedef{\if@patternscode\else\expandafter\patternscode\fi\let\if@patternscode\iffalse\@templatedef}
\def\@templatedef#1#2{\expandafter\def\csname #1\endcsname{\template{#2}}
       \expandafter\def\csname end#1\endcsname{\end{template}}
       \if@patternscode\else\expandafter\endpatternscode\fi}

\def\mkinput#1{\expandafter\lee\input #1 }      %we are lucky this works
\let\~~endinput\endinput
% ...y la guinda:
\def\mkendinput{\expandafter\lee}       %Expand the end of the file before \lee. It works!
\def\endinput{\expandafter\mkendinput\~~endinput}

%Esto ya es para el fichero que siga
\toksletters={}
\toksencoding={}
\newcount\c_amp

\catcode`\!=11
\catcode`\$=11
\catcode`\&=13

\count255='50  \@@count='60
\makeletters

\catcode`\[=11 \catcode`\]=11
\catcode`\|=11

\count255=129  \@@count=256
\makeletters

\catcode`\^^M=10
\catcode`\^=11
\let\~~lee\lee
\let\lee\relax
\endinput