module S09 (
lexer,
showXml,
uibkMail,
parseIntList,
select
) where
import Xml hiding (lexer)
import Parse
optional :: Parser t a -> Parser t ()
optional p = (p >> return ()) <|> return ()
lexer :: Parser Char [Token]
lexer = do
many space
optional parseProlog
many space
ts <- many (parseTag <|> parseComment <|> parseText)
eoi
return ts
where
parseProlog = string "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
showXml :: Xml -> String
showXml = tos 0
where
tos i (Txt t) = unlines $ map (replicate i ' ' ++) $ lines t
tos i (Xml t ns) =
indent ++ "<" ++ t ++ ">\n" ++
concat (map (tos (i + 1)) ns) ++
indent ++ "</" ++ t ++ ">\n"
where
indent = replicate i ' '
uibkMail :: String -> Maybe (String, String)
uibkMail = parse p
where
p = do
forename <- many1 (noneof ".")
char '.'
surname <- many1 (noneof "@")
char '@'
optional (string "student.")
string "uibk.ac.at"
return (forename, surname)
sepBy, sepBy1 :: Parser t a -> Parser t b -> Parser t [a]
sepBy1 p s = do { x <- p; xs <- many (s >> p); return (x:xs) }
sepBy p s = sepBy1 p s <|> return []
parseIntList :: Parser Char [Int]
parseIntList = between (char '[') (char ']') $
parseInt `sepBy` char ','
where
parseInt = many1 digit >>= return . read
select :: Tag -> Xml -> [Xml]
select s x@(Xml t xs)
| s == t = [x]
| otherwise = concat (map (select s) xs)
select _ _ = []