@@ -1,5 +1,6 @@
11module Parse.Helpers where
22
3+import Prelude hiding (until)
34import Control.Applicative ((<$>),(<*>))
45import Control.Monad
56import Control.Monad.State
@@ -237,17 +238,36 @@ closeComment =
237238 , concat <$> sequence [ try (string "{-"), closeComment, closeComment ]
238239 ]
239240
241+until :: IParser a -> IParser b -> IParser b
242+until p end = go
243+ where
244+ go = end <|> (p >> go)
245+
240246anyUntil :: IParser String -> IParser String
241247anyUntil end = go
242248 where
243249 go = end <|> (:) <$> anyChar <*> go
244250
245−anyThen :: IParser a -> IParser a
246−anyThen end = go
251+ignoreUntil :: IParser a -> IParser (Maybe a)
252+ignoreUntil end = go
247253 where
248254 ignore p = const () <$> p
249− go = end <|> do ignore multiComment <|> ignore anyChar
250− go
255+ filler = choice [ ignore multiComment
256+ , ignore (markdown (\_ _ -> mzero))
257+ , ignore anyChar
258+ ]
259+ go = choice [ Just <$> end
260+ , filler `until` choice [ const Nothing <$> eof, newline >> go ]
261+ ]
262+
263+onFreshLines :: (a -> b -> b) -> b -> IParser a -> IParser b
264+onFreshLines insert init thing = go init
265+ where
266+ go values = do
267+ optionValue <- ignoreUntil thing
268+ case optionValue of
269+ Nothing -> return values
270+ Just v -> go (insert v values)
251271
252272withSource :: IParser a -> IParser (String, a)
253273withSource p = do
@@ -266,3 +286,13 @@ anyUntilPos pos = go
266286 True -> return []
267287 False -> (:) <$> anyChar <*> go
268288
289+markdown :: (String -> [a] -> IParser (String, [a])) -> IParser (String, [a])
290+markdown interpolation = try (string "[markdown|") >> closeMarkdown "" []
291+ where
292+ closeMarkdown md stuff =
293+ choice [ do try (string "|]")
294+ return (md, stuff)
295+ , uncurry closeMarkdown =<< interpolation md stuff
296+ , do c <- anyChar
297+ closeMarkdown (md ++ [c]) stuff
298+ ]