% 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
