git.iko.soy/typeable/pandoc
on master help sign in
Slides: New approach, using hierarchicalize.

This will work better with the HTML slideshows.

commit0fd0dc23449165280add5d145a13c39422874432 authorJohn MacFarlane <fiddlosopher@gmail.com> dateMon 23 Jan 2012, 23:02 (15 years ago) parent228c76b
2 files changed+44−67
src/Text/Pandoc/Slides.hs+13−44 src/Text/Pandoc/Writers/LaTeX.hs+31−23
src/Text/Pandoc/Slides.hs+13−44
@@ -28,51 +28,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2828Utility functions for splitting documents into slides for slide
2929show formats (dzslides, s5, slidy, beamer).
3030-}
31−module Text.Pandoc.Slides ( toSlideElements, SlideElement(..) ) where
31+module Text.Pandoc.Slides ( getSlideLevel, prepSlides ) where
3232import Text.Pandoc.Definition
33−import Text.ParserCombinators.Parsec
34−import Text.Parsec.Pos (initialPos)
35−import Control.Monad
36−
37−data SlideElement = SectionSlide Int [Inline]
38− | ContentSlide [Inline] [Block] -- title - contents
39− deriving (Read, Show)
40−
41−toSlideElements :: [Block] -> [SlideElement]
42−toSlideElements bs =
43− case parse (pElements $ getSlideLevel bs) "blocks" bs of
44− Left err -> error $ "toSlideElements: " ++ show err -- should never happen
45− Right res -> res
46−
47−satisfies :: (Block -> Bool) -> GenParser Block () Block
48−satisfies f = token show (const $ initialPos "blocks")
49− (\x -> if f x then Just x else Nothing)
50−
51−pElements :: Int -> GenParser Block () [SlideElement]
52−pElements slideLevel = do
53− res <- many (pSectionSlide slideLevel <|> pContentSlide slideLevel)
54− eof
55− return res
56−
57−pContentSlide :: Int -> GenParser Block () SlideElement
58−pContentSlide slideLevel = try $ do
59− hrs <- many $ satisfies (== HorizontalRule)
60− Header _ tit <- option (Header 1 []) $ satisfies (isHeader (== slideLevel))
61− xs <- many $ try $ notFollowedBy (satisfies (== HorizontalRule)) >>
62− notFollowedBy (satisfies (isHeader (<= slideLevel))) >>
63− anyToken
64− guard $ not (null hrs && null tit && null xs) -- make sure we can't match empty
65− return $ ContentSlide tit xs
66−
67−pSectionSlide :: Int -> GenParser Block () SlideElement
68−pSectionSlide slideLevel = try $ do
69− skipMany $ satisfies (== HorizontalRule)
70− Header lvl txt <- satisfies (isHeader (< slideLevel))
71− return $ SectionSlide lvl txt
72−
73−isHeader :: (Int -> Bool) -> Block -> Bool
74−isHeader f (Header n _) = f n
75−isHeader _ _ = False
7633
7734-- | Find level of header that starts slides (defined as the least header
7835-- level that occurs before a non-header/non-hrule in the blocks).
@@ -86,3 +43,15 @@ getSlideLevel = go 6
8643 nonHOrHR (Header _ _) = False
8744 nonHOrHR (HorizontalRule) = False
8845 nonHOrHR _ = True
46+
47+-- | Prepare a block list to be passed to hierarchicalize.
48+prepSlides :: Int -> [Block] -> [Block]
49+prepSlides slideLevel = ensureStartWithH . splitHrule
50+ where splitHrule (HorizontalRule : Header n xs : ys)
51+ | n == slideLevel = Header slideLevel xs : splitHrule ys
52+ splitHrule (HorizontalRule : xs) = Header slideLevel [] : splitHrule xs
53+ splitHrule (x : xs) = x : splitHrule xs
54+ splitHrule [] = []
55+ ensureStartWithH bs@(Header n _:_)
56+ | n == slideLevel = bs
57+ ensureStartWithH bs = Header slideLevel [] : bs
src/Text/Pandoc/Writers/LaTeX.hs+31−23
@@ -200,29 +200,37 @@ inCmd :: String -> Doc -> Doc
200200inCmd cmd contents = char '\\' <> text cmd <> braces contents
201201
202202toSlides :: [Block] -> State WriterState [Block]
203−toSlides bs = concat `fmap` (mapM slideToBeamer $ toSlideElements bs)
204−
205−slideToBeamer :: SlideElement -> State WriterState [Block]
206−slideToBeamer (SectionSlide lvl tit) = return [Header lvl tit]
207−slideToBeamer (ContentSlide tit bs) = do
208− tit' <- inlineListToLaTeX tit
209− -- note: [fragile] is required or verbatim breaks
210− let hasCodeBlock (CodeBlock _ _) = [True]
211− hasCodeBlock _ = []
212− let hasCode (Code _ _) = [True]
213− hasCode _ = []
214− let fragile = if not $ null $ queryWith hasCodeBlock bs ++ queryWith hasCode bs
215− then "[fragile]"
216− else ""
217− let slideStart = RawBlock "latex" ("\\begin{frame}" ++ fragile ++
218− "\\frametitle{" ++ render Nothing tit' ++ "}")
219− let slideEnd = RawBlock "latex" "\\end{frame}"
220− -- now carve up slide into blocks if there are sections inside
221− let eltToBlocks (Blk b) = [b]
222− eltToBlocks (Sec _ _ _ lab xs) =
223− Para (RawInline "latex" "\\begin{block}{" : lab ++ [RawInline "latex" "}"])
224− : concatMap eltToBlocks xs ++ [RawBlock "latex" "\\end{block}"]
225− return $ slideStart : concatMap eltToBlocks (hierarchicalize bs) ++ [slideEnd]
203+toSlides bs = do
204+ let slideLevel = getSlideLevel bs
205+ let bs' = prepSlides slideLevel bs
206+ concat `fmap` (mapM (elementToBeamer slideLevel) $ hierarchicalize bs')
207+
208+elementToBeamer :: Int -> Element -> State WriterState [Block]
209+elementToBeamer _slideLevel (Blk b) = return [b]
210+elementToBeamer slideLevel (Sec lvl _num _ident tit elts)
211+ | lvl > slideLevel = do
212+ bs <- concat `fmap` mapM (elementToBeamer slideLevel) elts
213+ return $ Para ( RawInline "latex" "\\begin{block}{"
214+ : tit ++ [RawInline "latex" "}"] )
215+ : bs ++ [RawBlock "latex" "\\end{block}"]
216+ | lvl < slideLevel = do
217+ bs <- concat `fmap` mapM (elementToBeamer slideLevel) elts
218+ return $ (Header lvl tit) : bs
219+ | otherwise = do -- lvl == slideLevel
220+ -- note: [fragile] is required or verbatim breaks
221+ let hasCodeBlock (CodeBlock _ _) = [True]
222+ hasCodeBlock _ = []
223+ let hasCode (Code _ _) = [True]
224+ hasCode _ = []
225+ let fragile = if not $ null $ queryWith hasCodeBlock elts ++ queryWith hasCode elts
226+ then "[fragile]"
227+ else ""
228+ let slideStart = Para $ RawInline "latex" ("\\begin{frame}" ++ fragile ++
229+ "\\frametitle{") : tit ++ [RawInline "latex" "}"]
230+ let slideEnd = RawBlock "latex" "\\end{frame}"
231+ -- now carve up slide into blocks if there are sections inside
232+ bs <- concat `fmap` mapM (elementToBeamer slideLevel) elts
233+ return $ slideStart : bs ++ [slideEnd]
226234
227235isListBlock :: Block -> Bool
228236isListBlock (BulletList _) = True