{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Patat.Presentation.Read
( readPresentation
) where
import Control.Monad.Except (ExceptT (..), runExceptT,
throwError)
import Control.Monad.Trans (liftIO)
import qualified Data.Aeson as A
import qualified Data.HashMap.Strict as HMS
import Data.Maybe (fromMaybe)
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Data.Text.IO as T
import qualified Data.Yaml as Yaml
import Patat.Presentation.Fragment
import Patat.Presentation.Internal
import Prelude
import System.Directory (doesFileExist, getHomeDirectory)
import System.FilePath (takeExtension, (</>))
import qualified Text.Pandoc.Error as Pandoc
import qualified Text.Pandoc.Extended as Pandoc
readPresentation :: FilePath -> IO (Either String Presentation)
readPresentation :: FilePath -> IO (Either FilePath Presentation)
readPresentation filePath :: FilePath
filePath = ExceptT FilePath IO Presentation
-> IO (Either FilePath Presentation)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT FilePath IO Presentation
-> IO (Either FilePath Presentation))
-> ExceptT FilePath IO Presentation
-> IO (Either FilePath Presentation)
forall a b. (a -> b) -> a -> b
$ do
Text
src <- IO Text -> ExceptT FilePath IO Text
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Text -> ExceptT FilePath IO Text)
-> IO Text -> ExceptT FilePath IO Text
forall a b. (a -> b) -> a -> b
$ FilePath -> IO Text
T.readFile FilePath
filePath
PresentationSettings
homeSettings <- IO (Either FilePath PresentationSettings)
-> ExceptT FilePath IO PresentationSettings
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT IO (Either FilePath PresentationSettings)
readHomeSettings
PresentationSettings
metaSettings <- IO (Either FilePath PresentationSettings)
-> ExceptT FilePath IO PresentationSettings
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (IO (Either FilePath PresentationSettings)
-> ExceptT FilePath IO PresentationSettings)
-> IO (Either FilePath PresentationSettings)
-> ExceptT FilePath IO PresentationSettings
forall a b. (a -> b) -> a -> b
$ Either FilePath PresentationSettings
-> IO (Either FilePath PresentationSettings)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath PresentationSettings
-> IO (Either FilePath PresentationSettings))
-> Either FilePath PresentationSettings
-> IO (Either FilePath PresentationSettings)
forall a b. (a -> b) -> a -> b
$ Text -> Either FilePath PresentationSettings
readMetaSettings Text
src
let settings :: PresentationSettings
settings = PresentationSettings
metaSettings PresentationSettings
-> PresentationSettings -> PresentationSettings
forall a. Semigroup a => a -> a -> a
<> PresentationSettings
homeSettings PresentationSettings
-> PresentationSettings -> PresentationSettings
forall a. Semigroup a => a -> a -> a
<> PresentationSettings
defaultPresentationSettings
let pexts :: ExtensionList
pexts = ExtensionList -> Maybe ExtensionList -> ExtensionList
forall a. a -> Maybe a -> a
fromMaybe ExtensionList
defaultExtensionList (PresentationSettings -> Maybe ExtensionList
psPandocExtensions PresentationSettings
settings)
Text -> Either PandocError Pandoc
reader <- case ExtensionList
-> FilePath -> Maybe (Text -> Either PandocError Pandoc)
readExtension ExtensionList
pexts FilePath
ext of
Nothing -> FilePath -> ExceptT FilePath IO (Text -> Either PandocError Pandoc)
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (FilePath
-> ExceptT FilePath IO (Text -> Either PandocError Pandoc))
-> FilePath
-> ExceptT FilePath IO (Text -> Either PandocError Pandoc)
forall a b. (a -> b) -> a -> b
$ "Unknown file extension: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath -> FilePath
forall a. Show a => a -> FilePath
show FilePath
ext
Just x :: Text -> Either PandocError Pandoc
x -> (Text -> Either PandocError Pandoc)
-> ExceptT FilePath IO (Text -> Either PandocError Pandoc)
forall (m :: * -> *) a. Monad m => a -> m a
return Text -> Either PandocError Pandoc
x
Pandoc
doc <- case Text -> Either PandocError Pandoc
reader Text
src of
Left e :: PandocError
e -> FilePath -> ExceptT FilePath IO Pandoc
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (FilePath -> ExceptT FilePath IO Pandoc)
-> FilePath -> ExceptT FilePath IO Pandoc
forall a b. (a -> b) -> a -> b
$ "Could not parse document: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ PandocError -> FilePath
forall a. Show a => a -> FilePath
show PandocError
e
Right x :: Pandoc
x -> Pandoc -> ExceptT FilePath IO Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return Pandoc
x
IO (Either FilePath Presentation)
-> ExceptT FilePath IO Presentation
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (IO (Either FilePath Presentation)
-> ExceptT FilePath IO Presentation)
-> IO (Either FilePath Presentation)
-> ExceptT FilePath IO Presentation
forall a b. (a -> b) -> a -> b
$ Either FilePath Presentation -> IO (Either FilePath Presentation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath Presentation -> IO (Either FilePath Presentation))
-> Either FilePath Presentation
-> IO (Either FilePath Presentation)
forall a b. (a -> b) -> a -> b
$ FilePath
-> PresentationSettings -> Pandoc -> Either FilePath Presentation
pandocToPresentation FilePath
filePath PresentationSettings
settings Pandoc
doc
where
ext :: FilePath
ext = FilePath -> FilePath
takeExtension FilePath
filePath
readExtension
:: ExtensionList -> String
-> Maybe (T.Text -> Either Pandoc.PandocError Pandoc.Pandoc)
readExtension :: ExtensionList
-> FilePath -> Maybe (Text -> Either PandocError Pandoc)
readExtension (ExtensionList extensions :: Extensions
extensions) fileExt :: FilePath
fileExt = case FilePath
fileExt of
".md" -> (Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc)
forall a. a -> Maybe a
Just ((Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc))
-> (Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc)
forall a b. (a -> b) -> a -> b
$ PandocPure Pandoc -> Either PandocError Pandoc
forall a. PandocPure a -> Either PandocError a
Pandoc.runPure (PandocPure Pandoc -> Either PandocError Pandoc)
-> (Text -> PandocPure Pandoc) -> Text -> Either PandocError Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderOptions -> Text -> PandocPure Pandoc
forall (m :: * -> *).
PandocMonad m =>
ReaderOptions -> Text -> m Pandoc
Pandoc.readMarkdown ReaderOptions
readerOpts
".lhs" -> (Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc)
forall a. a -> Maybe a
Just ((Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc))
-> (Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc)
forall a b. (a -> b) -> a -> b
$ PandocPure Pandoc -> Either PandocError Pandoc
forall a. PandocPure a -> Either PandocError a
Pandoc.runPure (PandocPure Pandoc -> Either PandocError Pandoc)
-> (Text -> PandocPure Pandoc) -> Text -> Either PandocError Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderOptions -> Text -> PandocPure Pandoc
forall (m :: * -> *).
PandocMonad m =>
ReaderOptions -> Text -> m Pandoc
Pandoc.readMarkdown ReaderOptions
lhsOpts
"" -> (Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc)
forall a. a -> Maybe a
Just ((Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc))
-> (Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc)
forall a b. (a -> b) -> a -> b
$ PandocPure Pandoc -> Either PandocError Pandoc
forall a. PandocPure a -> Either PandocError a
Pandoc.runPure (PandocPure Pandoc -> Either PandocError Pandoc)
-> (Text -> PandocPure Pandoc) -> Text -> Either PandocError Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderOptions -> Text -> PandocPure Pandoc
forall (m :: * -> *).
PandocMonad m =>
ReaderOptions -> Text -> m Pandoc
Pandoc.readMarkdown ReaderOptions
readerOpts
".org" -> (Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc)
forall a. a -> Maybe a
Just ((Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc))
-> (Text -> Either PandocError Pandoc)
-> Maybe (Text -> Either PandocError Pandoc)
forall a b. (a -> b) -> a -> b
$ PandocPure Pandoc -> Either PandocError Pandoc
forall a. PandocPure a -> Either PandocError a
Pandoc.runPure (PandocPure Pandoc -> Either PandocError Pandoc)
-> (Text -> PandocPure Pandoc) -> Text -> Either PandocError Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderOptions -> Text -> PandocPure Pandoc
forall (m :: * -> *).
PandocMonad m =>
ReaderOptions -> Text -> m Pandoc
Pandoc.readOrg ReaderOptions
readerOpts
_ -> Maybe (Text -> Either PandocError Pandoc)
forall a. Maybe a
Nothing
where
readerOpts :: ReaderOptions
readerOpts = ReaderOptions
forall a. Default a => a
Pandoc.def
{ readerExtensions :: Extensions
Pandoc.readerExtensions =
Extensions
extensions Extensions -> Extensions -> Extensions
forall a. Semigroup a => a -> a -> a
<> Extensions
absolutelyRequiredExtensions
}
lhsOpts :: ReaderOptions
lhsOpts = ReaderOptions
readerOpts
{ readerExtensions :: Extensions
Pandoc.readerExtensions =
ReaderOptions -> Extensions
Pandoc.readerExtensions ReaderOptions
readerOpts Extensions -> Extensions -> Extensions
forall a. Semigroup a => a -> a -> a
<>
[Extension] -> Extensions
Pandoc.extensionsFromList [Extension
Pandoc.Ext_literate_haskell]
}
absolutelyRequiredExtensions :: Extensions
absolutelyRequiredExtensions =
[Extension] -> Extensions
Pandoc.extensionsFromList [Extension
Pandoc.Ext_yaml_metadata_block]
pandocToPresentation
:: FilePath -> PresentationSettings -> Pandoc.Pandoc
-> Either String Presentation
pandocToPresentation :: FilePath
-> PresentationSettings -> Pandoc -> Either FilePath Presentation
pandocToPresentation pFilePath :: FilePath
pFilePath pSettings :: PresentationSettings
pSettings pandoc :: Pandoc
pandoc@(Pandoc.Pandoc meta :: Meta
meta _) = do
let !pTitle :: [Inline]
pTitle = Meta -> [Inline]
Pandoc.docTitle Meta
meta
!pSlides :: [Slide]
pSlides = PresentationSettings -> Pandoc -> [Slide]
pandocToSlides PresentationSettings
pSettings Pandoc
pandoc
!pActiveFragment :: (Int, Int)
pActiveFragment = (0, 0)
!pAuthor :: [Inline]
pAuthor = [[Inline]] -> [Inline]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Meta -> [[Inline]]
Pandoc.docAuthors Meta
meta)
Presentation -> Either FilePath Presentation
forall (m :: * -> *) a. Monad m => a -> m a
return $WPresentation :: FilePath
-> [Inline]
-> [Inline]
-> PresentationSettings
-> [Slide]
-> (Int, Int)
-> Presentation
Presentation {..}
parseMetadataBlock :: T.Text -> Maybe A.Value
parseMetadataBlock :: Text -> Maybe Value
parseMetadataBlock src :: Text
src = do
ByteString
block <- Text -> ByteString
T.encodeUtf8 (Text -> ByteString) -> Maybe Text -> Maybe ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
mbBlock
(ParseException -> Maybe Value)
-> (Value -> Maybe Value)
-> Either ParseException Value
-> Maybe Value
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe Value -> ParseException -> Maybe Value
forall a b. a -> b -> a
const Maybe Value
forall a. Maybe a
Nothing) Value -> Maybe Value
forall a. a -> Maybe a
Just (ByteString -> Either ParseException Value
forall a. FromJSON a => ByteString -> Either ParseException a
Yaml.decodeEither' ByteString
block)
where
mbBlock :: Maybe T.Text
mbBlock :: Maybe Text
mbBlock = case Text -> [Text]
T.lines Text
src of
("---" : ls :: [Text]
ls) -> case (Text -> Bool) -> [Text] -> ([Text], [Text])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["---", "..."]) [Text]
ls of
(_, []) -> Maybe Text
forall a. Maybe a
Nothing
(block :: [Text]
block, (_ : _)) -> Text -> Maybe Text
forall a. a -> Maybe a
Just ([Text] -> Text
T.unlines [Text]
block)
_ -> Maybe Text
forall a. Maybe a
Nothing
readMetaSettings :: T.Text -> Either String PresentationSettings
readMetaSettings :: Text -> Either FilePath PresentationSettings
readMetaSettings src :: Text
src = Either FilePath PresentationSettings
-> Maybe (Either FilePath PresentationSettings)
-> Either FilePath PresentationSettings
forall a. a -> Maybe a -> a
fromMaybe (PresentationSettings -> Either FilePath PresentationSettings
forall a b. b -> Either a b
Right PresentationSettings
forall a. Monoid a => a
mempty) (Maybe (Either FilePath PresentationSettings)
-> Either FilePath PresentationSettings)
-> Maybe (Either FilePath PresentationSettings)
-> Either FilePath PresentationSettings
forall a b. (a -> b) -> a -> b
$ do
A.Object obj :: Object
obj <- Text -> Maybe Value
parseMetadataBlock Text
src
Value
val <- Text -> Object -> Maybe Value
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HMS.lookup "patat" Object
obj
Either FilePath PresentationSettings
-> Maybe (Either FilePath PresentationSettings)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath PresentationSettings
-> Maybe (Either FilePath PresentationSettings))
-> Either FilePath PresentationSettings
-> Maybe (Either FilePath PresentationSettings)
forall a b. (a -> b) -> a -> b
$! Result PresentationSettings -> Either FilePath PresentationSettings
forall a. Result a -> Either FilePath a
resultToEither (Result PresentationSettings
-> Either FilePath PresentationSettings)
-> Result PresentationSettings
-> Either FilePath PresentationSettings
forall a b. (a -> b) -> a -> b
$! Value -> Result PresentationSettings
forall a. FromJSON a => Value -> Result a
A.fromJSON Value
val
where
resultToEither :: A.Result a -> Either String a
resultToEither :: Result a -> Either FilePath a
resultToEither (A.Success x :: a
x) = a -> Either FilePath a
forall a b. b -> Either a b
Right a
x
resultToEither (A.Error e :: FilePath
e) = FilePath -> Either FilePath a
forall a b. a -> Either a b
Left (FilePath -> Either FilePath a) -> FilePath -> Either FilePath a
forall a b. (a -> b) -> a -> b
$!
"Error parsing patat settings from metadata: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
e
readHomeSettings :: IO (Either String PresentationSettings)
readHomeSettings :: IO (Either FilePath PresentationSettings)
readHomeSettings = do
FilePath
home <- IO FilePath
getHomeDirectory
let path :: FilePath
path = FilePath
home FilePath -> FilePath -> FilePath
</> ".patat.yaml"
Bool
exists <- FilePath -> IO Bool
doesFileExist FilePath
path
if Bool -> Bool
not Bool
exists
then Either FilePath PresentationSettings
-> IO (Either FilePath PresentationSettings)
forall (m :: * -> *) a. Monad m => a -> m a
return (PresentationSettings -> Either FilePath PresentationSettings
forall a b. b -> Either a b
Right PresentationSettings
forall a. Monoid a => a
mempty)
else do
Either ParseException PresentationSettings
errOrPs <- FilePath -> IO (Either ParseException PresentationSettings)
forall a. FromJSON a => FilePath -> IO (Either ParseException a)
Yaml.decodeFileEither FilePath
path
Either FilePath PresentationSettings
-> IO (Either FilePath PresentationSettings)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath PresentationSettings
-> IO (Either FilePath PresentationSettings))
-> Either FilePath PresentationSettings
-> IO (Either FilePath PresentationSettings)
forall a b. (a -> b) -> a -> b
$! case Either ParseException PresentationSettings
errOrPs of
Left err :: ParseException
err -> FilePath -> Either FilePath PresentationSettings
forall a b. a -> Either a b
Left (ParseException -> FilePath
forall a. Show a => a -> FilePath
show ParseException
err)
Right ps :: PresentationSettings
ps -> PresentationSettings -> Either FilePath PresentationSettings
forall a b. b -> Either a b
Right PresentationSettings
ps
pandocToSlides :: PresentationSettings -> Pandoc.Pandoc -> [Slide]
pandocToSlides :: PresentationSettings -> Pandoc -> [Slide]
pandocToSlides settings :: PresentationSettings
settings pandoc :: Pandoc
pandoc =
let slideLevel :: Int
slideLevel = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (Pandoc -> Int
detectSlideLevel Pandoc
pandoc) (PresentationSettings -> Maybe Int
psSlideLevel PresentationSettings
settings)
unfragmented :: [Slide]
unfragmented = Int -> Pandoc -> [Slide]
splitSlides Int
slideLevel Pandoc
pandoc
fragmented :: [Slide]
fragmented =
[ case Slide
slide of
TitleSlide _ -> Slide
slide
ContentSlide fragments0 :: [Fragment]
fragments0 ->
let blocks :: [Block]
blocks = (Fragment -> [Block]) -> [Fragment] -> [Block]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Fragment -> [Block]
unFragment [Fragment]
fragments0
blockss :: [[Block]]
blockss = FragmentSettings -> [Block] -> [[Block]]
fragmentBlocks FragmentSettings
fragmentSettings [Block]
blocks in
[Fragment] -> Slide
ContentSlide (([Block] -> Fragment) -> [[Block]] -> [Fragment]
forall a b. (a -> b) -> [a] -> [b]
map [Block] -> Fragment
Fragment [[Block]]
blockss)
| Slide
slide <- [Slide]
unfragmented
] in
[Slide]
fragmented
where
fragmentSettings :: FragmentSettings
fragmentSettings = $WFragmentSettings :: Bool -> FragmentSettings
FragmentSettings
{ fsIncrementalLists :: Bool
fsIncrementalLists = Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False (PresentationSettings -> Maybe Bool
psIncrementalLists PresentationSettings
settings)
}
detectSlideLevel :: Pandoc.Pandoc -> Int
detectSlideLevel :: Pandoc -> Int
detectSlideLevel (Pandoc.Pandoc _meta :: Meta
_meta blocks0 :: [Block]
blocks0) =
Int -> [Block] -> Int
go 6 [Block]
blocks0
where
go :: Int -> [Block] -> Int
go level :: Int
level (Pandoc.Header n :: Int
n _ _ : x :: Block
x : xs :: [Block]
xs)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
level Bool -> Bool -> Bool
&& Block -> Bool
nonHeader Block
x = Int -> [Block] -> Int
go Int
n [Block]
xs
| Bool
otherwise = Int -> [Block] -> Int
go Int
level (Block
xBlock -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:[Block]
xs)
go level :: Int
level (_ : xs :: [Block]
xs) = Int -> [Block] -> Int
go Int
level [Block]
xs
go level :: Int
level [] = Int
level
nonHeader :: Block -> Bool
nonHeader (Pandoc.Header _ _ _) = Bool
False
nonHeader _ = Bool
True
splitSlides :: Int -> Pandoc.Pandoc -> [Slide]
splitSlides :: Int -> Pandoc -> [Slide]
splitSlides slideLevel :: Int
slideLevel (Pandoc.Pandoc _meta :: Meta
_meta blocks0 :: [Block]
blocks0)
| (Block -> Bool) -> [Block] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Block -> Block -> Bool
forall a. Eq a => a -> a -> Bool
== Block
Pandoc.HorizontalRule) [Block]
blocks0 = [Block] -> [Slide]
splitAtRules [Block]
blocks0
| Bool
otherwise = [Block] -> [Block] -> [Slide]
splitAtHeaders [] [Block]
blocks0
where
mkContentSlide :: [Pandoc.Block] -> [Slide]
mkContentSlide :: [Block] -> [Slide]
mkContentSlide [] = []
mkContentSlide bs :: [Block]
bs = [[Fragment] -> Slide
ContentSlide [[Block] -> Fragment
Fragment [Block]
bs]]
splitAtRules :: [Block] -> [Slide]
splitAtRules blocks :: [Block]
blocks = case (Block -> Bool) -> [Block] -> ([Block], [Block])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Block -> Block -> Bool
forall a. Eq a => a -> a -> Bool
== Block
Pandoc.HorizontalRule) [Block]
blocks of
(xs :: [Block]
xs, []) -> [Block] -> [Slide]
mkContentSlide [Block]
xs
(xs :: [Block]
xs, (_rule :: Block
_rule : ys :: [Block]
ys)) -> [Block] -> [Slide]
mkContentSlide [Block]
xs [Slide] -> [Slide] -> [Slide]
forall a. [a] -> [a] -> [a]
++ [Block] -> [Slide]
splitAtRules [Block]
ys
splitAtHeaders :: [Block] -> [Block] -> [Slide]
splitAtHeaders acc :: [Block]
acc [] =
[Block] -> [Slide]
mkContentSlide ([Block] -> [Block]
forall a. [a] -> [a]
reverse [Block]
acc)
splitAtHeaders acc :: [Block]
acc (b :: Block
b@(Pandoc.Header i :: Int
i _ _) : bs :: [Block]
bs)
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
slideLevel = [Block] -> [Block] -> [Slide]
splitAtHeaders (Block
b Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block]
acc) [Block]
bs
| Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
slideLevel =
[Block] -> [Slide]
mkContentSlide ([Block] -> [Block]
forall a. [a] -> [a]
reverse [Block]
acc) [Slide] -> [Slide] -> [Slide]
forall a. [a] -> [a] -> [a]
++ [Block] -> [Block] -> [Slide]
splitAtHeaders [Block
b] [Block]
bs
| Bool
otherwise =
[Block] -> [Slide]
mkContentSlide ([Block] -> [Block]
forall a. [a] -> [a]
reverse [Block]
acc) [Slide] -> [Slide] -> [Slide]
forall a. [a] -> [a] -> [a]
++ [Block -> Slide
TitleSlide Block
b] [Slide] -> [Slide] -> [Slide]
forall a. [a] -> [a] -> [a]
++ [Block] -> [Block] -> [Slide]
splitAtHeaders [] [Block]
bs
splitAtHeaders acc :: [Block]
acc (b :: Block
b : bs :: [Block]
bs) =
[Block] -> [Block] -> [Slide]
splitAtHeaders (Block
b Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block]
acc) [Block]
bs