1 module Rakka.Wiki.Parser
7 import Text.ParserCombinators.Parsec
10 wikiPage :: Parser WikiPage
11 wikiPage = do xs <- many (try wikiElement)
17 wikiElement :: Parser WikiElement
18 wikiElement = skipMany comment >>
19 ( try (blockElement >>= return . Block)
21 try (inlineElement >>= return . Inline)
25 blockElement :: Parser BlockElement
26 blockElement = ( try heading
32 heading :: Parser BlockElement
33 heading = foldr (<|>) pzero (map (try . heading') [1..5])
37 heading' :: Int -> Parser BlockElement
38 heading' n = do count n (char '=')
39 notFollowedBy (char '=')
41 x <- notFollowedBy (char '=') >> anyChar
42 xs <- manyTill anyChar (try $ ws >> (count n (char '=')))
45 return (Heading n (x:xs))
48 emptyLine :: Parser BlockElement
49 emptyLine = count 2 newline >> many newline >> return EmptyLine
54 inlineElement :: Parser InlineElement
55 inlineElement = ( try text
61 text :: Parser InlineElement
62 text = text' >>= return . Text
64 text' :: Parser String
65 text' = do x <- noneOf inlineSymbols
70 _ -> many (noneOf ('\n':inlineSymbols)) >>= return . (x:)
73 pageLink :: Parser InlineElement
74 pageLink = do string "[["
75 page <- option Nothing
76 (many1 (noneOf "#|]") >>= return . Just)
77 fragment <- option Nothing
78 (char '#' >> many1 (noneOf "|]") >>= return . Just)
79 text <- option Nothing
80 (char '|' >> many1 (noneOf "]") >>= return . Just)
82 case (page, fragment) of
83 (Nothing, Nothing) -> pzero
87 return $ PageLink page fragment text
93 comment = (try (string "<!--") >> skipTillEnd 1)
97 skipTillEnd :: Int -> Parser ()
98 skipTillEnd level = ( (try (string "<!--") >> skipTillEnd (level + 1))
100 (try (string "-->") >> case level of
102 n -> skipTillEnd (n - 1))
104 (anyChar >> skipTillEnd level)
108 inlineSymbols :: [Char]
113 ws = skipMany ( (oneOf " \t" >> return ())
120 eol = ( (many1 newline >> return ())