Import hs-plugins cvs
This commit is contained in:
452
docs/haskell.sty
Normal file
452
docs/haskell.sty
Normal file
@ -0,0 +1,452 @@
|
||||
%%% This is a LaTeX2e style file.
|
||||
%%%
|
||||
%%% It supports setting functional languages like Haskell.
|
||||
%%%
|
||||
%%% Manuel M. T. Chakravarty <chak@cse.unsw.edu.au> [1998..2000]
|
||||
%%%
|
||||
%%% $Id: haskell.sty,v 1.2 2004/05/16 08:20:09 dons Exp $
|
||||
%%%
|
||||
%%% This file is free software; you can redistribute it and/or modify
|
||||
%%% it under the terms of the GNU General Public License as published by
|
||||
%%% the Free Software Foundation; either version 2 of the License, or
|
||||
%%% (at your option) any later version.
|
||||
%%%
|
||||
%%% This file is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
%%% GNU General Public License for more details.
|
||||
%%%
|
||||
%%% Acknowledegments ==========================================================
|
||||
%%%
|
||||
%%% Thanks to Gabriele Keller <keller@cs.tu-berlin.de> for beta testing and
|
||||
%%% code contributions. Thanks to the LaTeX3 project for improving the LaTeX
|
||||
%%% sources (which helped me writing this code). Furthermore, I am grateful
|
||||
%%% to Martin Erwig <Martin.Erwig@FernUni-Hagen.de> for feedback and
|
||||
%%% suggestions, and to Conal Elliott <conal@MICROSOFT.com> for pointing out
|
||||
%%% a tricky bug.
|
||||
%%%
|
||||
%%% TODO ======================================================================
|
||||
%%%
|
||||
%%% B ~ bug; F ~ feature
|
||||
%%%
|
||||
%%% * F: Along the lines of the discussion with Martin Erwig add support for
|
||||
%%% keywords etc (see the emails)
|
||||
%%%
|
||||
%%% * B: If we have as input
|
||||
%%%
|
||||
%%% \<map
|
||||
%%% g\>
|
||||
%%%
|
||||
%%% there won't be a `\hsap' inserted!! (Can this be solved by using
|
||||
%%% \obeylines in \<...\>?)
|
||||
%%%
|
||||
%%% * B: A \relax is needed after a & if it immediately followed by a \hsbody{}
|
||||
%%% (See TeXbook, S.240)
|
||||
%%%
|
||||
%%% * F: Implement a \hstext{...} as \(\text{...}\).
|
||||
%%%
|
||||
%%% * We would like hswhere* etc that are like haskell* (\hsalign already
|
||||
%%% supports this, ie, there is a \hsalign*).
|
||||
%%%
|
||||
%%% * Star-Versions of if, let etc that use a single line layout (maybe not
|
||||
%%% with star, because of the above).
|
||||
%%%
|
||||
%%% * Support for enforcing and prohibiting breaks in `haskell' displays.
|
||||
%%%
|
||||
%%% * Comments in a let-in should be aligned in the same way for the bindings
|
||||
%%% and the body.
|
||||
%%%
|
||||
%%% * It would be nice to have different styles (indentation after in of
|
||||
%%% let-in or not) etc; either to be set with a package option or in the
|
||||
%%% preamble (the latter probably makes more sense).
|
||||
%%%
|
||||
%%% * Literate programming facility: Variant of the `haskell' env (maybe
|
||||
%%% `hschunk', which is named and can be used in other chunks). But maybe
|
||||
%%% it is not necessary to provide a chunk-based reordering mechanism,
|
||||
%%% because most of the Haskell stuff can be in any order anyway...
|
||||
%%% Important is to provide a way to define visually pleasing layout
|
||||
%%% together with the raw Haskell form for program output. (Maybe `haskell*'
|
||||
%%% as Haskell env that outputs its contents?)
|
||||
%%%
|
||||
|
||||
%% Initialization
|
||||
%% ==============
|
||||
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{haskell}[2000/10/05 v1.0e Chilli's Haskell Style]
|
||||
|
||||
|
||||
%% Parameters
|
||||
%% ==========
|
||||
|
||||
\newskip\hsmargin
|
||||
\hsmargin\leftmargini
|
||||
|
||||
|
||||
%% Main macros and environments
|
||||
%% ============================
|
||||
|
||||
% applications
|
||||
%
|
||||
\newcommand{\hsap}{% % application by juxtaposition
|
||||
\unskip\mskip 4mu plus 1mu} % only the last \hsap counts
|
||||
|
||||
% commands to start and stop setting spaces as \hsap
|
||||
%
|
||||
{\obeyspaces\gdef\@hsSpaceToApp{\obeyspaces\let =\hsap}} % spaces matter!!!
|
||||
{\obeyspaces\gdef\@hsNormalSpace{\let =\space}}
|
||||
|
||||
% commands to start and stop treating numbers specially, ie, we don't want
|
||||
% them to be affected by font changing commands in Haskell contexts as this
|
||||
% would give italic numerals; the trick is to redefine their math code such
|
||||
% that they go into math class 0 and thus don't change families (cf. `The
|
||||
% TeXbook', Chapter 17, pp152)
|
||||
%
|
||||
\newcommand{\@hsRmNumbers}{%
|
||||
\mathcode`0="0030
|
||||
\mathcode`1="0031
|
||||
\mathcode`2="0032
|
||||
\mathcode`3="0033
|
||||
\mathcode`4="0034
|
||||
\mathcode`5="0035
|
||||
\mathcode`6="0036
|
||||
\mathcode`7="0037
|
||||
\mathcode`8="0038
|
||||
\mathcode`9="0039
|
||||
}
|
||||
\newcommand{\@hsNormalNumbers}{%
|
||||
\mathcode`0="7030
|
||||
\mathcode`1="7031
|
||||
\mathcode`2="7032
|
||||
\mathcode`3="7033
|
||||
\mathcode`4="7034
|
||||
\mathcode`5="7035
|
||||
\mathcode`6="7036
|
||||
\mathcode`7="7037
|
||||
\mathcode`8="7038
|
||||
\mathcode`9="7039
|
||||
}
|
||||
|
||||
% Save the bindings of the standard math commands
|
||||
%
|
||||
% This is somewhat subtle as we want to able to enter the original math mode
|
||||
% within Haskell mode and we have to ensure that the different opening
|
||||
% commands are matched by the correct versions of the closing commands.
|
||||
%
|
||||
\let\@hsmathorg=\(
|
||||
\let\@hsmathendorg=\)
|
||||
\let\hs@crorg=\\
|
||||
\newcommand{\@hsmath}{%
|
||||
\relax\hbox\bgroup
|
||||
\@hsNormalSpace
|
||||
\@hsNormalNumbers
|
||||
\let\(=\@hsmathorgx
|
||||
\let\)=\@hsmathend
|
||||
\def\\{\hs@crorg}%
|
||||
\@hsmathorg
|
||||
}
|
||||
\newcommand{\@hsmathend}{%
|
||||
\@hsmathendorg
|
||||
\egroup
|
||||
}
|
||||
\newcommand{\@hsmathorgx}{%
|
||||
\relax\@hsmathorg
|
||||
\let\)=\@hsmathendorg
|
||||
}
|
||||
|
||||
%% Typesetting of Haskell
|
||||
%% ======================
|
||||
|
||||
% Inline Haskell phrases are delimited by `\<' and `\>'.
|
||||
%
|
||||
% Note: `\>' is only locally redefined.
|
||||
%
|
||||
\newcommand{\<}{%
|
||||
\@hsmathorg
|
||||
\mathit\bgroup
|
||||
\@hsSpaceToApp
|
||||
\@hsRmNumbers
|
||||
\let\>=\@endhs
|
||||
\let\(=\@hsmath
|
||||
\def\\{\cr} % for Haskell alignments
|
||||
}
|
||||
\newcommand{\@endhs}{%
|
||||
\egroup
|
||||
\@hsmathendorg
|
||||
}
|
||||
|
||||
% Displayed Haskell (environment `haskell' and `haskell*')
|
||||
%
|
||||
% There are two kind of preambles for \halign: \hs@preambleNorm is for
|
||||
% `amsmath' style alignments and \hs@preambleStar for `equation' style
|
||||
% alignments (but with an unbound number of columns to its right)
|
||||
%
|
||||
% We need #### to get a ## in the \edef building the \halign command.
|
||||
%
|
||||
% first the preambles (also used in \hs@align below):
|
||||
%
|
||||
\def\hs@preambleNorm{%
|
||||
\noexpand\<####\unskip\noexpand\>\hfil&&\noexpand%
|
||||
\<{}####\unskip\noexpand\>\hfil}
|
||||
\def\hs@preambleStar{%
|
||||
\noexpand\<####\unskip\noexpand\>\hfil&\hfil\noexpand%
|
||||
\<{}####\unskip{}\noexpand\>\hfil&&\noexpand\<{}####\noexpand\>\hfil}
|
||||
%
|
||||
% the environments:
|
||||
%
|
||||
\newenvironment{haskell}{%
|
||||
\@haskell\hs@preambleNorm}{%
|
||||
\@endhaskell
|
||||
}
|
||||
\newenvironment{haskell*}{%
|
||||
\@haskell\hs@preambleStar}{%
|
||||
\@endhaskell
|
||||
}
|
||||
%
|
||||
% auxiliary definition getting the preamble as its first argument and starting
|
||||
% the environment:
|
||||
%
|
||||
\def\@haskell#1{%
|
||||
\bgroup
|
||||
\vspace\abovedisplayskip
|
||||
\let\(=\@hsmath % Important when `\(' occurs after `&'!
|
||||
\edef\@preamble{%
|
||||
\halign\bgroup\hskip\hsmargin#1\cr}
|
||||
\@preamble
|
||||
}
|
||||
%
|
||||
% Auxiliary definition ending environment:
|
||||
%
|
||||
\def\@endhaskell{%
|
||||
\crcr\egroup
|
||||
\vspace\belowdisplayskip
|
||||
\egroup\noindent\ignorespaces\global\@ignoretrue%
|
||||
}
|
||||
|
||||
% single line comment and keyword style
|
||||
%
|
||||
\newcommand{\hscom}[1]{%
|
||||
\relax\(\quad\textnormal{--- #1}\)}
|
||||
\newcommand{\hskwd}[1]{%
|
||||
\mathbf{#1}}
|
||||
|
||||
% informal description
|
||||
%
|
||||
\newcommand{\hsinf}[1]{%
|
||||
\(\langle\textnormal{#1}\rangle\)}
|
||||
|
||||
% literals and some special symbols
|
||||
%
|
||||
\newcommand{\hschar}[1]{\textrm'\mathrm{#1}\textrm'} % character literals
|
||||
\newcommand{\hsstr}[1]{"\mathrm{#1}"} % strings literals
|
||||
\newcommand{\hsfrom}{\leftarrow} % <-
|
||||
|
||||
% aligned subphrases
|
||||
%
|
||||
% check for an optional star and combine prefix (in #1) with one of the two
|
||||
% preambles (with star means to center the material between the first and
|
||||
% second &)
|
||||
%
|
||||
\def\hs@align#1{%
|
||||
\@ifstar
|
||||
{\hs@align@pre{#1\hs@preambleStar}}%
|
||||
{\hs@align@pre{#1\hs@preambleNorm}}%
|
||||
}
|
||||
%
|
||||
% test for optional argument; #1: preamble
|
||||
%
|
||||
\def\hs@align@pre#1{%
|
||||
\@testopt{\hs@align@prealign#1}t}
|
||||
%
|
||||
% got all arguments, now for the real code; #1: preamble; #2: alignment;
|
||||
% #3: body (the material set by the \halign)
|
||||
%
|
||||
\def\hs@align@prealign#1[#2]#3{%
|
||||
\relax\(
|
||||
\edef\@preamble{%
|
||||
\halign\bgroup#1\cr}
|
||||
\if #2t\vtop \else \if#2b\vbox \else \vcenter \fi\fi
|
||||
\bgroup%
|
||||
\@preamble
|
||||
#3%
|
||||
\crcr\egroup%
|
||||
\egroup\)
|
||||
}
|
||||
%
|
||||
% user-level command: alignment without a prefix
|
||||
%
|
||||
\newcommand{\hsalign}{%
|
||||
\relax
|
||||
\hs@align\relax%
|
||||
}
|
||||
|
||||
% subphrase breaking the surrounding alignment being flushed left
|
||||
%
|
||||
\newcommand{\hsnoalign}[1]{%
|
||||
\noalign{%
|
||||
\hs@align{\hskip\hsmargin}{#1}%
|
||||
}%
|
||||
}
|
||||
|
||||
% body expression breaking the surrounding alignment
|
||||
%
|
||||
% * setting \hsmargin to 0pt within the preamble (and _after_ it is used in
|
||||
% the preamble) is crucial, as we want \hsmargin only to be applied in
|
||||
% _outermost_ alignments
|
||||
%
|
||||
\newcommand{\hsbody}[1]{%
|
||||
{}\\
|
||||
\noalign{%
|
||||
\hs@align{\hskip\hsmargin\quad\hsmargin0pt}{#1}%
|
||||
}%
|
||||
}
|
||||
|
||||
|
||||
%% Defining commands for use in the Haskell mode
|
||||
%% =============================================
|
||||
%%
|
||||
%% We use some of the low-level machinery defined in LaTeX's source file
|
||||
%% `ltdefns.dtx'.
|
||||
%%
|
||||
%% \hscommand is similar to \newcommand, but there is no *-version.
|
||||
%%
|
||||
%% We use our own definitions here to insert a strategic `\relax' (see below)
|
||||
%% and to obey spaces within the bodies of Haskell definitions.
|
||||
|
||||
\newcommand{\hscommand}[1]{\@testopt{\hs@newcommand#1}0}
|
||||
\def\hs@newcommand#1[#2]{%
|
||||
\obeyspaces % spaces count in Haskell macros
|
||||
\@ifnextchar [{\hs@xargdef#1[#2]}%
|
||||
{\hs@argdef#1[#2]}}
|
||||
|
||||
% All this trouble only to be able to add the `\relax' into the expansion
|
||||
% process. If we don't that, commands without optional arguments when
|
||||
% invoked after an alignment character & don't work properly (actually, the
|
||||
% \obeyspaces doesn't work). I am sure that has to do with the scanning for
|
||||
% \omit etc in \halign (TeXbook, p240), but I don't understand yet why it
|
||||
% is problematic in this case.
|
||||
%
|
||||
% Furthermore, we switch off \obeyspaces in the end.
|
||||
%
|
||||
\long\def\hs@argdef#1[#2]#3{%
|
||||
\@ifdefinable#1{%
|
||||
\expandafter\def\expandafter#1\expandafter{%
|
||||
\relax % in order to stop token expansion after &
|
||||
\csname\string#1\expandafter\endcsname}%
|
||||
\expandafter\@yargdef
|
||||
\csname\string#1\endcsname
|
||||
\@ne
|
||||
{#2}%
|
||||
{#3}}%
|
||||
\catcode`\ =10% % stop obeying spaces now
|
||||
}
|
||||
|
||||
% Switch off \obeyspaces in the end.
|
||||
%
|
||||
\long\def\hs@xargdef#1[#2][#3]#4{%
|
||||
\@ifdefinable#1{%
|
||||
\expandafter\def\expandafter#1\expandafter{%
|
||||
\expandafter
|
||||
\@protected@testopt
|
||||
\expandafter
|
||||
#1%
|
||||
\csname\string#1\expandafter\endcsname
|
||||
{#3}}%
|
||||
\expandafter\@yargdef
|
||||
\csname\string#1\endcsname
|
||||
\tw@
|
||||
{#2}%
|
||||
{#4}}%
|
||||
\catcode`\ =10% % stop obeying spaces now
|
||||
}
|
||||
|
||||
|
||||
%% Abbreviations
|
||||
%% =============
|
||||
|
||||
% infix operators
|
||||
%
|
||||
\newcommand{\hsapp}{\mathbin{+\mkern-7mu+}}
|
||||
\newcommand{\hsifix}[1]{\mathbin{\string`#1\string`}}
|
||||
|
||||
% let expression
|
||||
%
|
||||
\hscommand{\hslet}[3][t]{%
|
||||
\hsalign[#1]{%
|
||||
\hskwd{let}\\
|
||||
\quad\hsalign{#2}\\
|
||||
\hskwd{in}\\
|
||||
#3
|
||||
}%
|
||||
}
|
||||
|
||||
% if expression
|
||||
%
|
||||
\hscommand{\hsif}[4][t]{%
|
||||
\hsalign[#1]{%
|
||||
\hskwd{if} #2 \hskwd{then}\\
|
||||
\quad\hsalign{#3}\\
|
||||
\hskwd{else}\\
|
||||
\quad\hsalign{#4}%
|
||||
}%
|
||||
}
|
||||
|
||||
% case expression
|
||||
%
|
||||
\hscommand{\hscase}[3][t]{%
|
||||
\hsalign[#1]{%
|
||||
\hskwd{case} #2 \hskwd{of}\\
|
||||
\quad\hsalign{#3}%
|
||||
}%
|
||||
}
|
||||
|
||||
% where clause
|
||||
%
|
||||
% * it is important to take the \quad into the preamble, so that nested
|
||||
% \noaligns can break it
|
||||
%
|
||||
\hscommand{\hswhere}[1]{%
|
||||
\hsbody{%
|
||||
\hskwd{where}\\
|
||||
\hs@align{\quad}{#1}%
|
||||
}%
|
||||
}
|
||||
|
||||
% do expression
|
||||
%
|
||||
\hscommand{\hsdo}[2][t]{%
|
||||
\hsalign[#1]{%
|
||||
\hskwd{do}\\
|
||||
\quad\hsalign{#2}\\
|
||||
}%
|
||||
}
|
||||
|
||||
|
||||
%% Extensions for Distributed Haskell (Goffin)
|
||||
%% ===========================================
|
||||
%%
|
||||
%% These definitions may change in the future.
|
||||
|
||||
\hscommand{\hsunif}{\mathbin{:=:}}
|
||||
\hscommand{\hsalias}{\mathrel{\sim}}
|
||||
\hscommand{\hsoutof}{\twoheadleftarrow}
|
||||
\hscommand{\hsinto}{\twoheadrightarrow}
|
||||
\hscommand{\hsparc}{\binampersand}
|
||||
\hscommand{\hsseq}{\Longrightarrow}
|
||||
\hscommand{\hsex}[2]{{\hskwd{ex} #1 \hskwd{in} #2}}
|
||||
|
||||
\hscommand{\hsexin}[3][t]{%
|
||||
\hsalign[#1]{%
|
||||
\hskwd{ex} #2 \hskwd{in}\\
|
||||
\quad\hsalign{#3}\\
|
||||
}%
|
||||
}
|
||||
|
||||
\hscommand{\hschoice}[2][t]{%
|
||||
\hsalign[#1]{%
|
||||
\hskwd{choice}\\
|
||||
\quad\hsalign{#2}\\
|
||||
}%
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user