Ticket #122: unlit.hs

File unlit.hs, 1.8 KB (added by igloo@…, 6 years ago)

untested proposed reference unlitter

Line 
1
2import Data.Char
3
4main :: IO ()
5main = do xs <- getContents
6          putStr $ unlines $ unlit BirdAllowed $ lines xs
7
8data State = InCode | InBird | BirdAllowed | BirdNotAllowed
9data LineType = BeginCode | EndCode | BirdTrack String | Blank | Normal
10
11unlit :: State -> [String] -> [String]
12unlit InCode [] = error "File ended in a code block"
13unlit _      [] = []
14unlit s (x:xs)
15 = case (lineType x, s) of
16   -- First deal with code blocks
17   (BeginCode,    InCode)         -> error "Can't nest code blocks"
18   (BeginCode,    _)              -> unlit InCode              xs
19   (EndCode,      InCode)         -> unlit BirdAllowed         xs
20   (EndCode,      _)              -> error "Closing non-existent code block"
21   (_,            InCode)         -> x  : unlit InCode         xs
22   -- Now deal with bird tracks
23   (BirdTrack _,  BirdNotAllowed) -> error "Bird track next to stuff"
24   (BirdTrack x', _)              -> x' : unlit InBird         xs
25   (Normal,       InBird)         -> error "Bird track next to stuff"
26   (Normal,       _)              ->      unlit BirdNotAllowed xs
27   (Blank,        _)              ->      unlit BirdAllowed    xs
28
29lineType :: String -> LineType
30lineType x
31 | x `starts` "\\begin{code}" = BeginCode
32 | x `starts` "\\end{code}"   = EndCode
33 | all isSpace x              = Blank
34lineType ('>':x')             = BirdTrack (' ':x')
35lineType _                    = Normal
36
37starts :: String -> String -> Bool
38x `starts` pref = case x `stripPrefix` pref of
39                  Just s
40                   | all isSpace s -> True
41                   | otherwise -> error ("Trailing characters after " ++ pref)
42                  Nothing -> False
43
44stripPrefix :: Eq a => [a] -> [a] -> Maybe [a]
45xs `stripPrefix` [] = Just xs
46[] `stripPrefix` _ = Nothing
47(x:xs) `stripPrefix` (y:ys)
48 | x == y = xs `stripPrefix` ys
49 | otherwise = Nothing