/usr/share/texmf-texlive/tex/generic/genmisc/mathlig.tex is in texlive-generic-recommended 2009-15.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | %
% mathlig.tex
%
% (c) 2001 Jules Bean <jules@jellybean.co.uk>
% Permission is granted to freely use, copy, and distribute
% without restriction. Permission is also granted to distribute
% modified versions and incorporate into your own macro packages
% if a brief acknowledgement is given.
%
% Version 1.0 11 May 2001
% Define 'mathmode' ligatures, as in
%
%\mathlig{->}{\rightarrow}
%\mathlig{<-}{\leftarrow}
%\mathlig{<->}{\leftrightarrow}
%
% Works even if they have common prefixes (takes the longest match,
% then backtracks).
%
% Can be used to create ligatures even if the second
% and subsequent characters have weird catcodes, but I don't recommend
% it.
\count255\catcode`@
\catcode`@=11
\chardef\mathlig@atcode\count255
% Let or def an 'active' version of a token. Thanks to Donald
% Arseneau and groups.google.com
\def\actively#1#2{\begingroup\uccode`\~=`#2\relax\uppercase{\endgroup#1~}}
% Eat the next token, and then pass control to mathlig@next@cmd
\def\mathlig@gobble{\afterassignment\mathlig@next@cmd\let\mathlig@next= }
% Used to delimit delimited arguments, and ifx tests for emptyness.
\def\mathlig@delim{\mathlig@delim}
% Some macros to help dealing with 'computed names' (csnames).
% Just like def, but first parameter is evaluated as a csname
\def\mathlig@defcs#1{\expandafter\def\csname#1\endcsname}
% A version of \let <normal cs><computed cs>
\def\mathlig@let@cs#1#2{\expandafter\let\expandafter#1\csname#2\endcsname}
% Maintain a 'list' of tokens as a macro which expands to them
\def\mathlig@appendcs#1#2{\expandafter\edef\csname#1\endcsname{\csname#1\endcsname#2}}
% The main externally visible macro.
% Defines '#1' as a 'ligature' to expand to #2
% First uses \mathlig@checklig to make sure that all initial segments of
% #1 as set up as ligatures.
% Then sets the ligature #1 to expand to #2.
\def\mathlig#1#2{\mathlig@checklig#1\mathlig@end\mathlig@defcs{mathlig@back@#1}{#2}\ignorespaces}
% All the @check macros should be idempotent: they set up the definitions
% only if it hasn't already been done.
%Check #1#2 can be a ligature:
% Check #1 is math-active.
% If not, save the mathcode, set the macros #1
%Now check the suffix tables with \checkrest
\def\mathlig@checklig#1#2\mathlig@end{%
\expandafter\ifx\csname mathlig@forw@#1\endcsname\relax
\expandafter\mathchardef\csname mathlig@back@#1\endcsname=\mathcode`#1%
\mathcode`#1"8000\actively\def#1{\csname mathlig@look@#1\endcsname}%
\mathlig@dolig#1\mathlig@delim
\fi
\mathlig@checksuffix#1#2\mathlig@end
}
%Two-part macro.
%Check suffix tables. If #2 is empty, no suffix!
%Otherwise, we make sure #2 is a valid suffix for #1,
%then recurse for #3 on #1#2
\def\mathlig@checksuffix#1#2\mathlig@end{%
\ifx\mathlig@delim#2\mathlig@delim\relax\else\mathlig@checksuffix@{#1}#2\mathlig@end\fi
}
\def\mathlig@checksuffix@#1#2#3\mathlig@end{%
\expandafter\ifx\csname mathlig@forw@#1#2\endcsname\relax\mathlig@dosuffix{#1}{#2}\fi
\mathlig@checksuffix{#1#2}#3\mathlig@end
}
% The do macros should not be called more than once for a given ligature.
% Add #2 to the list of valid suffixes for #1
% Then make the ligature for #1#2 one which only backtracks, for now
\def\mathlig@dosuffix#1#2{%
\mathlig@appendcs{mathlig@toks@#1}{#2}%
\mathlig@dolig{#1}{#2}\mathlig@delim
}
% Setup #1#2 so that ligatures beginning #1#2 work.
% Such ligatures will look at what's coming next (in case
% of a longer ligature) and, failing that,
% backtrack to just #1
\def\mathlig@dolig#1#2\mathlig@delim{%
%The look macro just \futurelets what's coming up and
%then passes control to forw
\mathlig@defcs{mathlig@look@#1#2}{%
\mathlig@let@cs\mathlig@next{mathlig@forw@#1#2}\futurelet\mathlig@next@tok\mathlig@next}%
%The forw macro uses chck to try all possible suffixes, passing control
%either to one of those, or to the back macro
\mathlig@defcs{mathlig@forw@#1#2}{%
\mathlig@let@cs\mathlig@next{mathlig@back@#1#2}%
\mathlig@let@cs\checker{mathlig@chck@#1#2}%
\mathlig@let@cs\mathligtoks{mathlig@toks@#1#2}%
\expandafter\ifx\expandafter\mathlig@delim\mathligtoks\mathlig@delim\relax\else
\expandafter\checker\mathligtoks\mathlig@delim\fi
\mathlig@next
}%
%The toks macro just stores the suffixes
\mathlig@defcs{mathlig@toks@#1#2}{}%
%The chk macro goes through the suffixes one by one
%tail recursing until it runs out, or finds one.
\mathlig@defcs{mathlig@chck@#1#2}##1##2\mathlig@delim{%
%\message{Lig so far '#1#2', checking for '##1'}%
\ifx\mathlig@next@tok##1%
\mathlig@let@cs\mathlig@next@cmd{mathlig@look@#1#2##1}\let\mathlig@next\mathlig@gobble
\fi
\ifx\mathlig@delim##2\mathlig@delim\relax\else
\csname mathlig@chck@#1#2\endcsname##2\mathlig@delim
\fi
}%
%
% The back macro, defined only if this is a ligature of at least
% two characters, is a default fallback: go back to the previous char.
% (If this is a ligature of only one character, the mathcode will have
% been saved and set as the fallback elsewhere)
\ifx\mathlig@delim#2\mathlig@delim\else
\mathlig@defcs{mathlig@back@#1#2}{\csname mathlig@back@#1\endcsname #2}%
\fi
}%
\catcode`@\mathlig@atcode
|