@@ -29,6 +29,49 @@ Utility functions for splitting documents into slides for slide
2929show formats (dzslides, s5, slidy, beamer).
3030-}
3131module Text.Pandoc.Slides ( ) where
32+import Text.Pandoc.Definition
33+import Text.ParserCombinators.Parsec
34+import Text.Parsec.Pos (initialPos)
3235
36+data SlideElement = Outside Block
37+ | Slide [Inline] [Inline] [Block] -- title - subtitle - contents
38+ deriving (Read, Show)
3339
40+toSlideElements :: [Block] -> [SlideElement]
41+toSlideElements bs =
42+ case parse (pElements $ getSlideLevel bs) "blocks" bs of
43+ Left err -> map Outside bs
44+ Right res -> res
3445
46+anyTok :: GenParser Block () Block
47+anyTok = token show (const $ initialPos "blocks") Just
48+
49+satisfies :: (Block -> Bool) -> GenParser Block () Block
50+satisfies f = token show (const $ initialPos "blocks")
51+ (\x -> if f x then Just x else Nothing)
52+
53+pElements :: Int -> GenParser Block () [SlideElement]
54+pElements slideLevel = do
55+ res <- many (pSlide slideLevel <|> pOutside)
56+ eof
57+ return res
58+
59+pSlide :: Int -> GenParser Block () SlideElement
60+pSlide slideLevel = try $ do
61+
62+
63+pOutside :: GenParser Block () SlideElement
64+pOutside = Outside `fmap` anyTok
65+
66+-- | Find level of header that starts slides (defined as the least header
67+-- level that occurs before a non-header/non-hrule in the blocks).
68+getSlideLevel :: [Block] -> Int
69+getSlideLevel = go 6
70+ where go least (Header n _ : x : xs)
71+ | n < least && nonHOrHR x = go n xs
72+ | otherwise = go least (x:xs)
73+ go least (x : xs) = go least xs
74+ go least [] = least
75+ nonHOrHR (Header _ _) = False
76+ nonHOrHR (HorizontalRule) = False
77+ nonHOrHR _ = True