content: %-------------------------------=  --------------------------------------------
  \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) ++ " "
  