% Copyright © 2000 Patryk Zadarnowski «pat@jantar.org»
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
% (1) Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer. (2) Redistributions
% in binary form must reproduce the above copyright notice, this list of
% conditions and the following disclaimer in the documentation and/or other
% materials provided with the distribution. (3) The name of any author may
% not be used to endorse or promote products derived from this software
% without their specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
% INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
% FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL THE
% AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
% OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.
%% lambdaTeX v1.0.5 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Limitations:
%
% - no support for nested comments
% - no support for LaTeX mode
% - no support for non-literate mode
% - no support for strings in inline mode
% - function names must be marked as such explicitely
% - < > as the first character in math mode don't work.
% - code lines don't wrap well.
%
% Quirks:
%
% 1. HaskellTeX reserves <, > and " as active characters, but, of
% course restores their meaning of < and > in math mode. However,
% this doesn't work as well as expected. When TeX sees the $
% character, it reads the following character to see if it is
% another $ beginning a math display. If that character is active,
% it attempts to expand it (a bug in TeX?! or just a mis-feature?
% I couldn't find anything in the TeXbook.) So, you must write
% $ >$ rather than $>$. Oh well. To make amends for this, I define
% \lt and \gt math macros to complement \le and \ge already in
% plain TeX, as $\gt$ looks better than $ >$. Fortunately, one rarely
% needs to write a relational operator as the first character in
% a formula, and, of course, $a>b$ works as expected.
%
% 2. When parsing comments, the lexical analyzer temporarily switches
% out of Haskell mode, so normal fonts, etc can take effect.
% Specifically, it switches out of TeX mode after processing the
% initial <dashes> token of a comment. This means that it must
% process the token immediately following the dashes, too, before
% leaving Haskell mode. Therefore, if this token is an active
% character, it will not work as expected (its category code will
% be 12.) Again, this normally is not a problem as the character
% immediately following the -- should be a space, anyway.
\catcode`@=11
\newskip\hsparskip \hsparskip=8pt
\newdimen\hsleftskip \hsleftskip=30pt
\newdimen\hsrightskip \hsrightskip=10pt
\newdimen\hscommentskip \hscommentskip=1em
\newdimen\hswordspace \hswordspace=.3em
\newdimen\hsspacewidth \hsspacewidth=1em
\newdimen\hstabwidth \hstabwidth=8em
\def\everyhs{}
\def\beforehs{\vskip 14pt plus3pt minus1pt}
\def\afterhs{\vskip 14pt plus3pt minus1pt}
\font\hs@keyface=phvb at 9pt
\font\hs@funface=phvr at 9pt
\font\hs@sfunface=phvr at 7pt % (added by florian)
\font\hs@varface=phvro at 9pt
\font\hs@conface=phvrc at 9pt
\font\hs@numface=phvr at 9pt
\font\hs@strface=pcrr at 9pt
\font\hs@symface=phvr at 9pt
\font\hs@ssymface=phvr at 7pt
\font\hs@sssymface=phvr at 5.8pt
\hyphenchar\hs@keyface=-1
\hyphenchar\hs@funface=-1
\hyphenchar\hs@varface=-1
\hyphenchar\hs@conface=-1
\hyphenchar\hs@symface=-1
\hyphenchar\hs@numface=-1
\hyphenchar\hs@strface=-1
\hyphenchar\hs@ssymface=-1
\hyphenchar\hs@sssymface=-1
%%% Lexical modes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The lexical analyzer can operate in one of three modes:
%
% 0. Inline - Haskell code appearing within a paragraph
% 1. Bird - Bird-style literate Haskell code
%
% The Inline mode is used to typeset a short fragment of Haskell code
% in the middle of a paragraph, for example when referring to a variable
% defined within the program. The mode is entered by the " character.
% The lexical analyzer exits when it encounters another " character.
% Newlines are treated as simple whitespace, and comments are illegal.
% Because the " character is reserved, strings cannot appear in the Inline
% mode.
%
% The Bird mode is used to process Bird-style literate scripts. The mode
% is entered by the > character (note that this is a hack - in Haskell, >
% designates literate code only when it appears as the first character on
% a line.) The mode exits when it encounters a blank line. The text is typeset
% as a separate paragraph, idented by \hsleftskip on the left and \hsrightskip
% on the right. The \beforehs macro is inserted before the fragment of code
% and \afterhs is inserted after it. The > character itself is not displayed.
% In both modes, the \everyhs macro is inserted immediately after entering
% the Haskell mode.
%
% One thing worth noting is that, because spaces are skipped following active
% characters, in the Inline mode any spaces immediately following the operning
% " are ignored. For consistency, we also ignore any spaces preceeding the
% closing ". In Bird mode, TeX swallows spaces following the opening >, so
% the lexical analyzer _assumes_ that the > was followed by a single space,
% and strips one space-worth of indentation from all remaining lines in the
% code fragment.
\newif\ifhs@inline
% The \lambdaTeX macro:
\def\lambdaTeX{$\lambda$\kern-1.5pt\TeX}
% The amount to kern the current token by:
\newdimen\hs@space
\newdimen\hs@guardpos
\newdimen\hs@previndent
\newdimen\hs@indent
% The boxes used to build up the current line:
\newbox\voidb@x % permanently void
\newbox\hs@i
\newbox\hs@ii
\newbox\hs@iii
% Macros for requesting special formatting of a specific lexeme:
\def\typeset#1#2{\expandafter\def\csname<#1>\endcsname{#2}}
% Define the Haskell keywords:
\typeset{case}{{\hs@keyface case}}
\typeset{class}{{\hs@keyface class}}
\typeset{data}{{\hs@keyface data}}
\typeset{default}{{\hs@keyface default}}
\typeset{deriving}{{\hs@keyface deriving}}
\typeset{do}{{\hs@keyface do}}
\typeset{else}{{\hs@keyface else}}
%\typeset{if}{{\hs@keyface if}}
\typeset{import}{{\hs@keyface import}}
\typeset{in}{$\in$}
\typeset{infix}{{\hs@keyface infix}}
\typeset{infixl}{{\hs@keyface infixl}}
\typeset{infixr}{{\hs@keyface infixr}}
\typeset{instance}{{\hs@keyface instance}}
\typeset{let}{{\hs@keyface let}}
\typeset{module}{{\hs@keyface module}}
\typeset{newtype}{{\hs@keyface newtype}}
\typeset{of}{{\hs@keyface of}}
\typeset{then}{{\hs@keyface then}}
\typeset{type}{{\hs@keyface type}}
\typeset{where}{{\hs@keyface where}}
\typeset{as}{{\hs@keyface as}}
\typeset{qualified}{{\hs@keyface qualified}}
\typeset{hiding}{{\hs@keyface hiding}}
\typeset{otherwise}{{\hs@keyface otherwise}}
\typeset{blw}{$\sqsubseteq$}
\typeset{abv}{$\sqsupseteq$}
\newlength{\spacewidth} % (added by florian).
\settowidth{\spacewidth}{ } % (added by florian).
\typeset{invfun}{$\hspace{-\spacewidth}^{-1}$} % (added by florian).
\typeset{relseqeq}{$\rightarrow^{\text{{\hs@sfunface seq}},=}$} % (added by florian).
\typeset{relseqineq}{$\rightarrow^{\text{{\hs@sfunface seq}},\sqsubseteq}$} % (added by florian).
\typeset{lift}{{\hs@conface lift}} % (added by florian).
%\typeset{xii}{\edef\hs@sub{j}\edef\hs@tok{x}\hs@emitvar}
% Define Greek letters:
\typeset{alpha}{$\alpha^{\hs@sup}_{\hs@sub}$}
\typeset{beta}{$\beta^{\hs@sup}_{\hs@sub}$}
\typeset{gamma}{$\gamma^{\hs@sup}_{\hs@sub}$}
\typeset{delta}{$\delta^{\hs@sup}_{\hs@sub}$}
\typeset{epsilon}{$\epsilon^{\hs@sup}_{\hs@sub}$}
\typeset{zeta}{$\zeta^{\hs@sup}_{\hs@sub}$}
\typeset{eta}{$\eta^{\hs@sup}_{\hs@sub}$}
\typeset{theta}{$\theta^{\hs@sup}_{\hs@sub}$}
\typeset{iota}{$\iota^{\hs@sup}_{\hs@sub}$}
\typeset{kappa}{$\kappa^{\hs@sup}_{\hs@sub}$}
\typeset{lambda}{$\lambda^{\hs@sup}_{\hs@sub}$}
\typeset{mu}{$\mu^{\hs@sup}_{\hs@sub}$}
\typeset{nu}{$\nu^{\hs@sup}_{\hs@sub}$}
\typeset{xi}{$\xi^{\hs@sup}_{\hs@sub}$}
\typeset{pi}{$\pi^{\hs@sup}_{\hs@sub}$}
\typeset{rho}{$\rho^{\hs@sup}_{\hs@sub}$}
\typeset{sigma}{$\sigma^{\hs@sup}_{\hs@sub}$}
\typeset{tau}{$\tau^{\hs@sup}_{\hs@sub}$}
\typeset{upsilon}{$\upsilon^{\hs@sup}_{\hs@sub}$}
\typeset{phi}{$\phi^{\hs@sup}_{\hs@sub}$}
\typeset{chi}{$\chi^{\hs@sup}_{\hs@sub}$}
\typeset{psi}{$\psi^{\hs@sup}_{\hs@sub}$}
\typeset{omega}{$\omega^{\hs@sup}_{\hs@sub}$}
\typeset{Alpha}{$\mit A^{\hs@sup}_{\hs@sub}$}
\typeset{Beta}{$\mit B^{\hs@sup}_{\hs@sub}$}
\typeset{Gamma}{$\mit\Gamma^{\hs@sup}_{\hs@sub}$}
\typeset{Delta}{$\mit\Delta^{\hs@sup}_{\hs@sub}$}
\typeset{Epsilon}{$\mit E^{\hs@sup}_{\hs@sub}$}
\typeset{Zeta}{$\mit Z^{\hs@sup}_{\hs@sub}$}
\typeset{Eta}{$\mit H^{\hs@sup}_{\hs@sub}$}
\typeset{Theta}{$\mit\Theta^{\hs@sup}_{\hs@sub}$}
\typeset{Iota}{$\mit I^{\hs@sup}_{\hs@sub}$}
\typeset{Kappa}{$\mit K^{\hs@sup}_{\hs@sub}$}
\typeset{Lambda}{$\mit\Lambda^{\hs@sup}_{\hs@sub}$}
\typeset{Mu}{$\mit M^{\hs@sup}_{\hs@sub}$}
\typeset{Nu}{$\mit N^{\hs@sup}_{\hs@sub}$}
\typeset{Xi}{$\mit\Xi^{\hs@sup}_{\hs@sub}$}
\typeset{Pi}{$\mit\Pi^{\hs@sup}_{\hs@sub}$}
\typeset{Rho}{$\mit P^{\hs@sup}_{\hs@sub}$}
\typeset{Sigma}{$\mit\Sigma^{\hs@sup}_{\hs@sub}$}
\typeset{Tau}{$\mit T^{\hs@sup}_{\hs@sub}$}
\typeset{Upsilon}{$\mit\Upsilon^{\hs@sup}_{\hs@sub}$}
\typeset{Phi}{$\mit\Phi^{\hs@sup}_{\hs@sub}$}
\typeset{Chi}{$\mit X^{\hs@sup}_{\hs@sub}$}
\typeset{Psi}{$\mit\Psi^{\hs@sup}_{\hs@sub}$}
\typeset{Omega}{$\mit\Omega^{\hs@sup}_{\hs@sub}$}
\typeset{ALPHA}{$\rm A^{\hs@sup}_{\hs@sub}$}
\typeset{BETA}{$\rm B^{\hs@sup}_{\hs@sub}$}
\typeset{GAMMA}{$\Gamma^{\hs@sup}_{\hs@sub}$}
\typeset{DELTA}{$\Delta^{\hs@sup}_{\hs@sub}$}
\typeset{EPSILON}{$\rm E^{\hs@sup}_{\hs@sub}$}
\typeset{ZETA}{$\rm Z^{\hs@sup}_{\hs@sub}$}
\typeset{ETA}{$\rm H^{\hs@sup}_{\hs@sub}$}
\typeset{THETA}{$\Theta^{\hs@sup}_{\hs@sub}$}
\typeset{IOTA}{$\rm I^{\hs@sup}_{\hs@sub}$}
\typeset{KAPPA}{$\rm K^{\hs@sup}_{\hs@sub}$}
\typeset{LAMBDA}{$\Lambda^{\hs@sup}_{\hs@sub}$}
\typeset{MU}{$\rm M^{\hs@sup}_{\hs@sub}$}
\typeset{NU}{$\rm N^{\hs@sup}_{\hs@sub}$}
\typeset{XI}{$\Xi^{\hs@sup}_{\hs@sub}$}
\typeset{PI}{$\Pi^{\hs@sup}_{\hs@sub}$}
\typeset{RHO}{$\rm P^{\hs@sup}_{\hs@sub}$}
\typeset{SIGMA}{$\Sigma^{\hs@sup}_{\hs@sub}$}
\typeset{TAU}{$\rm T^{\hs@sup}_{\hs@sub}$}
\typeset{UPSILON}{$\Upsilon^{\hs@sup}_{\hs@sub}$}
\typeset{PHI}{$\Phi^{\hs@sup}_{\hs@sub}$}
\typeset{CHI}{$\rm X^{\hs@sup}_{\hs@sub}$}
\typeset{PSI}{$\Psi^{\hs@sup}_{\hs@sub}$}
\typeset{OMEGA}{$\Omega^{\hs@sup}_{\hs@sub}$}
% Other math letters:
\typeset{aleph}{$\aleph$}
\typeset{infinity}{$\infty$}
\typeset{nabla}{$\nabla$}
\typeset{any}{$\exists$}
\typeset{all}{$\forall$}
\typeset{sum}{$\sum$}
\typeset{product}{$\prod$}
%\typeset{and}{$\bigwedge$}
\typeset{or}{$\bigvee$}
\typeset{undefined}{$\bot$}
\typeset{forall}{$\forall$}
\typeset{cup}{$\cup$}
\typeset{bigsqcup}{$\bigsqcup$}
% Define common symbols:
\typeset{=}{{\hs@symface=}}
\typeset{<-}{$\leftarrow$}
\typeset{->}{$\rightarrow$}
\typeset{=>}{$\Rightarrow$}
\typeset{++}{$+\kern-5pt+$}
\typeset{==}{$=$}
\typeset{/=}{${\mit/}\kern-.65em=$}
\typeset{<=}{$\leq$}
\typeset{>=}{$\geq$}
\typeset{||}{$\vee$}
\typeset{&&}{$\wedge$}
\typeset{==>}{$\Rightarrow$}
\typeset{<=>}{$\Leftrightarrow$}
% Symbols with a backslash are a little tricky:
{\catcode`/=0\catcode92=12
/expandafter/xdef/csname<\>/endcsname{$/lambda$}}
% Define a space letter (used in a few places)
{\catcode32=12\gdef\hs@{ }}
% Prepare the character codes, etc for use in haskell mode:
\def\hs@preparecodemode{%
\textfont15=\hs@symface
\scriptfont15=\hs@ssymface
\scriptscriptfont15=\hs@sssymface
% Category codes:
\chardef\hs@catcodeIX=\catcode9 \catcode9=12
\chardef\hs@catcodeXIII=\catcode13 \catcode13=12
\chardef\hs@catcodeXXXII=\catcode32 \catcode32=12
\chardef\hs@catcodeXXXIII=\catcode33 \catcode33=12
\chardef\hs@catcodeXXXIV=\catcode34 \catcode34=12
\chardef\hs@catcodeXXXV=\catcode35 \catcode35=12
\chardef\hs@catcodeXXXVI=\catcode36 \catcode36=12
\chardef\hs@catcodeXXXVII=\catcode37 \catcode37=12
\chardef\hs@catcodeXXXVIII=\catcode38 \catcode38=12
\chardef\hs@catcodeXXXIX=\catcode39 \catcode39=12
\chardef\hs@catcodeXL=\catcode40 \catcode40=12
\chardef\hs@catcodeXLI=\catcode41 \catcode41=12
\chardef\hs@catcodeXLII=\catcode42 \catcode42=12
\chardef\hs@catcodeXLIII=\catcode43 \catcode43=12
\chardef\hs@catcodeXLIV=\catcode44 \catcode44=12
\chardef\hs@catcodeXLV=\catcode45 \catcode45=12
\chardef\hs@catcodeXLVI=\catcode46 \catcode46=12
\chardef\hs@catcodeXLVII=\catcode47 \catcode47=12
\chardef\hs@catcodeLVIII=\catcode58 \catcode58=12
\chardef\hs@catcodeLIX=\catcode59 \catcode59=12
\chardef\hs@catcodeLX=\catcode60 \catcode60=12
\chardef\hs@catcodeLXI=\catcode61 \catcode61=12
\chardef\hs@catcodeLXII=\catcode62 \catcode62=12
\chardef\hs@catcodeLXIII=\catcode63 \catcode63=12
\chardef\hs@catcodeLXIV=\catcode64 \catcode64=12
\chardef\hs@catcodeXCI=\catcode91 \catcode91=12
\chardef\hs@catcodeXCII=\catcode92 \catcode92=12
\chardef\hs@catcodeXCIII=\catcode93 \catcode93=12
\chardef\hs@catcodeXCIV=\catcode94 \catcode94=12
\chardef\hs@catcodeXCV=\catcode95 \catcode95=12
\chardef\hs@catcodeXCVI=\catcode96 \catcode96=12
\chardef\hs@catcodeCXXIII=\catcode123 \catcode123=12
\chardef\hs@catcodeCXXIV=\catcode124 \catcode124=12
\chardef\hs@catcodeCXXV=\catcode125 \catcode125=12
\chardef\hs@catcodeCXXVI=\catcode126 \catcode126=12
% Math codes for Haskell symbols:
\mathchardef\hs@mathcodeXXXIII=\mathcode33 \mathcode33="0F21 % !
\mathchardef\hs@mathcodeXXXV=\mathcode35 \mathcode35="0F23 % #
\mathchardef\hs@mathcodeXXXVI=\mathcode36 \mathcode36="0F24 % $
\mathchardef\hs@mathcodeXXXVII=\mathcode37 \mathcode37="0F25 % %
\mathchardef\hs@mathcodeXXXVIII=\mathcode38 \mathcode38="0F26 % &
\mathchardef\hs@mathcodeXL=\mathcode40 \mathcode41="0028 % (
\mathchardef\hs@mathcodeXLI=\mathcode41 \mathcode41="0029 % )
\mathchardef\hs@mathcodeXLII=\mathcode42 \mathcode42="0203 % *
\mathchardef\hs@mathcodeXLIII=\mathcode43 \mathcode43="002B % +
\mathchardef\hs@mathcodeXLIV=\mathcode44 \mathcode44="0F2C % ,
\mathchardef\hs@mathcodeXLV=\mathcode45 \mathcode45="0200 % -
\mathchardef\hs@mathcodeXLVI=\mathcode46 \mathcode46="0F2E % .
\mathchardef\hs@mathcodeXLVII=\mathcode47 \mathcode47="002F % /
\mathchardef\hs@mathcodeLVIII=\mathcode58 \mathcode58="003A % :
\mathchardef\hs@mathcodeLVIX=\mathcode59 \mathcode59="0F3B % ;
\mathchardef\hs@mathcodeLX=\mathcode60 \mathcode60="013C % <
\mathchardef\hs@mathcodeLXI=\mathcode61 \mathcode61="003D % =
\mathchardef\hs@mathcodeLXII=\mathcode62 \mathcode62="013E % >
\mathchardef\hs@mathcodeLXIII=\mathcode63 \mathcode63="0F3F % ?
\mathchardef\hs@mathcodeLXIV=\mathcode64 \mathcode64="0F40 % @
\mathchardef\hs@mathcodeXCI=\mathcode91 \mathcode91="005B % [
\mathchardef\hs@mathcodeXCII=\mathcode92 \mathcode92="026E % \
\mathchardef\hs@mathcodeXCIII=\mathcode93 \mathcode93="005D % ]
\mathchardef\hs@mathcodeXCVI=\mathcode96 \mathcode96="0012 % `
\mathchardef\hs@mathcodeCXXIII=\mathcode123 \mathcode123="0266 % {
\mathchardef\hs@mathcodeCXXIV=\mathcode124 \mathcode124="007C % |
\mathchardef\hs@mathcodeCXXV=\mathcode125 \mathcode125="0267 % {
\mathchardef\hs@mathcodeCXXVI=\mathcode126 \mathcode126="0F7E % ~
\relax}
% Restore "normal" TeX environment within haskell comments:
\def\hs@preparecommentmode{%
% Category codes:
\catcode9=\hs@catcodeIX
\catcode13=\hs@catcodeXIII
\catcode32=\hs@catcodeXXXII
\catcode33=\hs@catcodeXXXIII
\catcode34=\hs@catcodeXXXIV
\catcode35=\hs@catcodeXXXV
\catcode36=\hs@catcodeXXXVI
\catcode37=\hs@catcodeXXXVII
\catcode38=\hs@catcodeXXXVIII
\catcode39=\hs@catcodeXXXIX
\catcode40=\hs@catcodeXL
\catcode41=\hs@catcodeXLI
\catcode42=\hs@catcodeXLII
\catcode43=\hs@catcodeXLIII
\catcode44=\hs@catcodeXLIV
\catcode45=\hs@catcodeXLV
\catcode46=\hs@catcodeXLVI
\catcode47=\hs@catcodeXLVII
\catcode58=\hs@catcodeLVIII
\catcode59=\hs@catcodeLIX
\catcode60=\hs@catcodeLX
\catcode61=\hs@catcodeLXI
\catcode62=\hs@catcodeLXII
\catcode63=\hs@catcodeLXIII
\catcode64=\hs@catcodeLXIV
\catcode91=\hs@catcodeXCI
\catcode92=\hs@catcodeXCII
\catcode93=\hs@catcodeXCIII
\catcode94=\hs@catcodeXCIV
\catcode95=\hs@catcodeXCV
\catcode96=\hs@catcodeXCVI
\catcode123=\hs@catcodeCXXIII
\catcode124=\hs@catcodeCXXIV
\catcode125=\hs@catcodeCXXV
\catcode126=\hs@catcodeCXXVI
% Math codes for Haskell symbols:
\mathcode33=\hs@mathcodeXXXIII % !
\mathcode35=\hs@mathcodeXXXV % #
\mathcode36=\hs@mathcodeXXXVI % $
\mathcode37=\hs@mathcodeXXXVII % %
\mathcode38=\hs@mathcodeXXXVIII % &
\mathcode40=\hs@mathcodeXL % (
\mathcode41=\hs@mathcodeXLI % )
\mathcode42=\hs@mathcodeXLII % *
\mathcode43=\hs@mathcodeXLIII % +
\mathcode44=\hs@mathcodeXLIV % ,
\mathcode45=\hs@mathcodeXLV % -
\mathcode46=\hs@mathcodeXLVI % .
\mathcode47=\hs@mathcodeXLVII % /
\mathcode58=\hs@mathcodeLVIII % :
\mathcode59=\hs@mathcodeLVIX % ;
\mathcode60=\hs@mathcodeLX % <
\mathcode61=\hs@mathcodeLXI % =
\mathcode62=\hs@mathcodeLXII % >
\mathcode63=\hs@mathcodeLXIII % ?
\mathcode64=\hs@mathcodeLXIV % @
\mathcode91=\hs@mathcodeXCI % [
\mathcode92=\hs@mathcodeXCII % \
\mathcode93=\hs@mathcodeXCIII % ]
\mathcode96=\hs@mathcodeXCVI % `
\mathcode123=\hs@mathcodeCXXIII % {
\mathcode124=\hs@mathcodeCXXIV % |
\mathcode125=\hs@mathcodeCXXV % {
\mathcode126=\hs@mathcodeCXXVI % ~
\relax}
% Entry points for each of the three modes:
\def\hs@preparehaskell{%
% Initial token "registers":
\xdef\hs@tok{}\edef\hs@sup{}\edef\hs@sub{}\hs@space=0pt
\hs@preparecodemode}
\def\hs@beginInline{%
\begingroup
\hs@inlinetrue
\everyhs
\hs@preparehaskell\hs@lex@state}
\def\hs@endInline{%
\endgroup}
\def\hs@beginBird{%
\beforehs
\begingroup
\hs@inlinefalse
\everyhs
\offinterlineskip
\def\hs@parskip{}%
\hs@preparehaskell
\hs@previndent=0pt
\hs@indent=\hsleftskip
\hs@code@state}
% Entry point for the italic mode:
{\catcode`>=\active
\gdef\hs@beginitalic{\begingroup\it\catcode`>=\active\let>=\endgroup}}
% Lexeme formatting macros:
\def\hs@emitvar{%
\if\csname<\hs@tok>\endcsname\relax
\setbox255=\hbox{\hs@varface\hs@tok\/$^{\hs@sup}_{\hs@sub}$}%
\else
\setbox255=\hbox{\csname<\hs@tok>\endcsname}%
\fi
\hs@emit}
\def\hs@emitcon{%
\if\csname<\hs@tok>\endcsname\relax
\setbox255=\hbox{\hs@conface\hs@tok$^{\hs@sup}_{\hs@sub}$}%
\else
\setbox255=\hbox{\csname<\hs@tok>\endcsname}%
\fi
\hs@emit}
\def\hs@emitsym{%
\def\hs@guard{|}%
\ifx\hs@tok\hs@guard
\ifhs@inline
\kern\hs@space\hbox{$|$}%
\else
\ifhbox\hs@i
% Set the new guard position:
\hs@guardpos=\hs@indent
\advance\hs@guardpos by \wd\hs@i
\advance\hs@guardpos by \hs@space
\else
% Align the guard with the previous one:
\ifdim\hs@guardpos>0pt\hs@indent=\hs@guardpos\fi
\fi
\global\setbox\hs@i=\hbox{%
\ifhbox\hs@i\unhbox\hs@i\fi\kern\hs@space\vrule width.17pt\ }%
\hs@afteremit
\fi
\else
\if\csname<\hs@tok>\endcsname\relax
\setbox255=\hbox{$\hs@tok$}%
\else
\setbox255=\hbox{\csname<\hs@tok>\endcsname}%
\fi
\hs@emit
\fi}
\def\hs@emitnum#1{%
\if\csname<#1\hs@tok>\endcsname\relax
\setbox255=\hbox{\hs@numface\hs@tok$_{\hs@sub}$}%
\else
\setbox255=\hbox{\csname<#1\hs@tok>\endcsname}%
\fi
\hs@emit}
\def\hs@emitchr{%
\if\csname<\hs@tok>\endcsname\relax
\setbox255=\hbox{\hs@symface`{\hs@strface\hs@tok}'}%
\else
\setbox255=\hbox{\csname<\hs@tok>\endcsname}%
\fi
\hs@emit}
\def\hs@emit{%
\ifhs@inline
\kern\hs@space\box255
\else
\global\setbox\hs@i=\hbox{\ifhbox\hs@i\unhbox\hs@i\fi\kern\hs@space\box255}%
\fi
\hs@afteremit}
\def\hs@afteremit{%
\xdef\hs@tok{}\edef\hs@sup{}\edef\hs@sub{}\hs@space=0pt}
\def\hs@outputline{%
\ifhbox\hs@i
% Emit the previous line:
\dimen255=\hsize
\advance\dimen255 by -\hsrightskip
\ifdim\wd\hs@i>\dimen255
\dimen255=-\dimen255 \advance\dimen255 by \wd\hs@i
\count255=\inputlineno \advance\count255 by -1
\immediate\write16{}%
\immediate\write16{%
Overful \hbox (\the\dimen255\hs@ too wide)
in Haskell code at line \the\count255}%
\global\setbox\hs@i=\hbox{\unhbox\hs@i\vrule width\overfullrule}%
\fi
\hs@parskip
\hbox{\strut\kern\hs@indent\unhbox\hs@i}%
% Reset the guard position if necessary:
\ifdim\hs@indent>\hs@previndent\else
\hs@guardpos=0pt
\fi
% Update indentation levels:
\hs@previndent=\hs@indent
\hs@indent=\hsleftskip
\fi}
% Entry point for the comment mode:
\def\hs@emitdashes{%
\setbox255=\hbox{\hskip\hscommentskip\hs@symface---\hs@tok}\hs@emit}
\def\hs@preparecomment{%
\hs@emitdashes
\begingroup
\hs@preparecommentmode
\catcode13=12
\relax}
{\catcode13=12\gdef\hs@comment@state#1^^M{\hs@emitcomment{#1}}}
\def\hs@emitcomment#1{%
\endgroup
\ifhs@inline
\errmessage{Comment in inline Haskell mode}%
\else
\setbox255=\hbox{#1\hfill}\hs@emit
\let\next=\hs@newline@state
\fi
\next}
% \endgroup
% \begingroup
% \hs@inlinefalse
% \everyhs
% \offinterlineskip
% \def\hs@parskip{}%
% \hs@preparehaskell
% \hs@previndent=0pt
% \hs@indent=\hsleftskip
% \hs@newline@state}
%%% Function detection %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Haskell syntax does not distinguish between functions and variables, but
% we would like to typeset each kind of names differently. Therefore, I
% define a convinient \functions macro which accepts a comma-separated list
% of function names. To change a function back into a variable, prefix its
% name in the list with the ! character.
\def\functions(#1){\def\hs@tok{}\hs@funbegin#1\relax}
\def\hs@funbegin#1{%
\ifx#1\relax
\let\next=\relax
\else\ifx#1,
\let\next=\hs@funbegin
\else\ifnum`#1=9
\let\next=\hs@funbegin
\else\ifnum`#1=32
\let\next=\hs@funbegin
\else\if#1!
\xdef\hs@tok{}%
\let\next=\hs@varcollect
\else
\xdef\hs@tok{#1}%
\let\next=\hs@funcollect
\fi\fi\fi\fi\fi
\next}
\def\hs@funcollect#1{%
\ifx#1\relax
\typeset{\hs@tok}{{\hs@funface\hs@tok$^{\hs@sup}_{\hs@sub}$}}%
\let\next=\relax
\else\ifx#1,
\typeset{\hs@tok}{{\hs@funface\hs@tok$^{\hs@sup}_{\hs@sub}$}}%
\let\next=\hs@funbegin
\else\ifnum`#1=9
\typeset{\hs@tok}{{\hs@funface\hs@tok$^{\hs@sup}_{\hs@sub}$}}%
\let\next=\hs@funbegin
\else\ifnum`#1=32
\typeset{\hs@tok}{{\hs@funface\hs@tok$^{\hs@sup}_{\hs@sub}$}}%
\let\next=\hs@funbegin
\else
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@funcollect
\fi\fi\fi\fi
\next}
\def\hs@varcollect#1{%
\ifx#1\relax
\typeset{\hs@tok}{{\hs@varface\hs@tok$^{\hs@sup}_{\hs@sub}$}}%
\let\next=\relax
\else\ifx#1,
\typeset{\hs@tok}{{\hs@varface\hs@tok$^{\hs@sup}_{\hs@sub}$}}%
\let\next=\hs@funbegin
\else\ifnum`#1=9
\typeset{\hs@tok}{{\hs@varface\hs@tok$^{\hs@sup}_{\hs@sub}$}}%
\let\next=\hs@funbegin
\else\ifnum`#1=32
\typeset{\hs@tok}{{\hs@varface\hs@tok$^{\hs@sup}_{\hs@sub}$}}%
\let\next=\hs@funbegin
\else
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@varcollect
\fi\fi\fi\fi
\next}
% Define standard prelude functions:
% Prelude:
\functions (succ,pred,toEnum,fromEnum,enumFrom,enumFromThen,enumFromTo,
enumFromThenTo,minBound,maxBound,negate,abs,signum,fromInteger,toRational,
quot,rem,div,mod,quotRem,divMod,toInteger,recip,fromRational,exp,log,sqrt,
logBase,sin,cos,tan,asin,acos,atan,sinh,cosh,tanh,asinh,acosh,atanh,
properFraction,truncate,round,ceiling,floor,floatRadix,floatDigits,floatRange,
decodeFloat,encodeFloat,exponent,significand,scaleFloat,isNaN,isInfinite,
isDenormalized,isIEEE,isNegativeZero,atan2,return,fail,fmap,mapM,
sequence,maybe,either,not,otherwise,subtract,even,odd,gcd,lcm,
fromIntegral,realToFrac,fst,snd,curry,uncurry,id,const,flip,until,
asTypeOf,error,seq)
% PreludeList:
\functions (map,filter,concat,head,last,tail,init,null,length,foldl,scanl,
foldr,scanr,iterate,repeat,replicate,cycle,take,drop,splitAt,takeWhile,
dropWhile,span,break,lines,words,unlines,unwords,reverse,elem,notElem,lookup,
maximum,minimum,concatMap,zip,zipWith,unzip)
% PreludeText:
\functions (readsProc,readList,showsProc,showList,reads,shows,show,read,lex,
showChar,showString,readParen,showParen)
% PreludeIO:
\functions (ioError,userError,catch,putChar,putStr,putStrLn,print,getChar,
getLine,getContents,interact,readFile,writeFile,appendFile,readIO,readLn)
% other typeclass-methods:
\functions (compare, showsPrec, readsPrec, mempty, mappend, mconcat)
%%% Haskell category codes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% In a moment we will implement a relatively complete lexical analyser for
% Haskell. To make our job simpler, we collect all ASCII characters into
% the following ten equivalence classes:
%
% 0. SP - space
% 1. LC - lowercase letters
% 2. UC - uppercase letters
% 3. DI - digits
% 4. SY - symbols
% 5. PU - punctuators
% 6. AP - apostrophe
% 7. QT - double quotation mark
% 8. NL - newline
\chardef\hs@SP=0
\chardef\hs@LC=1
\chardef\hs@UC=2
\chardef\hs@DI=3
\chardef\hs@SY=4
\chardef\hs@PU=5
\chardef\hs@AP=6
\chardef\hs@QT=7
\chardef\hs@NL=8
% The macro \hs@getcc#1 computes the Haskell category code of its argument
% ans stores it in the counter variable \hs@cc.
\newcount\hs@cc
\def\hs@getcc#1{%
\hs@cc=`#1
\ifnum\hs@cc<65 %%% NUL - @
\ifnum\hs@cc<32 %%% NUL - US
\ifnum\hs@cc=9
\hs@cc=\hs@SP
\else\ifnum\hs@cc=13
\hs@cc=\hs@NL
\else
\hs@cc=-1
\fi\fi
\else %%% SP - @
\ifnum\hs@cc<48 %%% SP - /
\ifnum\hs@cc=32 %%% SP
\hs@cc=\hs@SP
\else\ifnum\hs@cc=34 %%% "
\hs@cc=\hs@QT
\else\ifnum\hs@cc=39 %%% '
\hs@cc=\hs@AP
\else\ifnum\hs@cc=40 %%% (
\hs@cc=\hs@PU
\else\ifnum\hs@cc=41 %%% )
\hs@cc=\hs@PU
\else\ifnum\hs@cc=44 %%% ,
\hs@cc=\hs@PU
\else
\hs@cc=\hs@SY
\fi\fi\fi\fi\fi\fi
\else %%% 0 - @
\ifnum\hs@cc<58 %%% 0 - 9
\hs@cc=\hs@DI
\else\ifnum\hs@cc=59 %%% ;
\hs@cc=\hs@PU
\else
\hs@cc=\hs@SY
\fi\fi
\fi
\fi
\else %%% A - DEL
\ifnum\hs@cc<97 %%% A - `
\ifnum\hs@cc<91 %%% A - Z
\hs@cc=\hs@UC
\else\ifnum\hs@cc=92 %%% \
\hs@cc=\hs@SY
\else\ifnum\hs@cc=94 %%% ^
\hs@cc=\hs@SY
% \else\ifnum\hs@cc=95 %%% _
% \hs@cc=\hs@LC
\else %%% [ ] `
\hs@cc=\hs@PU
\fi\fi\fi%\fi
\else %%% a - DEL
\ifnum\hs@cc<123 %%% a - z
\hs@cc=\hs@LC
\else\ifnum\hs@cc=123 %%% {
\hs@cc=\hs@PU
\else\ifnum\hs@cc=124 %%% |
\hs@cc=\hs@SY
\else\ifnum\hs@cc=125 %%% }
\hs@cc=\hs@PU
\else\ifnum\hs@cc=126 %%% ~
\hs@cc=\hs@SY
\else
\hs@cc=-1
\fi\fi\fi\fi\fi
\fi
\fi}
%%% The lexical analyzer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Now we are ready to implement the actual lexical analyzer.
%
\def\hs@code@state#1{%
\hs@getcc#1%
\ifcase\hs@cc
% SP - space
\ifnum`#1=9\advance\hs@indent by \hstabwidth
\else\advance\hs@indent by \hsspacewidth\fi
\let\next=\hs@code@state
\or % LC - lowercase letters
\xdef\hs@tok{#1}%
\let\next=\hs@var@state
\or % UC - uppercase letters
\xdef\hs@tok{#1}%
\let\next=\hs@con@state
\or % DI - digits
\xdef\hs@tok{#1}%
\ifx#10\let\next=\hs@zero@state\else\let\next=\hs@dec@state\fi
\or % SY - symbols
\xdef\hs@tok{#1}%
\ifx#1-\let\next=\hs@dash@state\else\let\next=\hs@sym@state\fi
\or % PU - punctuators
\xdef\hs@tok{#1}%
\hs@emitsym
\let\next=\hs@lex@state
\or % AP - apostrophe
\let\next=\hs@chr@state
\or % QT - double quotation mark
\let\next=\hs@str@state
\or % NL - newline
\def\hs@parskip{\vskip\hsparskip\def\hs@parskip{}}%
\let\next=\hs@newline@state
\else
\errmessage{Illegal character in Haskell mode: #1}%
\fi
\next}
\def\hs@newline@state#1{%
\hs@outputline
\ifx#1>
\hs@space=0pt
\let\next=\hs@code@state
\else
% It must be a space or a newline; just drop it.
\par
\endgroup
\afterhs
\par\noindent\ignorespaces
\let\next=\relax
\fi
\next}
\def\hs@lex@state#1{%
\hs@getcc#1%
\ifcase\hs@cc
% SP - space
\hs@space=\hswordspace
\let\next=\hs@lex@state
\or % LC - lowercase letters
\xdef\hs@tok{#1}%
\let\next=\hs@var@state
\or % UC - uppercase letters
\xdef\hs@tok{#1}%
\let\next=\hs@con@state
\or % DI - digits
\xdef\hs@tok{#1}%
\ifx#10\let\next=\hs@zero@state\else\let\next=\hs@dec@state\fi
\or % SY - symbols
\xdef\hs@tok{#1}%
\ifx#1-\let\next=\hs@dash@state\else\let\next=\hs@sym@state\fi
\or % PU - punctuators
\xdef\hs@tok{#1}%
\hs@emitsym
\let\next=\hs@lex@state
\or % AP - apostrophe
\xdef\hs@tok{}%
\let\next=\hs@chr@state
\or % QT - double quotation mark
\ifhs@inline
\hs@endInline
\let\next=\relax
\else
\xdef\hs@tok{}%
\let\next=\hs@str@state
\fi
\or % NL - newline
\ifhs@inline
\hs@space=\hswordspace
\let\next=\hs@lex@state
\else
\let\next=\hs@newline@state
\fi
\else
\errmessage{Illegal character in Haskell mode: #1}%
\fi
\next}
\def\hs@var@state#1{%
\hs@getcc#1%
\ifcase\hs@cc
% SP - space
\hs@emitvar
\hs@space=\hswordspace
\let\next=\hs@lex@state
\or % LC - lowercase letters
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@var@state
\or % UC - uppercase letters
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@var@state
\or % DI - digits
\edef\hs@sub{\hs@sub#1}%
\let\next=\hs@var@state
\or % SY - symbols
\hs@emitvar
\xdef\hs@tok{#1}%
\ifx#1-\let\next=\hs@dash@state\else\let\next=\hs@sym@state\fi
\or % PU - punctuators
\hs@emitvar
\xdef\hs@tok{#1}%
\hs@emitsym
\let\next=\hs@lex@state
\or % AP - apostrophe
\edef\hs@sup{\hs@sup\prime}%
\let\next=\hs@var@state
\or % QT - double quotation mark
\hs@emitvar
\ifhs@inline
\hs@endInline
\let\next=\relax
\else
\let\next=\hs@str@state
\fi
\or % NL - newline
\hs@emitvar
\ifhs@inline
\hs@space=\hswordspace
\let\next=\hs@lex@state
\else
\let\next=\hs@newline@state
\fi
\else
\errmessage{Illegal character in Haskell mode: #1}%
\fi
\next}
\def\hs@con@state#1{%
\hs@getcc#1%
\ifcase\hs@cc
% SP - space
\hs@emitcon
\hs@space=\hswordspace
\let\next=\hs@lex@state
\or % LC - lowercase letters
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@con@state
\or % UC - uppercase letters
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@con@state
\or % DI - digits
\edef\hs@sub{\hs@sub#1}%
\let\next=\hs@con@state
\or % SY - symbols
\hs@emitcon
\xdef\hs@tok{#1}%
\ifx#1-\let\next=\hs@dash@state\else\let\next=\hs@sym@state\fi
\or % PU - punctuators
\hs@emitcon
\xdef\hs@tok{#1}%
\hs@emitsym
\let\next=\hs@lex@state
\or % AP - apostrophe
\edef\hs@sup{\hs@sup\prime}%
\let\next=\hs@con@state
\or % QT - double quotation mark
\hs@emitcon
\ifhs@inline
\hs@endInline
\let\next=\relax
\else
\let\next=\hs@str@state
\fi
\or % NL - newline
\hs@emitcon
\ifhs@inline
\hs@space=\hswordspace
\let\next=\hs@lex@state
\else
\let\next=\hs@newline@state
\fi
\else
\errmessage{Illegal character in Haskell mode: #1}%
\fi
\next}
\def\hs@sym@state#1{%
\hs@getcc#1%
\ifcase\hs@cc
% SP - space
\hs@emitsym
\hs@space=\hswordspace
\let\next=\hs@lex@state
\or % LC - lowercase letters
\hs@emitsym
\xdef\hs@tok{#1}%
\let\next=\hs@var@state
\or % UC - uppercase letters
\hs@emitsym
\xdef\hs@tok{#1}%
\let\next=\hs@con@state
\or % DI - digits
\hs@emitsym
\xdef\hs@tok{#1}%
\ifx#10\let\next=\hs@zero@state\else\let\next=\hs@dec@state\fi
\or % SY - symbols
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@sym@state
\or % PU - punctuators
\hs@emitsym
\xdef\hs@tok{#1}%
\hs@emitsym
\let\next=\hs@lex@state
\or % AP - apostrophe
\hs@emitsym
\xdef\hs@tok{}%
\let\next=\hs@chr@state
\or % QT - double quotation mark
\hs@emitsym
\ifhs@inline
\hs@endInline
\let\next=\relax
\else
\xdef\hs@tok{}%
\let\next=\hs@str@state
\fi
\or % NL - newline
\hs@emitsym
\ifhs@inline
\hs@space=\hswordspace
\let\next=\hs@lex@state
\else
\let\next=\hs@newline@state
\fi
\else
\errmessage{Illegal character in Haskell mode: #1}%
\fi
\next}
\def\hs@dash@state#1{%
\hs@getcc#1%
\ifcase\hs@cc
% SP - space
\hs@emitsym
\hs@space=\hswordspace
\let\next=\hs@lex@state
\or % LC - lowercase letters
\hs@emitsym
\xdef\hs@tok{#1}%
\let\next=\hs@var@state
\or % UC - uppercase letters
\hs@emitsym
\xdef\hs@tok{#1}%
\let\next=\hs@con@state
\or % DI - digits
\hs@emitsym
\xdef\hs@tok{#1}%
\ifx#10\let\next=\hs@zero@state\else\let\next=\hs@dec@state\fi
\or % SY - symbols
\xdef\hs@tok{\hs@tok#1}%
\ifx#1-\let\next=\hs@dashdash@state\else\let\next=\hs@sym@state\fi
\or % PU - punctuators
\hs@emitsym
\xdef\hs@tok{#1}%
\hs@emitsym
\let\next=\hs@lex@state
\or % AP - apostrophe
\hs@emitsym
\xdef\hs@tok{}%
\let\next=\hs@chr@state
\or % QT - double quotation mark
\hs@emitsym
\ifhs@inline
\hs@endInline
\let\next=\relax
\else
\xdef\hs@tok{}%
\let\next=\hs@str@state
\fi
\or % NL - newline
\hs@emitsym
\ifhs@inline
\hs@space=\hswordspace
\let\next=\hs@lex@state
\else
\let\next=\hs@newline@state
\fi
\else
\errmessage{Illegal character in Haskell mode: #1}%
\fi
\next}
%%% XXX
\def\hs@dashdash@state#1{%
\hs@getcc#1%
\ifcase\hs@cc
% SP - space
\xdef\hs@tok{\hs@}%
\hs@preparecomment
\let\next=\hs@comment@state
\or % LC - lowercase letters
\xdef\hs@tok{#1}%
\hs@preparecomment
\let\next=\hs@comment@state
\or % UC - uppercase letters
\xdef\hs@tok{#1}%
\hs@preparecomment
\let\next=\hs@comment@state
\or % DI - digits
\xdef\hs@tok{#1}%
\hs@preparecomment
\let\next=\hs@comment@state
\or % SY - symbols
\xdef\hs@tok{\hs@tok#1}%
\ifx#1-\let\next=\hs@dashdash@state\else\let\next=\hs@sym@state\fi
\or % PU - punctuators
\xdef\hs@tok{#1}%
\hs@preparecomment
\let\next=\hs@comment@state
\or % AP - apostrophe
\xdef\hs@tok{#1}%
\hs@preparecomment
\let\next=\hs@comment@state
\or % QT - double quotation mark
\xdef\hs@tok{#1}%
\hs@preparecomment
\let\next=\hs@comment@state
\or % NL - newline
\ifhs@inline
\errmessage{Comment in inline Haskell mode}%
\else
\xdef\hs@tok{}%
\hs@emitdashes
\let\next=\hs@newline@state
\fi
\else
\errmessage{Illegal character in Haskell mode: #1}%
\fi
\next}
\def\hs@zero@state#1{%
\hs@getcc#1%
\ifcase\hs@cc
% SP - space
\hs@emitnum{}%
\hs@space=\hswordspace
\let\next=\hs@lex@state
\or % LC - lowercase letters
\ifx#1o
\edef\hs@sub{8}%
\xdef\hs@tok{}%
\let\next=\hs@oct@state
\else\ifx#1x
\edef\hs@sub{16}%
\xdef\hs@tok{}%
\let\next=\hs@hex@state
\else
\hs@emitnum{}%
\xdef\hs@tok{#1}%
\let\next=\hs@var@state
\fi\fi
\or % UC - uppercase letters
\ifx#1O
\edef\hs@sub{8}%
\xdef\hs@tok{}%
\let\next=\hs@oct@state
\else\ifx#1X
\edef\hs@sub{16}%
\xdef\hs@tok{}%
\let\next=\hs@hex@state
\else
\hs@emitnum{}%
\xdef\hs@tok{#1}%
\let\next=\hs@con@state
\fi\fi
\or % DI - digits
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@dec@state
\or % SY - symbols
\hs@emitnum{}%
\xdef\hs@tok{#1}%
\ifx#1-\let\next=\hs@dash@state\else\let\next=\hs@sym@state\fi
\or % PU - punctuators
\hs@emitnum{}%
\xdef\hs@tok{#1}%
\hs@emitsym
\let\next=\hs@lex@state
\or % AP - apostrophe
\hs@emitnum{}%
\xdef\hs@tok{}%
\let\next=\hs@chr@state
\or % QT - double quotation mark
\hs@emitnum{}%
\ifhs@inline
\hs@endInline
\let\next=\relax
\else
\xdef\hs@tok{}%
\let\next=\hs@str@state
\fi
\or % NL - newline
\hs@emitnum{}%
\ifhs@inline
\hs@space=\hswordspace
\let\next=\hs@lex@state
\else
\let\next=\hs@newline@state
\fi
\else
\errmessage{Illegal character in Haskell mode: #1}%
\fi
\next}
\def\hs@dec@state#1{%
\hs@getcc#1%
\ifcase\hs@cc
% SP - space
\hs@emitnum{}%
\hs@space=\hswordspace
\let\next=\hs@lex@state
\or % LC - lowercase letters
\hs@emitnum{}%
\xdef\hs@tok{#1}%
\let\next=\hs@var@state
\or % UC - uppercase letters
\hs@emitnum{}%
\xdef\hs@tok{#1}%
\let\next=\hs@con@state
\or % DI - digits
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@dec@state
\or % SY - symbols
\hs@emitnum{}%
\xdef\hs@tok{#1}%
\ifx#1-\let\next=\hs@dash@state\else\let\next=\hs@sym@state\fi
\or % PU - punctuators
\hs@emitnum{}%
\xdef\hs@tok{#1}%
\hs@emitsym
\let\next=\hs@lex@state
\or % AP - apostrophe
\hs@emitnum{}%
\xdef\hs@tok{}%
\let\next=\hs@chr@state
\or % QT - double quotation mark
\hs@emitnum{}%
\ifhs@inline
\hs@endInline
\let\next=\relax
\else
\xdef\hs@tok{}%
\let\next=\hs@str@state
\fi
\or % NL - newline
\hs@emitnum{}%
\ifhs@inline
\hs@space=\hswordspace
\let\next=\hs@lex@state
\else
\let\next=\hs@newline@state
\fi
\else
\errmessage{Illegal character in Haskell mode: #1}%
\fi
\next}
\def\hs@oct@state#1{%
\hs@getcc#1%
\ifcase\hs@cc
% SP - space
\hs@emitnum{0o}%
\hs@space=\hswordspace
\let\next=\hs@lex@state
\or % LC - lowercase letters
\hs@emitnum{0o}%
\xdef\hs@tok{#1}%
\let\next=\hs@var@state
\or % UC - uppercase letters
\hs@emitnum{0o}%
\xdef\hs@tok{#1}%
\let\next=\hs@con@state
\or % DI - digits
\ifnum`#1<`8
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@oct@state
\else
\hs@emitnum{0o}%
\xdef\hs@tok{#1}%
\let\next=\hs@dec@state
\fi
\or % SY - symbols
\hs@emitnum{0o}%
\xdef\hs@tok{#1}%
\ifx#1-\let\next=\hs@dash@state\else\let\next=\hs@sym@state\fi
\or % PU - punctuators
\hs@emitnum{0o}%
\xdef\hs@tok{#1}%
\hs@emitsym
\let\next=\hs@lex@state
\or % AP - apostrophe
\hs@emitnum{0o}%
\xdef\hs@tok{}%
\let\next=\hs@chr@state
\or % QT - double quotation mark
\hs@emitnum{0o}%
\ifhs@inline
\hs@endInline
\let\next=\relax
\else
\xdef\hs@tok{}%
\let\next=\hs@str@state
\fi
\or % NL - newline
\hs@emitnum{0o}%
\ifhs@inline
\hs@space=\hswordspace
\let\next=\hs@lex@state
\else
\let\next=\hs@newline@state
\fi
\else
\errmessage{Illegal character in Haskell mode: #1}%
\fi
\next}
\def\hs@hex@state#1{%
\hs@getcc#1%
\ifcase\hs@cc
% SP - space
\hs@emitnum{0x}%
\hs@space=\hswordspace
\let\next=\hs@lex@state
\or % LC - lowercase letters
\ifnum`#1<`g
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@hex@state
\else
\hs@emitnum{0x}%
\xdef\hs@tok{#1}%
\let\next=\hs@var@state
\fi
\or % UC - uppercase letters
\ifnum`#1<`G
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@hex@state
\else
\hs@emitnum{0x}%
\xdef\hs@tok{#1}%
\let\next=\hs@con@state
\fi
\or % DI - digits
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@hex@state
\or % SY - symbols
\hs@emitnum{0x}%
\xdef\hs@tok{#1}%
\ifx#1-\let\next=\hs@dash@state\else\let\next=\hs@sym@state\fi
\or % PU - punctuators
\hs@emitnum{0x}%
\xdef\hs@tok{#1}%
\hs@emitsym
\let\next=\hs@lex@state
\or % AP - apostrophe
\hs@emitnum{0x}%
\xdef\hs@tok{}%
\let\next=\hs@chr@state
\or % QT - double quotation mark
\hs@emitnum{0x}%
\ifhs@inline
\hs@endInline
\let\next=\relax
\else
\xdef\hs@tok{}%
\let\next=\hs@str@state
\fi
\or % NL - newline
\hs@emitnum{0x}%
\ifhs@inline
\hs@space=\hswordspace
\let\next=\hs@lex@state
\else
\let\next=\hs@newline@state
\fi
\else
\errmessage{Illegal character in Haskell mode: #1}%
\fi
\next}
\def\hs@chr@state#1{%
\ifnum`#1=`'
\hs@emitchr
\let\next=\hs@lex@state
\else\ifnum`#1=92
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@chresc@state
\else
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@chr@state
\fi\fi
\next}
\def\hs@chresc@state#1{%
\xdef\hs@tok{\hs@tok#1}\hs@chr@state}
\def\hs@str@state{%
\def\hs@strprefix{\hs@symface``}%
\hs@strchr@state}
\def\hs@strchr@state#1{%
\ifx#1"
\setbox255=\hbox{\hs@strprefix\hs@strface\hs@tok\hs@symface''}%
\hs@emit
\let\next=\hs@lex@state
\else\ifnum`#1=92
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@stresc@state
\else
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@strchr@state
\fi\fi
\next}
\def\hs@stresc@state#1{%
\hs@getcc#1%
\ifnum\hs@cc=\hs@SP
\let\next=\hs@gap@state
\else\ifnum\hs@cc=\hs@NL
\let\next=\hs@gapnewline@state
\else
\xdef\hs@tok{\hs@tok#1}%
\let\next=\hs@strchr@state
\fi\fi
\next}
\def\hs@gap@state#1{%
\hs@getcc#1%
\ifnum\hs@cc=\hs@SP
\let\next=\hs@gap@state
\else\ifnum\hs@cc=\hs@NL
\let\next=\hs@gapnewline@state
\else
\ifnum`#1=92
\xdef\hs@tok{\hs@tok\hs@#1}%
\let\next=\hs@strchr@state
\else
\errmessage{Unexpected character in a gap: #1}%
\fi
\fi\fi
\next}
\def\hs@gapnewline@state#1{%
\setbox255=\hbox{\hs@strprefix\hs@strface\hs@tok}%
\hs@emit
\hs@outputline
\ifx#1>
\def\hs@strprefix{}%
\hs@space=0pt
\let\next=\hs@gapcode@state
\else
\errmessage{Literate comments cannot appear in a gap}
\fi
\next}
\def\hs@gapcode@state#1{%
\hs@getcc#1%
\ifnum\hs@cc=\hs@SP
\ifnum`#1=9\advance\hs@indent by \hstabwidth
\else\advance\hs@indent by \hsspacewidth\fi
\let\next=\hs@gapcode@state
\else\ifnum\hs@cc=\hs@NL
\def\hs@parskip{\vskip\hsparskip\def\hs@parskip{}}%
\let\next=\hs@gapnewline@state
\else
\ifnum`#1=92
\xdef\hs@tok{#1}%
\let\next=\hs@strchr@state
\else
\errmessage{Unexpected character in a gap: #1}%
\fi
\fi\fi
\next}
%%% The "hidden" environment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
\newbox\hs@junkbox
\def\beginhidden{\begingroup\setbox\hs@junkbox=\vbox\bgroup}
\def\endhidden{\egroup\endgroup}
%%% Activate active characters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% As we've already confiscated > as an active character, let's take < too
% and use <...> to typeset ... in italic.
% To make amends for the above quirk, I define \lt and \gt math macros
% to complement the \le, \ge, etc. already in plain TeX:
\def\inch{"}
\def\lt{<}
\def\gt{>}
% Finally, we are ready to active our three active characters:
\catcode`"=\active \let"=\hs@beginInline
\catcode`>=\active \let>=\hs@beginBird
\catcode`<=\active \let<=\hs@beginitalic
% Restore the meaning of < and > in math mode.
% WARNING: this doesn't work as well as expected. When TeX sees the $
% character, it reads the following character to see if it is another $.
% If that character is active, it attempts to expand it (a bug in TeX?!
% or just a mis-feature?) So, you must write $ >$ rather than $>$. Oh well.
\everymath{\let<\lt\let>\gt\relax}
\everydisplay{\let<\lt\let>\gt\relax}
\catcode`@=12
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% THE END %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%