lhs2tex-1.21: src/Typewriter.lhs
%-------------------------------= --------------------------------------------
\subsection{Typewriter formatter}
%-------------------------------= --------------------------------------------
%if codeOnly || showModuleHeader
> module Typewriter ( module Typewriter )
> where
>
> import Control.Monad
>
> import Verbatim ( trim, expand )
> import Document
> import Directives
> import HsLexer
> import qualified FiniteMap as FM
> import Auxiliaries
> import TeXCommands ( Lang (..) )
%endif
% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -
\subsubsection{Inline and display code}
% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -
> inline, display :: Lang -> Formats -> String -> Either Exc Doc
> inline lang dict = tokenize lang
> >=> lift (latexs sub'thin sub'thin dict)
> >=> lift sub'inline
> display lang dict = lift trim
> >=> lift (expand 0)
> >=> tokenize lang
> >=> lift (latexs sub'space sub'nl dict)
> >=> lift sub'code
% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -
\subsubsection{\LaTeX\ encoding}
% - - - - - - - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - -
> latexs :: Doc -> Doc -> Formats -> [Token] -> Doc
> latexs sp nl dict = catenate . map (latex sp nl dict)
>
> latex :: Doc -> Doc -> Formats -> Token -> Doc
> latex sp nl dict = tex Empty
> where
> tex _ (Space s) = sub'spaces (convert False s)
> tex q (Conid s) = replace q s (sub'conid (q <<>> convert False s))
> tex _ (Varid "") = sub'dummy -- HACK
> tex q (Varid s) = replace q s (sub'varid (q <<>> convert False s))
> tex q (Consym s) = replace q s (sub'consym (q <<>> convert False s))
> tex q (Varsym s) = replace q s (sub'varsym (q <<>> convert False s))
> tex _ (Numeral s) = replace Empty s (sub'numeral (convert True s)) -- NEU
> tex _ (Char s) = sub'char (catenate (map conv' (init $ tail s))) -- NEW: remove quotes
> tex _ (String s) = sub'string (catenate (map conv' (init $ tail s))) -- NEW: remove quotes
> tex _ (Special c) = sub'special (replace Empty [c] (conv False c))
> tex _ (Comment s) = sub'comment (Embedded s)
> tex _ (Nested s) = sub'nested (Embedded s)
> tex _ (Pragma s) = sub'pragma (Embedded s)
> tex _ (Keyword s) = replace Empty s (sub'keyword (convert False s))
> tex _ (TeX False d) = d
> tex _ (TeX True d) = sub'tex d
> tex _ t@(Qual ms t') = replace Empty (string t) (tex (catenate (map (\m -> tex Empty (Conid m) <<>> Text ".") ms)) t')
> tex _ t@(Op t') = replace Empty (string t) (sub'backquoted (tex Empty t'))
>
> replace q s def = case FM.lookup s dict of
> Just (_, _, [], ts) -> q <<>> catenate (map (tex Empty) ts)
> _ -> def
\NB the directives @%format a = b@ and @%format b = a@ cause a loop.
\NB Only nullary macros are applied.
Conversion of strings and characters. The Boolean indicates whether we
want to convert a numeric literal which could contain an exponent.
> convert :: Bool -> String -> Doc
> convert isNum s = catenate (map (conv isNum) s)
> conv :: Bool -> Char -> Doc
> conv _ ' ' = sp
> conv _ '\n' = nl
> conv isNum c
> | c `elem` "#$%&" = Text ("\\" ++ [c])
> | c `elem` "\"\\^_{}~" = Text (char c)
> | isNum && c `elem` "-+"= Text ("{" ++ [c] ++ "}")
> | otherwise = Text [c]
>
> conv' ' ' = Text "~" -- NEW: instead of |Text (char ' ')| -- for character and string literals
> conv' c = conv False c
\NB The character @"@ is not copied verbatim, to be able to use
@german.sty@ (@"@ is made active).
\NB The coding of characters is not independent of the \TeX\ font used,
eg @\/@ appears different in italics and typewriter (@\@ is
\texttt{\char'134} in typewriter, but \textit{\char'134} in italics).
> char :: Char -> String
> char c = "\\char" ++ show (fromEnum c) ++ " "