{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{- |
   Module      : Text.Pandoc.Slides
   Copyright   : Copyright (C) 2012-2019 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 Prelude
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