    {-# LANGUAGE OverloadedStrings #-}
    {- |
       Module      : Text.Pandoc.Slides
       Copyright   : Copyright (C) 2012-2020 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 6
      where go :: Int -> [Block] -> Int
    go least :: Int
    least (Header n :: Int
    n _ _ : x :: Block
    x : xs :: [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 least :: Int
    least (Div _ bs :: [Block]
    bs : xs :: [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 least :: Int
    least (_ : xs :: [Block]
    xs) = Int -> [Block] -> Int
    go Int
    least [Block]
    xs
            go least :: Int
    least [] = Int
    least
            nonHOrHR :: Block -> Bool
    nonHOrHR Header{}       = Bool
    False
            nonHOrHR HorizontalRule = Bool
    False
            nonHOrHR _              = Bool
    True

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