% % @TAG(OTHER_BSD) % % 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 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. \ProvidesPackage{lambdaTeX} \catcode`@=11 \newskip\hsparskip \hsparskip=8pt \newdimen\hsleftskip \hsleftskip=20pt \newdimen\hsrightskip \hsrightskip=10pt \newdimen\hscommentskip \hscommentskip=1em \newdimen\hswordspace \hswordspace=.3em \newdimen\hsspacewidth \hsspacewidth=0.5em \newdimen\hstabwidth \hstabwidth=8em \def\everyhs{} \def\beforehs{\vskip 4pt plus3pt minus1pt} \def\afterhs{\vskip 4pt plus3pt minus1pt} \let\hs@family\empty \let\hs@family\hsfamily \ifx\hs@family\empty\let\hs@family\ttfamily\fi \newcommand{\hs@keyface}{\hs@family\bfseries} \newcommand{\hs@funface}{\hs@family} \newcommand{\hs@varface}{\hs@family\itshape} \newcommand{\hs@conface}{\hs@family\scshape} \newcommand{\hs@numface}{\hs@family} \newcommand{\hs@strface}{\ttfamily} \newcommand{\hs@symface}{\hs@family} %%% 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 % Subscripts and superscripts \def\hs@scripts{$\fam=15 ^{\hs@sup}_{\hs@sub}$} % 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}{{\hs@keyface 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}} % Define Greek letters: \typeset{alpha}{$\alpha$\hs@scripts} \typeset{beta}{$\beta$\hs@scripts} \typeset{gamma}{$\gamma$\hs@scripts} \typeset{delta}{$\delta$\hs@scripts} \typeset{epsilon}{$\epsilon$\hs@scripts} \typeset{zeta}{$\zeta$\hs@scripts} \typeset{eta}{$\eta$\hs@scripts} \typeset{theta}{$\theta$\hs@scripts} \typeset{iota}{$\iota$\hs@scripts} \typeset{kappa}{$\kappa$\hs@scripts} \typeset{lambda}{$\lambda$\hs@scripts} \typeset{mu}{$\mu$\hs@scripts} \typeset{nu}{$\nu$\hs@scripts} \typeset{xi}{$\xi$\hs@scripts} \typeset{pi}{$\pi$\hs@scripts} \typeset{rho}{$\rho$\hs@scripts} \typeset{sigma}{$\sigma$\hs@scripts} \typeset{tau}{$\tau$\hs@scripts} \typeset{upsilon}{$\upsilon$\hs@scripts} \typeset{phi}{$\phi$\hs@scripts} \typeset{chi}{$\chi$\hs@scripts} \typeset{psi}{$\psi$\hs@scripts} \typeset{omega}{$\omega$\hs@scripts} \typeset{Alpha}{$\mit A$\hs@scripts} \typeset{Beta}{$\mit B$\hs@scripts} \typeset{Gamma}{$\mit\Gamma$\hs@scripts} \typeset{Delta}{$\mit\Delta$\hs@scripts} \typeset{Epsilon}{$\mit E$\hs@scripts} \typeset{Zeta}{$\mit Z$\hs@scripts} \typeset{Eta}{$\mit H$\hs@scripts} \typeset{Theta}{$\mit\Theta$\hs@scripts} \typeset{Iota}{$\mit I$\hs@scripts} \typeset{Kappa}{$\mit K$\hs@scripts} \typeset{Lambda}{$\mit\Lambda$\hs@scripts} \typeset{Mu}{$\mit M$\hs@scripts} \typeset{Nu}{$\mit N$\hs@scripts} \typeset{Xi}{$\mit\Xi$\hs@scripts} \typeset{Pi}{$\mit\Pi$\hs@scripts} \typeset{Rho}{$\mit P$\hs@scripts} \typeset{Sigma}{$\mit\Sigma$\hs@scripts} \typeset{Tau}{$\mit T$\hs@scripts} \typeset{Upsilon}{$\mit\Upsilon$\hs@scripts} \typeset{Phi}{$\mit\Phi$\hs@scripts} \typeset{Chi}{$\mit X$\hs@scripts} \typeset{Psi}{$\mit\Psi$\hs@scripts} \typeset{Omega}{$\mit\Omega$\hs@scripts} \typeset{ALPHA}{$\rm A$\hs@scripts} \typeset{BETA}{$\rm B$\hs@scripts} \typeset{GAMMA}{$\Gamma$\hs@scripts} \typeset{DELTA}{$\Delta$\hs@scripts} \typeset{EPSILON}{$\rm E$\hs@scripts} \typeset{ZETA}{$\rm Z$\hs@scripts} \typeset{ETA}{$\rm H$\hs@scripts} \typeset{THETA}{$\Theta$\hs@scripts} \typeset{IOTA}{$\rm I$\hs@scripts} \typeset{KAPPA}{$\rm K$\hs@scripts} \typeset{LAMBDA}{$\Lambda$\hs@scripts} \typeset{MU}{$\rm M$\hs@scripts} \typeset{NU}{$\rm N$\hs@scripts} \typeset{XI}{$\Xi$\hs@scripts} \typeset{PI}{$\Pi$\hs@scripts} \typeset{RHO}{$\rm P$\hs@scripts} \typeset{SIGMA}{$\Sigma$\hs@scripts} \typeset{TAU}{$\rm T$\hs@scripts} \typeset{UPSILON}{$\Upsilon$\hs@scripts} \typeset{PHI}{$\Phi$\hs@scripts} \typeset{CHI}{$\rm X$\hs@scripts} \typeset{PSI}{$\Psi$\hs@scripts} \typeset{OMEGA}{$\Omega$\hs@scripts} % 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{not}{$\lnot$} % Define common symbols: \typeset{=}{{\hs@symface=}} \typeset{<-}{$\leftarrow$} \typeset{->}{$\rightarrow$} \typeset{=>}{$\Rightarrow$} \typeset{++}{$+\kern-.2em+$} \typeset{==}{$=$} \typeset{/=}{$\neq$} \typeset{<=}{$\leq$} \typeset{>=}{$\geq$} \typeset{||}{$\vee$} \typeset{&&}{$\wedge$} % Symbols with a backslash are a little tricky: \expandafter\def\csname<\string\>\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{% {\hs@symface\global\textfont15=\font \scriptsize\global\scriptfont15=\font \tiny\global\scriptscriptfont15=\font}% % 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 \mathcode40="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="026A % | \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@scripts}% \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@scripts}% \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$\fam=15 _{\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@scripts}}% \let\next=\relax \else\ifx#1, \typeset{\hs@tok}{{\hs@funface\hs@tok\hs@scripts}}% \let\next=\hs@funbegin \else\ifnum`#1=9 \typeset{\hs@tok}{{\hs@funface\hs@tok\hs@scripts}}% \let\next=\hs@funbegin \else\ifnum`#1=32 \typeset{\hs@tok}{{\hs@funface\hs@tok\hs@scripts}}% \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@scripts}}% \let\next=\relax \else\ifx#1, \typeset{\hs@tok}{{\hs@varface\hs@tok\hs@scripts}}% \let\next=\hs@funbegin \else\ifnum`#1=9 \typeset{\hs@tok}{{\hs@varface\hs@tok\hs@scripts}}% \let\next=\hs@funbegin \else\ifnum`#1=32 \typeset{\hs@tok}{{\hs@varface\hs@tok\hs@scripts}}% \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,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) %%% 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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%