content: % lhs2TeX -math -align 33 Unlit.lhs > Unlit.tex
  
  \documentclass{article}
  \usepackage[german]{babel}
  
  %-------------------------------=  --------------------------------------------
  
  %include ../lhs2TeX.sty
  %include ../lhs2TeX.fmt
  
  %-------------------------------=  --------------------------------------------
  
  \begin{document}
  
  %-------------------------------=  --------------------------------------------
  \section{\texttt{unlit}}
  %-------------------------------=  --------------------------------------------
  
  Literate-Skripte, die Bird-Tracks verwenden, in Skripte "uberf"uhren,
  die die Pseudo-\TeX-Kommandos \verb|\begin{code}|, \verb|\end{code}|
  verwenden. Das Programm realisiert einen einfachen UNIX-Filter.
  
  Synopsis:
  %
  \begin{verbatim}
  unlit
  unlit <file>
  \end{verbatim}
  
  %-------------------------------=  --------------------------------------------
  
  %if code || showModuleHeader
  
  > module Main			(  main  )
  > where
  >
  > import Char			(  isSpace  )
  > import System			(  getArgs  )
  > import Auxiliaries		(  (.>)  )
  
  %endif
  
  > data Class			=  Program LineNo Line
  >				|  Spec    LineNo Line
  >				|  Blank   LineNo Line
  >				|  Comment LineNo Line
  >
  > type LineNo			=  Int
  > type Line			=  String
  
  > beginCode, endCode, 
  >     beginSpec, endSpec	:: Line
  > beginCode			=  "\\begin{code}"
  > endCode			=  "\\end\&{code}"
  > beginSpec			=  "\\begin{spec}"
  > endSpec			=  "\\end{spec}"
  
  \NB Damit \verb|"\\end{code}"| nicht das Codesegment beendet, wird ein
  Nullstring eingef"ugt: \verb|"\\end\&{code}"|.
  
  > main				:: IO ()
  > main				=  do args <- getArgs
  >				      unlit args
  >
  > unlit []			=  getContents       >>= (putStr . convert)
  > unlit (filePath : _)		=  readFile filePath >>= (putStr . convert)
  
  Fehlt: Fehlerbehandlung, wenn die Datei nicht vorhanden oder nicht
  lesbar ist.
  
  > convert			:: String -> String
  > convert			=  lines
  >				.> zip [1 ..]		-- number
  >				.> map classify
  >				.> format
  >				.> unlines
  
  > classify			:: (LineNo, Line) -> Class
  > classify (n, '>' : s)		=  Program n (' ' : s)
  > classify (n, '<' : s)		=  Spec    n (' ' : s)
  > classify (n, s)
  >     | all isSpace s		=  Blank   n s
  > classify (n, s)		=  Comment n s
  
  Die Formatierung wird mit einem einfachen endlichen Automaten mit f"unf
  Zust"anden vorgenommen. Es wird darauf geachtet, da"s die Anzahl der
  Zeilen nicht ver"andert wird.
  
  > format			:: [Class] -> [Line]
  > format []			=  []
  > format (Program _ a : x)	=  (beginCode ++ a) : inProgram x
  > format (Spec    _ a : x)	=  (beginSpec ++ a) : inSpec    x
  > format (Blank   _ a : x)	=                     inBlank a x
  > format (Comment _ a : x)	=                 a : inComment x
  
  > inBlank			:: Line -> [Class] -> [Line]
  > inBlank a []			=  [a]
  > inBlank a (Program _ b : x)	=  beginCode : b : inProgram x
  > inBlank a (Spec    _ b : x)	=  beginSpec : b : inSpec    x
  > inBlank a (Blank   _ b : x)	=          a :     inBlank b x
  > inBlank a (Comment _ b : x)	=          a : b : inComment x
  
  > inProgram			:: [Class] -> [Line]
  > inProgram []			=  [ endCode ]
  > inProgram (Program _ a : x)	=            a : inProgram x
  > inProgram (Spec    n a : x)	=  message n "program line" "specification line"
  > inProgram (Blank   _ a : x)	=  endCode     : format    x
  > inProgram (Comment n a : x)	=  message n "program line" "comment"
  
  > inSpec			:: [Class] -> [Line]
  > inSpec []			=  [ endSpec ]
  > inSpec (Program n a : x)	=  message n "specification line" "program line"
  > inSpec (Spec    _ a : x)	=            a : inSpec x
  > inSpec (Blank   _ a : x)	=  endSpec     : format x
  > inSpec (Comment n a : x)	=  message n "specification line" "comment"
  
  > inComment			:: [Class] -> [Line]
  > inComment []			=  []
  > inComment (Program n a : x)	=  message n "comment" "program line"
  > inComment (Spec    n a : x)	=  message n "comment" "specification line"
  > inComment (Blank   _ a : x)	=      inBlank   a x
  > inComment (Comment _ a : x)	=  a : inComment x
  
  > message			:: LineNo -> String -> String -> a
  > message n x y			=  error ("line " ++ show n ++ ": "
  >				++ x ++ " next to " ++ y ++ "\n")
  
  \end{document}
  