wikiPage :: Parser WikiPage
-wikiPage = do xs <- many (try wikiElement)
- skipMany comment
+wikiPage = do xs <- many (try blockElement)
+ skipMany ( comment
+ <|>
+ (newline >> return ())
+ )
eof
return xs
-wikiElement :: Parser WikiElement
-wikiElement = skipMany comment >>
- ( try (blockElement >>= return . Block)
- <|>
- try (inlineElement >>= return . Inline)
- )
-
-
blockElement :: Parser BlockElement
-blockElement = ( try heading
+blockElement = skipMany ( comment
+ <|>
+ (newline >> return ())
+ )
+ >>
+ ( heading
<|>
- try emptyLine
+ paragraph
)
heading :: Parser BlockElement
-heading = foldr (<|>) pzero (map (try . heading') [1..5])
+heading = foldr (<|>) pzero (map heading' [1..5])
<?>
"heading"
where
heading' :: Int -> Parser BlockElement
- heading' n = do count n (char '=')
- notFollowedBy (char '=')
+ heading' n = do try $ do count n (char '=')
+ notFollowedBy (char '=')
ws
x <- notFollowedBy (char '=') >> anyChar
- xs <- manyTill anyChar (try $ ws >> (count n (char '=')))
+ xs <- manyTill anyChar (try $ ws >> ( count n (char '=')
+ <?>
+ ("trailing " ++ take n (repeat '='))
+ )
+ )
ws
eol
return (Heading n (x:xs))
-emptyLine :: Parser BlockElement
-emptyLine = count 2 newline >> many newline >> return EmptyLine
- <?>
- "empty line"
+paragraph :: Parser BlockElement
+paragraph = paragraph' >>= return . Paragraph
+ where
+ paragraph' :: Parser [InlineElement]
+ paragraph' = do x <- inlineElement
+ xs <- try ( do newline
+ eof
+ return []
+ -- \n で文字列が終はってゐたら、ここ
+ -- で終了。
+ )
+ <|>
+ try ( do newline
+ ((oneOf ('\n':blockSymbols) >> pzero) <|> return ())
+ ys <- (paragraph' <|> return [])
+ return (Text "\n" : ys)
+ -- \n があり、その次に \n または
+ -- blockSymbols があれば、fail して
+ -- 最初の newline を讀んだ所まで卷き
+ -- 戻す。
+ )
+ <|>
+ try paragraph'
+ -- それ以外の場合は次の inlineElement から
+ -- を讀んで見る。但し一つも無くても良い。
+ <|>
+ return [] -- 全部失敗したらここで終了。
+ return (x:xs)
inlineElement :: Parser InlineElement
-inlineElement = ( try text
+inlineElement = skipMany comment
+ >>
+ ( try text
<|>
try pageLink
)
text :: Parser InlineElement
-text = text' >>= return . Text
- where
- text' :: Parser String
- text' = do x <- noneOf inlineSymbols
- case x of
- -- 單獨の \n は受け入れる。
- '\n' -> return [x]
- -- それ以外では \n を受け入れない。
- _ -> many (noneOf ('\n':inlineSymbols)) >>= return . (x:)
+text = many1 (noneOf ('\n':inlineSymbols)) >>= return . Text
pageLink :: Parser InlineElement
)
+blockSymbols :: [Char]
+blockSymbols = "="
+
+
inlineSymbols :: [Char]
inlineSymbols = "<["
-- end of line
eol :: Parser ()
-eol = ( (many1 newline >> return ())
+eol = ( (newline >> return ())
<|>
eof
)