{-# LANGUAGE OverloadedStrings #-}
{- |
   Module      : Text.Pandoc.Slides
   Copyright   : Copyright (C) 2012-2023 John MacFarlane
   License     : GNU GPL, version 2 or above

   Maintainer  : John MacFarlane <jgm@berkeley.edu>
   Stability   : alpha
   Portability : portable

Utility functions for splitting documents into slides for slide
show formats (dzslides, revealjs, s5, slidy, slideous, beamer).
-}
module Text.Pandoc.Slides ( getSlideLevel, prepSlides ) where
import Text.Pandoc.Definition

-- | Find level of header that starts slides (defined as the least header
-- level that occurs before a non-header/non-hrule in the blocks).
getSlideLevel :: [Block] -> Int
getSlideLevel :: [Block] -> Int
getSlideLevel = Int -> [Block] -> Int
go Int
6
  where go :: Int -> [Block] -> Int
go Int
least (Header Int
n Attr
_ [Inline]
_ : Block
x : [Block]
xs)
                 | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
least Bool -> Bool -> Bool
&& Block -> Bool
nonHOrHR Block
x = Int -> [Block] -> Int
go Int
n [Block]
xs
                 | Bool
otherwise               = Int -> [Block] -> Int
go Int
least (Block
xBlock -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:[Block]
xs)
        go Int
least (Div Attr
_ [Block]
bs : [Block]
xs) = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Int -> [Block] -> Int
go Int
least [Block]
bs) (Int -> [Block] -> Int
go Int
least [Block]
xs)
        go Int
least (Block
_ : [Block]
xs) = Int -> [Block] -> Int
go Int
least [Block]
xs
        go Int
least [] = Int
least
        nonHOrHR :: Block -> Bool
nonHOrHR Header{}       = Bool
False
        nonHOrHR Block
HorizontalRule = Bool
False
        nonHOrHR Block
_              = Bool
True

-- | Prepare a block list to be passed to makeSections.
prepSlides :: Int -> [Block] -> [Block]
prepSlides :: Int -> [Block] -> [Block]
prepSlides Int
slideLevel = [Block] -> [Block]
ensureStartWithH ([Block] -> [Block]) -> ([Block] -> [Block]) -> [Block] -> [Block]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Block] -> [Block]
splitHrule ([Block] -> [Block]) -> ([Block] -> [Block]) -> [Block] -> [Block]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Block] -> [Block]
extractRefsHeader
  where splitHrule :: [Block] -> [Block]
splitHrule (Block
HorizontalRule : Header Int
n Attr
attr [Inline]
xs : [Block]
ys)
                       | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
slideLevel = Int -> Attr -> [Inline] -> Block
Header Int
slideLevel Attr
attr [Inline]
xs Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block] -> [Block]
splitHrule [Block]
ys
        splitHrule (Block
HorizontalRule : [Block]
xs) = Int -> Attr -> [Inline] -> Block
Header Int
slideLevel Attr
nullAttr [Text -> Inline
Str Text
"\0"] Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:
                                           [Block] -> [Block]
splitHrule [Block]
xs
        splitHrule (Block
x : [Block]
xs)              = Block
x Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block] -> [Block]
splitHrule [Block]
xs
        splitHrule []                    = []
        extractRefsHeader :: [Block] -> [Block]
extractRefsHeader [Block]
bs             =
          case [Block] -> [Block]
forall a. [a] -> [a]
reverse [Block]
bs of
               (Div (Text
"refs",[Text]
classes,[(Text, Text)]
kvs) (Header Int
n Attr
attrs [Inline]
xs : [Block]
ys) : [Block]
zs)
                 -> [Block] -> [Block]
forall a. [a] -> [a]
reverse [Block]
zs [Block] -> [Block] -> [Block]
forall a. [a] -> [a] -> [a]
++ [Int -> Attr -> [Inline] -> Block
Header Int
n Attr
attrs [Inline]
xs,
                                   Attr -> [Block] -> Block
Div (Text
"refs",[Text]
classes,[(Text, Text)]
kvs) [Block]
ys]
               [Block]
_ -> [Block]
bs
        ensureStartWithH :: [Block] -> [Block]
ensureStartWithH bs :: [Block]
bs@(Header Int
n Attr
_ [Inline]
_:[Block]
_)
                       | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
slideLevel = [Block]
bs
        ensureStartWithH bs :: [Block]
bs@(Div Attr
_ (Header Int
n Attr
_ [Inline]
_:[Block]
_) : [Block]
_)
                       | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
slideLevel = [Block]
bs
        ensureStartWithH [Block]
bs              = Int -> Attr -> [Inline] -> Block
Header Int
slideLevel Attr
nullAttr [Text -> Inline
Str Text
"\0"] Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block]
bs