%D \module
%D   [       file=t-mathlig,
%D        version=2006.12.04,
%D          title=Math \quote{ligature} support,
%D       subtitle=Adapted from \mono{mathlig.tex},
%D         author=Aditya Mahajan,
%D           date=\currentdate,
%D      copyright={Aditya Mahajan}]

%M \usemodule[mathlig]

%D This module is a \CONTEXT ified version of \filename{mathlig.tex} by Jules
%D Bean, which can be downloaded from \hyphenatedurl
%D   {ftp://tug.ctan.org/pub/tex-archive/macros/generic/misc/mathlig.tex}.
%D The documentation and explanation here is copied from
%D \filename{mathlig.tex} (with slight modification)
%D
%D This module allows you to define mathmode ligatures, for example 
%D \startbuffer
%D \catcode`|=\other    % We can only use characters that are not active.
%D \definemathligature  [|-]  {\vdash}
%D \definemathligature  [-|]  {\dashv}
%D \definemathligature  [->]  {\rightarrow}
%D \definemathligature  [<-]  {\leftarrow}
%D \definemathcommand   [n]   {\land}
%D \definemathcommand   [v]   {\lor}
%D \startformula
%D    A \n B, C \v D, E -> F |- C \v D <- A 
%D \stopformula
%D \stopbuffer
%D \typebuffer which give {\getbuffer}
%D and
%D \startbuffer
%D \definemathligature  [*]     {\times}
%D \definemathligature  [(x)]   {\otimes}
%D \definemathligature  [(+)]   {\oplus}
%D \definemathligature  [.]     {\cdot}
%D \startformula
%D  (V * W) (x) (V (+) W) = Q.S
%D \stopformula
%D \stopbuffer
%D \typebuffer which given {\getbuffer}.
%D The \tex{definemathligature} command works even if the math ligatures have
%D common prefix; it takes the longest match and then backtracks. This macro
%D can be used to create ligatures even if the second and subsequent
%D characters have weird catcodes, but I don't recommend it.
%D
%D There are various caveats on the use of \filename{t-mathlig}. It won't work
%D with any active characters in the ligature. Certainly don't put control
%D sequences in there: the ligature should consist of characters of catcodes
%D 11 and 12, although if you are a glutton for weird TeX errors, you can
%D probably get away with catcodes 3,4,5,6,7,8 on non-initial characters. I
%D wouldn't advise it.
%D 
%D \filename{t-mathlig} works by using \type|\ifx| to check the next token, so
%D it doesn't distinguish between explicit and implicit tokens. You can
%D probably fool it quite happily with \type|\let\lessthan<| and such like
%D tricks. Using \type|\bgroup| you may even be able to define ligatures with
%D \type|{| in them.
%D 
%D \filename{t-mathlig} will conflict with any other set of macros which make
%D characters active or math-active, insofar as they affect any characters
%D used as initial characters of the ligatures, i.e.,
%D \type|\definemathligature [->]| makes \type|-| math-active, so it will
%D conflict with anything else making \type|-| math-active, or active. If you
%D previous were using the \type|\mathcode"8000| trick to make characters
%D math-active, then you can simply use one-character \filename{t-mathlig}s
%D and be perfectly compatible.
%D 
%D \filename{t-mathlig} isn't set up to create ligatures with arguments, but
%D if you make a ligature expand into something which is expecting an argument
%D next, that should work fine.  A complete rework to support arguments would
%D be technically feasible, but I'm not sure it would be worthwhile.
%D 
%D Extending the \filename{t-mathlig} trick to make fully active characters,
%D and hence ligatures which work outside of mathmode, is also be possible,
%D but with \ETEX\ it would require quite a bit more work (and an awful lot of
%D the \type|\uppercase| trick to create active and non-active versions of
%D tokens). 
%D 
%D {\bf\sl The next example is the only original contribution of AM}.
%D
%D However in \LUATEX, such tricky parsing can be done in a cleaner
%D way. This is just a feeble attempt to do imitate what Hans showed with
%D \LUATEX:
%D \startbuffer
%D \definemathligature  [sin]    {\sin}
%D \definemathligature  [cos]    {\cos}
%D \definemathligature  [exp]    {e^}
%D \definemathligature  [sqrt]   {\sqrt}
%D
%D % An ugly hack to get things to work: Notice the space
%D \definemathcommand [sin]     [nolop] {\mfunction{s in}}
%D \definemathcommand [cos]     [nolop] {\mfunction{c os}}
%D
%D \startformula
%D  sqrt{sin(x^2) + cos(x^2)}
%D \stopformula
%D \startformula
%D  exp{x} + (exp{x})^2
%D  \stopformula
%D \stopbuffer
%D \typebuffer {\getbuffer}

\unprotect

%D AM: The first two macros should probably go in on the core files.
%D 
%D A macro let or def an \quote{active} version of a token.  Thanks to Donald
%D Arseneau and \filename{groups.google.com}.

\def\actively#1#2%
  {\begingroup\uccode`\~=`#2\relax\uppercase{\endgroup#1~}}

%D A version of \type|\let <normal cs><computed cs>|

\def\letexpandedvalue#1#2{\@EA\let\@EA#1\csname#2\endcsname}

%D Eat the next token, and then pass control to mathlig@next@cmd
\def\gobblemathligature
  {\afterassignment\mathlig@next@cmd\let\mathlig@next=}


%D \macros{definemathligature}
%D
%D The main externally visible macro.  Defines \type|#1| as a 'ligature' to
%D expand to \type|#2| First uses \tex{startcheckmathligature} to make sure
%D that all initial segments of \type|#1| as set up as ligatures.  Then sets
%D the ligature \type|#1| to expand to \type|#2|.

\def\definemathligature
  {\dosingleargument\dodefinemathligature}

\def\dodefinemathligature[#1]#2%
{\startcheckmathligature#1\stopcheckmathligature
   \setvalue{mathlig@back@#1}{#2}}

%D All the \type|check| macros should be idempotent: they set up the
%D definitions only if it hasn't already been done.
%D \startlines
%D Check \type|#1#2| can be a ligature:
%D Check \type|#1| is math-active.
%D If not, save the mathcode, set the macros \type|#1|
%D Now check the suffix tables with \tex{checkrest}
%D \stoplines

\def\startcheckmathligature#1#2\stopcheckmathligature
 {\doifundefined{mathlig@forw@#1}
  {\expandafter\mathchardef\csname mathlig@back@#1\endcsname=\mathcode`#1%
    \mathcode`#1"8000\actively\def#1{\getvalue{mathlig@look@#1}}%
   \dostartmathligature#1\dostopmathligature}
   \startcheckmathligaturesuffix#1#2\stopcheckmathligaturesuffix}

%D Two-part macro.
%D
%D Check suffix tables. If \type|#2| is empty, no suffix!
%D
%D Otherwise, we make sure \type|#2| is a valid suffix for \type|#1|,
%D then recurse for \type|#3| on \type|#1#2|

\def\startcheckmathligaturesuffix#1#2\stopcheckmathligaturesuffix
  {\doifnotempty{#2}
    {\dostartcheckmathligaturesuffix{#1}#2\dostopcheckmathligaturesuffix}}

\def\dostartcheckmathligaturesuffix#1#2#3\dostopcheckmathligaturesuffix%
 {\doifundefined{mathlig@forw@#1#2}
  {\domathligaturesuffix{#1}{#2}}
  \startcheckmathligaturesuffix{#1#2}#3\stopcheckmathligaturesuffix}

%D The do macros should not be called more than once for a given ligature.

%D Add \type|#2| to the list of valid suffixes for \type|#1|
%D Then make the ligature for \type|#1#2| one which only backtracks, for now

\def\domathligaturesuffix#1#2%
  {\appendvalue{mathlig@toks@#1}{#2}%
  \dostartmathligature{#1}{#2}\dostopmathligature}

%D Setup \type|#1#2| so that ligatures beginning \type|#1#2| work.
%D Such ligatures will look at what's coming next (in case
%D of a longer ligature) and, failing that, 
%D backtrack to just \type|#1|

\def\dostartmathligature#1#2\dostopmathligature
%D The look macro just \tex{futurelets} what's coming up and
%D then passes control to \type|forw|
 {\setvalue{mathlig@look@#1#2}%
  {\letexpandedvalue\mathlig@next{mathlig@forw@#1#2}%
   \futurelet\mathlig@next@tok\mathlig@next}%
%D The \type|forw| macro uses \type|\checkmathligatures| to try all possible
%D suffixes, passing control either to one of those, or to the back macro
 \setvalue{mathlig@forw@#1#2}%
 {\letexpandedvalue\mathlig@next{mathlig@back@#1#2}%
  \letexpandedvalue\checkmathligatures{dostartmathligaturecheck#1#2}%
  \letexpandedvalue\mathligtoks{mathlig@toks@#1#2}%
  \expandafter\doifsomething{\mathligtoks}%
  {\expandafter\checkmathligatures\mathligtoks\dostopmathligaturecheck}%
  \mathlig@next}
%D The toks macro just stores the suffixes
 \resetvalue{mathlig@toks@#1#2}%
%D The chk macro goes through the suffixes one by one
%D tail recursing until it runs out, or finds one.
 \setvalue{dostartmathligaturecheck#1#2}##1##2\dostopmathligaturecheck%
 {%\message{Lig so far '#1#2', checking for '##1'}%
  \ifx\mathlig@next@tok##1%
   \letexpandedvalue\mathlig@next@cmd{mathlig@look@#1#2##1}%
   \let\mathlig@next\gobblemathligature
  \fi 
  \doifnotempty{##2}
   {\getvalue{dostartmathligaturecheck#1#2}##2\dostopmathligaturecheck}}
%D The back macro, defined only if this is a ligature of at least
%D two characters, is a default fallback: go back to the previous char.
%D (If this is a ligature of only one character, the mathcode will have 
%D been saved and set as the fallback elsewhere)
 \doifnotempty{#2}
   {\setvalue{mathlig@back@#1#2}{\getvalue{mathlig@back@#1}#2}}}

\protect
