    {-# LANGUAGE CPP                 #-}
    {-# LANGUAGE FlexibleContexts    #-}
    {-# LANGUAGE PatternGuards       #-}
    {-# LANGUAGE OverloadedStrings   #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {- |
       Module      : Text.Pandoc.Writers.EPUB
       Copyright   : Copyright (C) 2010-2020 John MacFarlane
       License     : GNU GPL, version 2 or above

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

    Conversion of 'Pandoc' documents to EPUB.
    -}
    module Text.Pandoc.Writers.EPUB ( writeEPUB2, writeEPUB3 ) where
    import Codec.Archive.Zip (Entry, addEntryToArchive, eRelativePath, emptyArchive,
                              fromArchive, fromEntry, toEntry)
    import Control.Applicative ( (<|>) )
    import Control.Monad (mplus, unless, when, zipWithM)
    import Control.Monad.Except (catchError, throwError)
    import Control.Monad.State.Strict (StateT, evalState, evalStateT, get,
                                       gets, lift, modify)
    import qualified Data.ByteString.Lazy as B
    import qualified Data.ByteString.Lazy.Char8 as B8
    import Data.Char (isAlphaNum, isAscii, isDigit, toLower)
    import Data.List (isInfixOf, isPrefixOf)
    import qualified Data.Map as M
    import Data.Maybe (fromMaybe, isNothing, mapMaybe, isJust)
    import qualified Data.Set as Set
    import qualified Data.Text as TS
    import qualified Data.Text.Lazy as TL
    import Network.HTTP (urlEncode)
    import System.FilePath (takeExtension, takeFileName, makeRelative)
    import Text.HTML.TagSoup (Tag (TagOpen), fromAttrib, parseTags)
    import Text.Pandoc.Builder (fromList, setMeta)
    import Text.Pandoc.Class.PandocMonad (PandocMonad, report)
    import qualified Text.Pandoc.Class.PandocPure as P
    import qualified Text.Pandoc.Class.PandocMonad as P
    import Data.Time
    import Text.Pandoc.Definition
    import Text.Pandoc.Error
    import Text.Pandoc.ImageSize
    import Text.Pandoc.Logging
    import Text.Pandoc.MIME (MimeType, extensionFromMimeType, getMimeType)
    import Text.Pandoc.Options (EPUBVersion (..), HTMLMathMethod (..),
                                ObfuscationMethod (NoObfuscation), WrapOption (..),
                                WriterOptions (..))
    import Text.Pandoc.Shared (makeSections, normalizeDate, renderTags',
                               safeRead, stringify, trim, uniqueIdent, tshow)
    import qualified Text.Pandoc.UTF8 as UTF8
    import Text.Pandoc.UUID (getUUID)
    import Text.Pandoc.Walk (query, walk, walkM)
    import Text.Pandoc.Writers.HTML (writeHtmlStringForEPUB)
    import Text.Printf (printf)
    import Text.XML.Light (Attr (..), Element (..), Node (..), QName (..),
                           add_attrs, lookupAttr, node, onlyElems, parseXML,
                           ppElement, showElement, strContent, unode, unqual)
    import Text.Pandoc.XML (escapeStringForXML)
    import Text.DocTemplates (FromContext(lookupContext), Context(..),
                              ToContext(toVal), Val(..))

    -- A Chapter includes a list of blocks.
    data Chapter = Chapter [Block]
      deriving (Int -> Chapter -> ShowS
    [Chapter] -> ShowS
    Chapter -> String
    (Int -> Chapter -> ShowS)
    -> (Chapter -> String) -> ([Chapter] -> ShowS) -> Show Chapter
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Chapter] -> ShowS
    $cshowList :: [Chapter] -> ShowS
    show :: Chapter -> String
    $cshow :: Chapter -> String
    showsPrec :: Int -> Chapter -> ShowS
    $cshowsPrec :: Int -> Chapter -> ShowS
    Show)

    data EPUBState = EPUBState {
            EPUBState -> [(String, (String, Maybe Entry))]
    stMediaPaths  :: [(FilePath, (FilePath, Maybe Entry))]
          , EPUBState -> Int
    stMediaNextId :: Int
          , EPUBState -> String
    stEpubSubdir  :: String
          }

    type E m = StateT EPUBState m

    data EPUBMetadata = EPUBMetadata{
        EPUBMetadata -> [Identifier]
    epubIdentifier    :: [Identifier]
      , EPUBMetadata -> [Title]
    epubTitle         :: [Title]
      , EPUBMetadata -> [Date]
    epubDate          :: [Date]
      , EPUBMetadata -> String
    epubLanguage      :: String
      , EPUBMetadata -> [Creator]
    epubCreator       :: [Creator]
      , EPUBMetadata -> [Creator]
    epubContributor   :: [Creator]
      , EPUBMetadata -> [String]
    epubSubject       :: [String]
      , EPUBMetadata -> Maybe String
    epubDescription   :: Maybe String
      , EPUBMetadata -> Maybe String
    epubType          :: Maybe String
      , EPUBMetadata -> Maybe String
    epubFormat        :: Maybe String
      , EPUBMetadata -> Maybe String
    epubPublisher     :: Maybe String
      , EPUBMetadata -> Maybe String
    epubSource        :: Maybe String
      , EPUBMetadata -> Maybe String
    epubRelation      :: Maybe String
      , EPUBMetadata -> Maybe String
    epubCoverage      :: Maybe String
      , EPUBMetadata -> Maybe String
    epubRights        :: Maybe String
      , EPUBMetadata -> Maybe String
    epubCoverImage    :: Maybe String
      , EPUBMetadata -> [String]
    epubStylesheets   :: [FilePath]
      , EPUBMetadata -> Maybe ProgressionDirection
    epubPageDirection :: Maybe ProgressionDirection
      , EPUBMetadata -> [(String, String)]
    epubIbooksFields  :: [(String, String)]
      , EPUBMetadata -> [(String, String)]
    epubCalibreFields :: [(String, String)]
      } deriving Int -> EPUBMetadata -> ShowS
    [EPUBMetadata] -> ShowS
    EPUBMetadata -> String
    (Int -> EPUBMetadata -> ShowS)
    -> (EPUBMetadata -> String)
    -> ([EPUBMetadata] -> ShowS)
    -> Show EPUBMetadata
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [EPUBMetadata] -> ShowS
    $cshowList :: [EPUBMetadata] -> ShowS
    show :: EPUBMetadata -> String
    $cshow :: EPUBMetadata -> String
    showsPrec :: Int -> EPUBMetadata -> ShowS
    $cshowsPrec :: Int -> EPUBMetadata -> ShowS
    Show

    data Date = Date{
        Date -> String
    dateText  :: String
      , Date -> Maybe String
    dateEvent :: Maybe String
      } deriving Int -> Date -> ShowS
    [Date] -> ShowS
    Date -> String
    (Int -> Date -> ShowS)
    -> (Date -> String) -> ([Date] -> ShowS) -> Show Date
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Date] -> ShowS
    $cshowList :: [Date] -> ShowS
    show :: Date -> String
    $cshow :: Date -> String
    showsPrec :: Int -> Date -> ShowS
    $cshowsPrec :: Int -> Date -> ShowS
    Show

    data Creator = Creator{
        Creator -> String
    creatorText   :: String
      , Creator -> Maybe String
    creatorRole   :: Maybe String
      , Creator -> Maybe String
    creatorFileAs :: Maybe String
      } deriving Int -> Creator -> ShowS
    [Creator] -> ShowS
    Creator -> String
    (Int -> Creator -> ShowS)
    -> (Creator -> String) -> ([Creator] -> ShowS) -> Show Creator
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Creator] -> ShowS
    $cshowList :: [Creator] -> ShowS
    show :: Creator -> String
    $cshow :: Creator -> String
    showsPrec :: Int -> Creator -> ShowS
    $cshowsPrec :: Int -> Creator -> ShowS
    Show

    data Identifier = Identifier{
        Identifier -> String
    identifierText   :: String
      , Identifier -> Maybe String
    identifierScheme :: Maybe String
      } deriving Int -> Identifier -> ShowS
    [Identifier] -> ShowS
    Identifier -> String
    (Int -> Identifier -> ShowS)
    -> (Identifier -> String)
    -> ([Identifier] -> ShowS)
    -> Show Identifier
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Identifier] -> ShowS
    $cshowList :: [Identifier] -> ShowS
    show :: Identifier -> String
    $cshow :: Identifier -> String
    showsPrec :: Int -> Identifier -> ShowS
    $cshowsPrec :: Int -> Identifier -> ShowS
    Show

    data Title = Title{
        Title -> String
    titleText   :: String
      , Title -> Maybe String
    titleFileAs :: Maybe String
      , Title -> Maybe String
    titleType   :: Maybe String
      } deriving Int -> Title -> ShowS
    [Title] -> ShowS
    Title -> String
    (Int -> Title -> ShowS)
    -> (Title -> String) -> ([Title] -> ShowS) -> Show Title
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Title] -> ShowS
    $cshowList :: [Title] -> ShowS
    show :: Title -> String
    $cshow :: Title -> String
    showsPrec :: Int -> Title -> ShowS
    $cshowsPrec :: Int -> Title -> ShowS
    Show

    data ProgressionDirection = LTR | RTL deriving Int -> ProgressionDirection -> ShowS
    [ProgressionDirection] -> ShowS
    ProgressionDirection -> String
    (Int -> ProgressionDirection -> ShowS)
    -> (ProgressionDirection -> String)
    -> ([ProgressionDirection] -> ShowS)
    -> Show ProgressionDirection
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [ProgressionDirection] -> ShowS
    $cshowList :: [ProgressionDirection] -> ShowS
    show :: ProgressionDirection -> String
    $cshow :: ProgressionDirection -> String
    showsPrec :: Int -> ProgressionDirection -> ShowS
    $cshowsPrec :: Int -> ProgressionDirection -> ShowS
    Show

    dcName :: String -> QName
    dcName :: String -> QName
    dcName n :: String
    n = String -> Maybe String -> Maybe String -> QName
    QName String
    n Maybe String
    forall a. Maybe a
    Nothing (String -> Maybe String
    forall a. a -> Maybe a
    Just "dc")

    dcNode :: Node t => String -> t -> Element
    dcNode :: String -> t -> Element
    dcNode = QName -> t -> Element
    forall t. Node t => QName -> t -> Element
    node (QName -> t -> Element)
    -> (String -> QName) -> String -> t -> Element
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> QName
    dcName

    opfName :: String -> QName
    opfName :: String -> QName
    opfName n :: String
    n = String -> Maybe String -> Maybe String -> QName
    QName String
    n Maybe String
    forall a. Maybe a
    Nothing (String -> Maybe String
    forall a. a -> Maybe a
    Just "opf")

    toId :: FilePath -> String
    toId :: ShowS
    toId = (Char -> Char) -> ShowS
    forall a b. (a -> b) -> [a] -> [b]
    map (\x :: Char
    x -> if Char -> Bool
    isAlphaNum Char
    x Bool -> Bool -> Bool
    || Char
    x Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == '-' Bool -> Bool -> Bool
    || Char
    x Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == '_'
                         then Char
    x
                         else '_') ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ShowS
    takeFileName

    removeNote :: Inline -> Inline
    removeNote :: Inline -> Inline
    removeNote (Note _) = Text -> Inline
    Str ""
    removeNote x :: Inline
    x        = Inline
    x

    toVal' :: String -> Val TS.Text
    toVal' :: String -> Val Text
    toVal' = Text -> Val Text
    forall a b. ToContext a b => b -> Val a
    toVal (Text -> Val Text) -> (String -> Text) -> String -> Val Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Text
    TS.pack

    mkEntry :: PandocMonad m => FilePath -> B.ByteString -> E m Entry
    mkEntry :: String -> ByteString -> E m Entry
    mkEntry path :: String
    path content :: ByteString
    content = do
      String
    epubSubdir <- (EPUBState -> String) -> StateT EPUBState m String
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets EPUBState -> String
    stEpubSubdir
      let addEpubSubdir :: Entry -> Entry
          addEpubSubdir :: Entry -> Entry
    addEpubSubdir e :: Entry
    e = Entry
    e{ eRelativePath :: String
    eRelativePath =
              (if String -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    epubSubdir
                  then ""
                  else String
    epubSubdir String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ "/") String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Entry -> String
    eRelativePath Entry
    e }
      Integer
    epochtime <- POSIXTime -> Integer
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (POSIXTime -> Integer)
    -> StateT EPUBState m POSIXTime -> StateT EPUBState m Integer
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m POSIXTime -> StateT EPUBState m POSIXTime
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m POSIXTime
    forall (m :: * -> *). PandocMonad m => m POSIXTime
    P.getPOSIXTime
      Entry -> E m Entry
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Entry -> E m Entry) -> Entry -> E m Entry
    forall a b. (a -> b) -> a -> b
    $
           (if String
    path String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "mimetype" Bool -> Bool -> Bool
    || "META-INF" String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf` String
    path
               then Entry -> Entry
    forall a. a -> a
    id
               else Entry -> Entry
    addEpubSubdir) (Entry -> Entry) -> Entry -> Entry
    forall a b. (a -> b) -> a -> b
    $ String -> Integer -> ByteString -> Entry
    toEntry String
    path Integer
    epochtime ByteString
    content

    getEPUBMetadata :: PandocMonad m => WriterOptions -> Meta -> E m EPUBMetadata
    getEPUBMetadata :: WriterOptions -> Meta -> E m EPUBMetadata
    getEPUBMetadata opts :: WriterOptions
    opts meta :: Meta
    meta = do
      let md :: EPUBMetadata
    md = WriterOptions -> Meta -> EPUBMetadata
    metadataFromMeta WriterOptions
    opts Meta
    meta
      let elts :: [Element]
    elts = [Element] -> (Text -> [Element]) -> Maybe Text -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] ([Content] -> [Element]
    onlyElems ([Content] -> [Element])
    -> (Text -> [Content]) -> Text -> [Element]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> [Content]
    forall s. XmlSource s => s -> [Content]
    parseXML) (Maybe Text -> [Element]) -> Maybe Text -> [Element]
    forall a b. (a -> b) -> a -> b
    $ WriterOptions -> Maybe Text
    writerEpubMetadata WriterOptions
    opts
      let md' :: EPUBMetadata
    md' = (Element -> EPUBMetadata -> EPUBMetadata)
    -> EPUBMetadata -> [Element] -> EPUBMetadata
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Element -> EPUBMetadata -> EPUBMetadata
    addMetadataFromXML EPUBMetadata
    md [Element]
    elts
      let addIdentifier :: EPUBMetadata -> t m EPUBMetadata
    addIdentifier m :: EPUBMetadata
    m =
           if [Identifier] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (EPUBMetadata -> [Identifier]
    epubIdentifier EPUBMetadata
    m)
              then do
                String
    randomId <- (UUID -> String
    forall a. Show a => a -> String
    show (UUID -> String) -> (StdGen -> UUID) -> StdGen -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StdGen -> UUID
    forall g. RandomGen g => g -> UUID
    getUUID) (StdGen -> String) -> t m StdGen -> t m String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m StdGen -> t m StdGen
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m StdGen
    forall (m :: * -> *). PandocMonad m => m StdGen
    P.newStdGen
                EPUBMetadata -> t m EPUBMetadata
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EPUBMetadata -> t m EPUBMetadata)
    -> EPUBMetadata -> t m EPUBMetadata
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata
    m{ epubIdentifier :: [Identifier]
    epubIdentifier = [String -> Maybe String -> Identifier
    Identifier String
    randomId Maybe String
    forall a. Maybe a
    Nothing] }
              else EPUBMetadata -> t m EPUBMetadata
    forall (m :: * -> *) a. Monad m => a -> m a
    return EPUBMetadata
    m
      let addLanguage :: EPUBMetadata -> t m EPUBMetadata
    addLanguage m :: EPUBMetadata
    m =
           if String -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (EPUBMetadata -> String
    epubLanguage EPUBMetadata
    m)
              then case Text -> Context Text -> Maybe Text
    forall a b. FromContext a b => Text -> Context a -> Maybe b
    lookupContext "lang" (WriterOptions -> Context Text
    writerVariables WriterOptions
    opts) of
                         Just x :: Text
    x  -> EPUBMetadata -> t m EPUBMetadata
    forall (m :: * -> *) a. Monad m => a -> m a
    return EPUBMetadata
    m{ epubLanguage :: String
    epubLanguage = Text -> String
    TS.unpack Text
    x }
                         Nothing -> do
                           Maybe Text
    mLang <- m (Maybe Text) -> t m (Maybe Text)
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m (Maybe Text) -> t m (Maybe Text))
    -> m (Maybe Text) -> t m (Maybe Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> m (Maybe Text)
    forall (m :: * -> *). PandocMonad m => Text -> m (Maybe Text)
    P.lookupEnv "LANG"
                           let localeLang :: Text
    localeLang =
                                 case Maybe Text
    mLang of
                                   Just lang :: Text
    lang ->
                                     (Char -> Char) -> Text -> Text
    TS.map (\c :: Char
    c -> if Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == '_' then '-' else Char
    c) (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
                                     (Char -> Bool) -> Text -> Text
    TS.takeWhile (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /='.') Text
    lang
                                   Nothing -> "en-US"
                           EPUBMetadata -> t m EPUBMetadata
    forall (m :: * -> *) a. Monad m => a -> m a
    return EPUBMetadata
    m{ epubLanguage :: String
    epubLanguage = Text -> String
    TS.unpack Text
    localeLang }
              else EPUBMetadata -> t m EPUBMetadata
    forall (m :: * -> *) a. Monad m => a -> m a
    return EPUBMetadata
    m
      let fixDate :: EPUBMetadata -> t m EPUBMetadata
    fixDate m :: EPUBMetadata
    m =
           if [Date] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (EPUBMetadata -> [Date]
    epubDate EPUBMetadata
    m)
              then do
                UTCTime
    currentTime <- m UTCTime -> t m UTCTime
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m UTCTime
    forall (m :: * -> *). PandocMonad m => m UTCTime
    P.getCurrentTime
                EPUBMetadata -> t m EPUBMetadata
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EPUBMetadata -> t m EPUBMetadata)
    -> EPUBMetadata -> t m EPUBMetadata
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata
    m{ epubDate :: [Date]
    epubDate = [ Date :: String -> Maybe String -> Date
    Date{
                                 dateText :: String
    dateText = UTCTime -> String
    showDateTimeISO8601 UTCTime
    currentTime
                               , dateEvent :: Maybe String
    dateEvent = Maybe String
    forall a. Maybe a
    Nothing } ] }
              else EPUBMetadata -> t m EPUBMetadata
    forall (m :: * -> *) a. Monad m => a -> m a
    return EPUBMetadata
    m
      let addAuthor :: EPUBMetadata -> m EPUBMetadata
    addAuthor m :: EPUBMetadata
    m =
           if (Creator -> Bool) -> [Creator] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (\c :: Creator
    c -> Creator -> Maybe String
    creatorRole Creator
    c Maybe String -> Maybe String -> Bool
    forall a. Eq a => a -> a -> Bool
    == String -> Maybe String
    forall a. a -> Maybe a
    Just "aut") ([Creator] -> Bool) -> [Creator] -> Bool
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> [Creator]
    epubCreator EPUBMetadata
    m
              then EPUBMetadata -> m EPUBMetadata
    forall (m :: * -> *) a. Monad m => a -> m a
    return EPUBMetadata
    m
              else do
                let authors' :: [Text]
    authors' = ([Inline] -> Text) -> [[Inline]] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map [Inline] -> Text
    forall a. Walkable Inline a => a -> Text
    stringify ([[Inline]] -> [Text]) -> [[Inline]] -> [Text]
    forall a b. (a -> b) -> a -> b
    $ Meta -> [[Inline]]
    docAuthors Meta
    meta
                let toAuthor :: Text -> Creator
    toAuthor name :: Text
    name = Creator :: String -> Maybe String -> Maybe String -> Creator
    Creator{ creatorText :: String
    creatorText = Text -> String
    TS.unpack Text
    name
                                           , creatorRole :: Maybe String
    creatorRole = String -> Maybe String
    forall a. a -> Maybe a
    Just "aut"
                                           , creatorFileAs :: Maybe String
    creatorFileAs = Maybe String
    forall a. Maybe a
    Nothing }
                EPUBMetadata -> m EPUBMetadata
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EPUBMetadata -> m EPUBMetadata) -> EPUBMetadata -> m EPUBMetadata
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata
    m{ epubCreator :: [Creator]
    epubCreator = (Text -> Creator) -> [Text] -> [Creator]
    forall a b. (a -> b) -> [a] -> [b]
    map Text -> Creator
    toAuthor [Text]
    authors' [Creator] -> [Creator] -> [Creator]
    forall a. [a] -> [a] -> [a]
    ++ EPUBMetadata -> [Creator]
    epubCreator EPUBMetadata
    m }
      EPUBMetadata -> E m EPUBMetadata
    forall (t :: (* -> *) -> * -> *) (m :: * -> *).
    (MonadTrans t, Monad (t m), PandocMonad m) =>
    EPUBMetadata -> t m EPUBMetadata
    addIdentifier EPUBMetadata
    md' E m EPUBMetadata
    -> (EPUBMetadata -> E m EPUBMetadata) -> E m EPUBMetadata
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= EPUBMetadata -> E m EPUBMetadata
    forall (t :: (* -> *) -> * -> *) (m :: * -> *).
    (MonadTrans t, Monad (t m), PandocMonad m) =>
    EPUBMetadata -> t m EPUBMetadata
    fixDate E m EPUBMetadata
    -> (EPUBMetadata -> E m EPUBMetadata) -> E m EPUBMetadata
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= EPUBMetadata -> E m EPUBMetadata
    forall (m :: * -> *). Monad m => EPUBMetadata -> m EPUBMetadata
    addAuthor E m EPUBMetadata
    -> (EPUBMetadata -> E m EPUBMetadata) -> E m EPUBMetadata
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= EPUBMetadata -> E m EPUBMetadata
    forall (t :: (* -> *) -> * -> *) (m :: * -> *).
    (MonadTrans t, Monad (t m), PandocMonad m) =>
    EPUBMetadata -> t m EPUBMetadata
    addLanguage

    addMetadataFromXML :: Element -> EPUBMetadata -> EPUBMetadata
    addMetadataFromXML :: Element -> EPUBMetadata -> EPUBMetadata
    addMetadataFromXML e :: Element
    e@(Element (QName name :: String
    name _ (Just "dc")) attrs :: [Attr]
    attrs _ _) md :: EPUBMetadata
    md
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "identifier" = EPUBMetadata
    md{ epubIdentifier :: [Identifier]
    epubIdentifier =
                 Identifier :: String -> Maybe String -> Identifier
    Identifier{ identifierText :: String
    identifierText = Element -> String
    strContent Element
    e
                           , identifierScheme :: Maybe String
    identifierScheme = QName -> [Attr] -> Maybe String
    lookupAttr (String -> QName
    opfName "scheme") [Attr]
    attrs
                           } Identifier -> [Identifier] -> [Identifier]
    forall a. a -> [a] -> [a]
    : EPUBMetadata -> [Identifier]
    epubIdentifier EPUBMetadata
    md }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "title" = EPUBMetadata
    md{ epubTitle :: [Title]
    epubTitle =
                Title :: String -> Maybe String -> Maybe String -> Title
    Title{ titleText :: String
    titleText = Element -> String
    strContent Element
    e
                     , titleFileAs :: Maybe String
    titleFileAs = String -> Maybe String
    getAttr "file-as"
                     , titleType :: Maybe String
    titleType = String -> Maybe String
    getAttr "type"
                     } Title -> [Title] -> [Title]
    forall a. a -> [a] -> [a]
    : EPUBMetadata -> [Title]
    epubTitle EPUBMetadata
    md }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "date" = EPUBMetadata
    md{ epubDate :: [Date]
    epubDate =
                 Date :: String -> Maybe String -> Date
    Date{ dateText :: String
    dateText = String -> Maybe String -> String
    forall a. a -> Maybe a -> a
    fromMaybe "" (Maybe String -> String) -> Maybe String -> String
    forall a b. (a -> b) -> a -> b
    $ String -> Maybe String
    normalizeDate' (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    strContent Element
    e
                     , dateEvent :: Maybe String
    dateEvent = String -> Maybe String
    getAttr "event"
                     } Date -> [Date] -> [Date]
    forall a. a -> [a] -> [a]
    : EPUBMetadata -> [Date]
    epubDate EPUBMetadata
    md }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "language" = EPUBMetadata
    md{ epubLanguage :: String
    epubLanguage = Element -> String
    strContent Element
    e }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "creator" = EPUBMetadata
    md{ epubCreator :: [Creator]
    epubCreator =
                  Creator :: String -> Maybe String -> Maybe String -> Creator
    Creator{ creatorText :: String
    creatorText = Element -> String
    strContent Element
    e
                         , creatorRole :: Maybe String
    creatorRole = String -> Maybe String
    getAttr "role"
                         , creatorFileAs :: Maybe String
    creatorFileAs = String -> Maybe String
    getAttr "file-as"
                         } Creator -> [Creator] -> [Creator]
    forall a. a -> [a] -> [a]
    : EPUBMetadata -> [Creator]
    epubCreator EPUBMetadata
    md }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "contributor" = EPUBMetadata
    md{ epubContributor :: [Creator]
    epubContributor =
                  Creator :: String -> Maybe String -> Maybe String -> Creator
    Creator  { creatorText :: String
    creatorText = Element -> String
    strContent Element
    e
                           , creatorRole :: Maybe String
    creatorRole = String -> Maybe String
    getAttr "role"
                           , creatorFileAs :: Maybe String
    creatorFileAs = String -> Maybe String
    getAttr "file-as"
                           } Creator -> [Creator] -> [Creator]
    forall a. a -> [a] -> [a]
    : EPUBMetadata -> [Creator]
    epubContributor EPUBMetadata
    md }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "subject" = EPUBMetadata
    md{ epubSubject :: [String]
    epubSubject = Element -> String
    strContent Element
    e String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : EPUBMetadata -> [String]
    epubSubject EPUBMetadata
    md }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "description" = EPUBMetadata
    md { epubDescription :: Maybe String
    epubDescription = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    strContent Element
    e }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "type" = EPUBMetadata
    md { epubType :: Maybe String
    epubType = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    strContent Element
    e }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "format" = EPUBMetadata
    md { epubFormat :: Maybe String
    epubFormat = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    strContent Element
    e }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "type" = EPUBMetadata
    md { epubType :: Maybe String
    epubType = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    strContent Element
    e }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "publisher" = EPUBMetadata
    md { epubPublisher :: Maybe String
    epubPublisher = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    strContent Element
    e }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "source" = EPUBMetadata
    md { epubSource :: Maybe String
    epubSource = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    strContent Element
    e }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "relation" = EPUBMetadata
    md { epubRelation :: Maybe String
    epubRelation = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    strContent Element
    e }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "coverage" = EPUBMetadata
    md { epubCoverage :: Maybe String
    epubCoverage = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    strContent Element
    e }
      | String
    name String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "rights" = EPUBMetadata
    md { epubRights :: Maybe String
    epubRights = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    strContent Element
    e }
      | Bool
    otherwise = EPUBMetadata
    md
      where getAttr :: String -> Maybe String
    getAttr n :: String
    n = QName -> [Attr] -> Maybe String
    lookupAttr (String -> QName
    opfName String
    n) [Attr]
    attrs
    addMetadataFromXML e :: Element
    e@(Element (QName "meta" _ _) attrs :: [Attr]
    attrs _ _) md :: EPUBMetadata
    md =
      case String -> Maybe String
    getAttr "property" of
           Just s :: String
    s | "ibooks:" String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf` String
    s ->
                    EPUBMetadata
    md{ epubIbooksFields :: [(String, String)]
    epubIbooksFields = (Int -> ShowS
    forall a. Int -> [a] -> [a]
    drop 7 String
    s, Element -> String
    strContent Element
    e) (String, String) -> [(String, String)] -> [(String, String)]
    forall a. a -> [a] -> [a]
    :
                           EPUBMetadata -> [(String, String)]
    epubIbooksFields EPUBMetadata
    md }
           _ -> case String -> Maybe String
    getAttr "name" of
                     Just s :: String
    s | "calibre:" String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf` String
    s ->
                       EPUBMetadata
    md{ epubCalibreFields :: [(String, String)]
    epubCalibreFields =
                             (Int -> ShowS
    forall a. Int -> [a] -> [a]
    drop 8 String
    s, String -> Maybe String -> String
    forall a. a -> Maybe a -> a
    fromMaybe "" (Maybe String -> String) -> Maybe String -> String
    forall a b. (a -> b) -> a -> b
    $ String -> Maybe String
    getAttr "content") (String, String) -> [(String, String)] -> [(String, String)]
    forall a. a -> [a] -> [a]
    :
                              EPUBMetadata -> [(String, String)]
    epubCalibreFields EPUBMetadata
    md }
                     _ -> EPUBMetadata
    md
      where getAttr :: String -> Maybe String
    getAttr n :: String
    n = QName -> [Attr] -> Maybe String
    lookupAttr (String -> QName
    unqual String
    n) [Attr]
    attrs
    addMetadataFromXML _ md :: EPUBMetadata
    md = EPUBMetadata
    md

    metaValueToString :: MetaValue -> String
    metaValueToString :: MetaValue -> String
    metaValueToString (MetaString s :: Text
    s)    = Text -> String
    TS.unpack Text
    s
    metaValueToString (MetaInlines ils :: [Inline]
    ils) = Text -> String
    TS.unpack (Text -> String) -> Text -> String
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Text
    forall a. Walkable Inline a => a -> Text
    stringify [Inline]
    ils
    metaValueToString (MetaBlocks bs :: [Block]
    bs)   = Text -> String
    TS.unpack (Text -> String) -> Text -> String
    forall a b. (a -> b) -> a -> b
    $ [Block] -> Text
    forall a. Walkable Inline a => a -> Text
    stringify [Block]
    bs
    metaValueToString (MetaBool True)   = "true"
    metaValueToString (MetaBool False)  = "false"
    metaValueToString _                 = ""

    metaValueToPaths :: MetaValue -> [FilePath]
    metaValueToPaths :: MetaValue -> [String]
    metaValueToPaths (MetaList xs :: [MetaValue]
    xs) = (MetaValue -> String) -> [MetaValue] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map MetaValue -> String
    metaValueToString [MetaValue]
    xs
    metaValueToPaths x :: MetaValue
    x             = [MetaValue -> String
    metaValueToString MetaValue
    x]

    getList :: TS.Text -> Meta -> (MetaValue -> a) -> [a]
    getList :: Text -> Meta -> (MetaValue -> a) -> [a]
    getList s :: Text
    s meta :: Meta
    meta handleMetaValue :: MetaValue -> a
    handleMetaValue =
      case Text -> Meta -> Maybe MetaValue
    lookupMeta Text
    s Meta
    meta of
           Just (MetaList xs :: [MetaValue]
    xs) -> (MetaValue -> a) -> [MetaValue] -> [a]
    forall a b. (a -> b) -> [a] -> [b]
    map MetaValue -> a
    handleMetaValue [MetaValue]
    xs
           Just mv :: MetaValue
    mv            -> [MetaValue -> a
    handleMetaValue MetaValue
    mv]
           Nothing            -> []

    getIdentifier :: Meta -> [Identifier]
    getIdentifier :: Meta -> [Identifier]
    getIdentifier meta :: Meta
    meta = Text -> Meta -> (MetaValue -> Identifier) -> [Identifier]
    forall a. Text -> Meta -> (MetaValue -> a) -> [a]
    getList "identifier" Meta
    meta MetaValue -> Identifier
    handleMetaValue
      where handleMetaValue :: MetaValue -> Identifier
    handleMetaValue (MetaMap m :: Map Text MetaValue
    m) =
               Identifier :: String -> Maybe String -> Identifier
    Identifier{ identifierText :: String
    identifierText = String -> (MetaValue -> String) -> Maybe MetaValue -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe "" MetaValue -> String
    metaValueToString
                                            (Maybe MetaValue -> String) -> Maybe MetaValue -> String
    forall a b. (a -> b) -> a -> b
    $ Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "text" Map Text MetaValue
    m
                         , identifierScheme :: Maybe String
    identifierScheme = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                                              Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "scheme" Map Text MetaValue
    m }
            handleMetaValue mv :: MetaValue
    mv = String -> Maybe String -> Identifier
    Identifier (MetaValue -> String
    metaValueToString MetaValue
    mv) Maybe String
    forall a. Maybe a
    Nothing

    getTitle :: Meta -> [Title]
    getTitle :: Meta -> [Title]
    getTitle meta :: Meta
    meta = Text -> Meta -> (MetaValue -> Title) -> [Title]
    forall a. Text -> Meta -> (MetaValue -> a) -> [a]
    getList "title" Meta
    meta MetaValue -> Title
    handleMetaValue
      where handleMetaValue :: MetaValue -> Title
    handleMetaValue (MetaMap m :: Map Text MetaValue
    m) =
               Title :: String -> Maybe String -> Maybe String -> Title
    Title{ titleText :: String
    titleText = String -> (MetaValue -> String) -> Maybe MetaValue -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe "" MetaValue -> String
    metaValueToString (Maybe MetaValue -> String) -> Maybe MetaValue -> String
    forall a b. (a -> b) -> a -> b
    $ Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "text" Map Text MetaValue
    m
                    , titleFileAs :: Maybe String
    titleFileAs = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "file-as" Map Text MetaValue
    m
                    , titleType :: Maybe String
    titleType = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "type" Map Text MetaValue
    m }
            handleMetaValue mv :: MetaValue
    mv = String -> Maybe String -> Maybe String -> Title
    Title (MetaValue -> String
    metaValueToString MetaValue
    mv) Maybe String
    forall a. Maybe a
    Nothing Maybe String
    forall a. Maybe a
    Nothing

    getCreator :: TS.Text -> Meta -> [Creator]
    getCreator :: Text -> Meta -> [Creator]
    getCreator s :: Text
    s meta :: Meta
    meta = Text -> Meta -> (MetaValue -> Creator) -> [Creator]
    forall a. Text -> Meta -> (MetaValue -> a) -> [a]
    getList Text
    s Meta
    meta MetaValue -> Creator
    handleMetaValue
      where handleMetaValue :: MetaValue -> Creator
    handleMetaValue (MetaMap m :: Map Text MetaValue
    m) =
               Creator :: String -> Maybe String -> Maybe String -> Creator
    Creator{ creatorText :: String
    creatorText = String -> (MetaValue -> String) -> Maybe MetaValue -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe "" MetaValue -> String
    metaValueToString (Maybe MetaValue -> String) -> Maybe MetaValue -> String
    forall a b. (a -> b) -> a -> b
    $ Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "text" Map Text MetaValue
    m
                      , creatorFileAs :: Maybe String
    creatorFileAs = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "file-as" Map Text MetaValue
    m
                      , creatorRole :: Maybe String
    creatorRole = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "role" Map Text MetaValue
    m }
            handleMetaValue mv :: MetaValue
    mv = String -> Maybe String -> Maybe String -> Creator
    Creator (MetaValue -> String
    metaValueToString MetaValue
    mv) Maybe String
    forall a. Maybe a
    Nothing Maybe String
    forall a. Maybe a
    Nothing

    getDate :: TS.Text -> Meta -> [Date]
    getDate :: Text -> Meta -> [Date]
    getDate s :: Text
    s meta :: Meta
    meta = Text -> Meta -> (MetaValue -> Date) -> [Date]
    forall a. Text -> Meta -> (MetaValue -> a) -> [a]
    getList Text
    s Meta
    meta MetaValue -> Date
    handleMetaValue
      where handleMetaValue :: MetaValue -> Date
    handleMetaValue (MetaMap m :: Map Text MetaValue
    m) =
               Date :: String -> Maybe String -> Date
    Date{ dateText :: String
    dateText = String -> Maybe String -> String
    forall a. a -> Maybe a -> a
    fromMaybe "" (Maybe String -> String) -> Maybe String -> String
    forall a b. (a -> b) -> a -> b
    $
                       Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "text" Map Text MetaValue
    m Maybe MetaValue -> (MetaValue -> Maybe String) -> Maybe String
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= String -> Maybe String
    normalizeDate' (String -> Maybe String)
    -> (MetaValue -> String) -> MetaValue -> Maybe String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MetaValue -> String
    metaValueToString
                   , dateEvent :: Maybe String
    dateEvent = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "event" Map Text MetaValue
    m }
            handleMetaValue mv :: MetaValue
    mv = Date :: String -> Maybe String -> Date
    Date { dateText :: String
    dateText = String -> Maybe String -> String
    forall a. a -> Maybe a -> a
    fromMaybe "" (Maybe String -> String) -> Maybe String -> String
    forall a b. (a -> b) -> a -> b
    $ String -> Maybe String
    normalizeDate' (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ MetaValue -> String
    metaValueToString MetaValue
    mv
                                      , dateEvent :: Maybe String
    dateEvent = Maybe String
    forall a. Maybe a
    Nothing }

    simpleList :: TS.Text -> Meta -> [String]
    simpleList :: Text -> Meta -> [String]
    simpleList s :: Text
    s meta :: Meta
    meta =
      case Text -> Meta -> Maybe MetaValue
    lookupMeta Text
    s Meta
    meta of
           Just (MetaList xs :: [MetaValue]
    xs) -> (MetaValue -> String) -> [MetaValue] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map MetaValue -> String
    metaValueToString [MetaValue]
    xs
           Just x :: MetaValue
    x             -> [MetaValue -> String
    metaValueToString MetaValue
    x]
           Nothing            -> []

    metadataFromMeta :: WriterOptions -> Meta -> EPUBMetadata
    metadataFromMeta :: WriterOptions -> Meta -> EPUBMetadata
    metadataFromMeta opts :: WriterOptions
    opts meta :: Meta
    meta = EPUBMetadata :: [Identifier]
    -> [Title]
    -> [Date]
    -> String
    -> [Creator]
    -> [Creator]
    -> [String]
    -> Maybe String
    -> Maybe String
    -> Maybe String
    -> Maybe String
    -> Maybe String
    -> Maybe String
    -> Maybe String
    -> Maybe String
    -> Maybe String
    -> [String]
    -> Maybe ProgressionDirection
    -> [(String, String)]
    -> [(String, String)]
    -> EPUBMetadata
    EPUBMetadata{
          epubIdentifier :: [Identifier]
    epubIdentifier         = [Identifier]
    identifiers
        , epubTitle :: [Title]
    epubTitle              = [Title]
    titles
        , epubDate :: [Date]
    epubDate               = [Date]
    date
        , epubLanguage :: String
    epubLanguage           = String
    language
        , epubCreator :: [Creator]
    epubCreator            = [Creator]
    creators
        , epubContributor :: [Creator]
    epubContributor        = [Creator]
    contributors
        , epubSubject :: [String]
    epubSubject            = [String]
    subjects
        , epubDescription :: Maybe String
    epubDescription        = Maybe String
    description
        , epubType :: Maybe String
    epubType               = Maybe String
    epubtype
        , epubFormat :: Maybe String
    epubFormat             = Maybe String
    format
        , epubPublisher :: Maybe String
    epubPublisher          = Maybe String
    publisher
        , epubSource :: Maybe String
    epubSource             = Maybe String
    source
        , epubRelation :: Maybe String
    epubRelation           = Maybe String
    relation
        , epubCoverage :: Maybe String
    epubCoverage           = Maybe String
    coverage
        , epubRights :: Maybe String
    epubRights             = Maybe String
    rights
        , epubCoverImage :: Maybe String
    epubCoverImage         = Maybe String
    coverImage
        , epubStylesheets :: [String]
    epubStylesheets        = [String]
    stylesheets
        , epubPageDirection :: Maybe ProgressionDirection
    epubPageDirection      = Maybe ProgressionDirection
    pageDirection
        , epubIbooksFields :: [(String, String)]
    epubIbooksFields       = [(String, String)]
    ibooksFields
        , epubCalibreFields :: [(String, String)]
    epubCalibreFields      = [(String, String)]
    calibreFields
        }
      where identifiers :: [Identifier]
    identifiers = Meta -> [Identifier]
    getIdentifier Meta
    meta
            titles :: [Title]
    titles = Meta -> [Title]
    getTitle Meta
    meta
            date :: [Date]
    date = Text -> Meta -> [Date]
    getDate "date" Meta
    meta
            language :: String
    language = String -> (MetaValue -> String) -> Maybe MetaValue -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe "" MetaValue -> String
    metaValueToString (Maybe MetaValue -> String) -> Maybe MetaValue -> String
    forall a b. (a -> b) -> a -> b
    $
               Text -> Meta -> Maybe MetaValue
    lookupMeta "language" Meta
    meta Maybe MetaValue -> Maybe MetaValue -> Maybe MetaValue
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    `mplus` Text -> Meta -> Maybe MetaValue
    lookupMeta "lang" Meta
    meta
            creators :: [Creator]
    creators = Text -> Meta -> [Creator]
    getCreator "creator" Meta
    meta
            contributors :: [Creator]
    contributors = Text -> Meta -> [Creator]
    getCreator "contributor" Meta
    meta
            subjects :: [String]
    subjects = Text -> Meta -> [String]
    simpleList "subject" Meta
    meta
            description :: Maybe String
    description = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Meta -> Maybe MetaValue
    lookupMeta "description" Meta
    meta
            epubtype :: Maybe String
    epubtype = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Meta -> Maybe MetaValue
    lookupMeta "type" Meta
    meta
            format :: Maybe String
    format = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Meta -> Maybe MetaValue
    lookupMeta "format" Meta
    meta
            publisher :: Maybe String
    publisher = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Meta -> Maybe MetaValue
    lookupMeta "publisher" Meta
    meta
            source :: Maybe String
    source = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Meta -> Maybe MetaValue
    lookupMeta "source" Meta
    meta
            relation :: Maybe String
    relation = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Meta -> Maybe MetaValue
    lookupMeta "relation" Meta
    meta
            coverage :: Maybe String
    coverage = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Meta -> Maybe MetaValue
    lookupMeta "coverage" Meta
    meta
            rights :: Maybe String
    rights = MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Meta -> Maybe MetaValue
    lookupMeta "rights" Meta
    meta
            coverImage :: Maybe String
    coverImage =
                (Text -> String
    TS.unpack (Text -> String) -> Maybe Text -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Context Text -> Maybe Text
    forall a b. FromContext a b => Text -> Context a -> Maybe b
    lookupContext "epub-cover-image"
                                  (WriterOptions -> Context Text
    writerVariables WriterOptions
    opts))
                Maybe String -> Maybe String -> Maybe String
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    `mplus` (MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Meta -> Maybe MetaValue
    lookupMeta "cover-image" Meta
    meta)
            mCss :: Maybe MetaValue
    mCss = Text -> Meta -> Maybe MetaValue
    lookupMeta "css" Meta
    meta Maybe MetaValue -> Maybe MetaValue -> Maybe MetaValue
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Text -> Meta -> Maybe MetaValue
    lookupMeta "stylesheet" Meta
    meta
            stylesheets :: [String]
    stylesheets = [String] -> (MetaValue -> [String]) -> Maybe MetaValue -> [String]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] MetaValue -> [String]
    metaValueToPaths Maybe MetaValue
    mCss [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++
                          case Text -> Context Text -> Maybe [Text]
    forall a b. FromContext a b => Text -> Context a -> Maybe b
    lookupContext "css" (WriterOptions -> Context Text
    writerVariables WriterOptions
    opts) of
                             Just xs :: [Text]
    xs -> (Text -> String) -> [Text] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map Text -> String
    TS.unpack [Text]
    xs
                             Nothing ->
                               case Text -> Context Text -> Maybe Text
    forall a b. FromContext a b => Text -> Context a -> Maybe b
    lookupContext "css" (WriterOptions -> Context Text
    writerVariables WriterOptions
    opts) of
                                 Just x :: Text
    x  -> [Text -> String
    TS.unpack Text
    x]
                                 Nothing -> []
            pageDirection :: Maybe ProgressionDirection
    pageDirection = case (Char -> Char) -> ShowS
    forall a b. (a -> b) -> [a] -> [b]
    map Char -> Char
    toLower ShowS -> (MetaValue -> String) -> MetaValue -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MetaValue -> String
    metaValueToString (MetaValue -> String) -> Maybe MetaValue -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                                 Text -> Meta -> Maybe MetaValue
    lookupMeta "page-progression-direction" Meta
    meta of
                                  Just "ltr" -> ProgressionDirection -> Maybe ProgressionDirection
    forall a. a -> Maybe a
    Just ProgressionDirection
    LTR
                                  Just "rtl" -> ProgressionDirection -> Maybe ProgressionDirection
    forall a. a -> Maybe a
    Just ProgressionDirection
    RTL
                                  _          -> Maybe ProgressionDirection
    forall a. Maybe a
    Nothing
            ibooksFields :: [(String, String)]
    ibooksFields = case Text -> Meta -> Maybe MetaValue
    lookupMeta "ibooks" Meta
    meta of
                                Just (MetaMap mp :: Map Text MetaValue
    mp)
                                   -> Map String String -> [(String, String)]
    forall k a. Map k a -> [(k, a)]
    M.toList (Map String String -> [(String, String)])
    -> Map String String -> [(String, String)]
    forall a b. (a -> b) -> a -> b
    $ (Text -> String) -> Map Text String -> Map String String
    forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
    M.mapKeys Text -> String
    TS.unpack (Map Text String -> Map String String)
    -> Map Text String -> Map String String
    forall a b. (a -> b) -> a -> b
    $ (MetaValue -> String) -> Map Text MetaValue -> Map Text String
    forall a b k. (a -> b) -> Map k a -> Map k b
    M.map MetaValue -> String
    metaValueToString Map Text MetaValue
    mp
                                _  -> []
            calibreFields :: [(String, String)]
    calibreFields = case Text -> Meta -> Maybe MetaValue
    lookupMeta "calibre" Meta
    meta of
                                Just (MetaMap mp :: Map Text MetaValue
    mp)
                                   -> Map String String -> [(String, String)]
    forall k a. Map k a -> [(k, a)]
    M.toList (Map String String -> [(String, String)])
    -> Map String String -> [(String, String)]
    forall a b. (a -> b) -> a -> b
    $ (Text -> String) -> Map Text String -> Map String String
    forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
    M.mapKeys Text -> String
    TS.unpack (Map Text String -> Map String String)
    -> Map Text String -> Map String String
    forall a b. (a -> b) -> a -> b
    $ (MetaValue -> String) -> Map Text MetaValue -> Map Text String
    forall a b k. (a -> b) -> Map k a -> Map k b
    M.map MetaValue -> String
    metaValueToString Map Text MetaValue
    mp
                                _  -> []

    -- | Produce an EPUB2 file from a Pandoc document.
    writeEPUB2 :: PandocMonad m
              => WriterOptions  -- ^ Writer options
              -> Pandoc         -- ^ Document to convert
              -> m B.ByteString
    writeEPUB2 :: WriterOptions -> Pandoc -> m ByteString
    writeEPUB2 = EPUBVersion -> WriterOptions -> Pandoc -> m ByteString
    forall (m :: * -> *).
    PandocMonad m =>
    EPUBVersion -> WriterOptions -> Pandoc -> m ByteString
    writeEPUB EPUBVersion
    EPUB2

    -- | Produce an EPUB3 file from a Pandoc document.
    writeEPUB3 :: PandocMonad m
              => WriterOptions  -- ^ Writer options
              -> Pandoc         -- ^ Document to convert
              -> m B.ByteString
    writeEPUB3 :: WriterOptions -> Pandoc -> m ByteString
    writeEPUB3 = EPUBVersion -> WriterOptions -> Pandoc -> m ByteString
    forall (m :: * -> *).
    PandocMonad m =>
    EPUBVersion -> WriterOptions -> Pandoc -> m ByteString
    writeEPUB EPUBVersion
    EPUB3

    -- | Produce an EPUB file from a Pandoc document.
    writeEPUB :: PandocMonad m
              => EPUBVersion
              -> WriterOptions  -- ^ Writer options
              -> Pandoc         -- ^ Document to convert
              -> m B.ByteString
    writeEPUB :: EPUBVersion -> WriterOptions -> Pandoc -> m ByteString
    writeEPUB epubVersion :: EPUBVersion
    epubVersion opts :: WriterOptions
    opts doc :: Pandoc
    doc = do
      let epubSubdir :: Text
    epubSubdir = WriterOptions -> Text
    writerEpubSubdirectory WriterOptions
    opts
      -- sanity check on epubSubdir
      Bool -> m () -> m ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless ((Char -> Bool) -> Text -> Bool
    TS.all (\c :: Char
    c -> Char -> Bool
    isAscii Char
    c Bool -> Bool -> Bool
    && Char -> Bool
    isAlphaNum Char
    c) Text
    epubSubdir) (m () -> m ()) -> m () -> m ()
    forall a b. (a -> b) -> a -> b
    $
        PandocError -> m ()
    forall e (m :: * -> *) a. MonadError e m => e -> m a
    throwError (PandocError -> m ()) -> PandocError -> m ()
    forall a b. (a -> b) -> a -> b
    $ Text -> PandocError
    PandocEpubSubdirectoryError Text
    epubSubdir
      let initState :: EPUBState
    initState = EPUBState :: [(String, (String, Maybe Entry))] -> Int -> String -> EPUBState
    EPUBState { stMediaPaths :: [(String, (String, Maybe Entry))]
    stMediaPaths = [], stMediaNextId :: Int
    stMediaNextId = 0, stEpubSubdir :: String
    stEpubSubdir = Text -> String
    TS.unpack Text
    epubSubdir }
      StateT EPUBState m ByteString -> EPUBState -> m ByteString
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT (EPUBVersion
    -> WriterOptions -> Pandoc -> StateT EPUBState m ByteString
    forall (m :: * -> *).
    PandocMonad m =>
    EPUBVersion -> WriterOptions -> Pandoc -> E m ByteString
    pandocToEPUB EPUBVersion
    epubVersion WriterOptions
    opts Pandoc
    doc) EPUBState
    initState

    pandocToEPUB :: PandocMonad m
                 => EPUBVersion
                 -> WriterOptions
                 -> Pandoc
                 -> E m B.ByteString
    pandocToEPUB :: EPUBVersion -> WriterOptions -> Pandoc -> E m ByteString
    pandocToEPUB version :: EPUBVersion
    version opts :: WriterOptions
    opts doc :: Pandoc
    doc = do
      -- handle pictures
      Pandoc meta :: Meta
    meta blocks :: [Block]
    blocks <- (Inline -> StateT EPUBState m Inline)
    -> Pandoc -> StateT EPUBState m Pandoc
    forall a b (m :: * -> *).
    (Walkable a b, Monad m, Applicative m, Functor m) =>
    (a -> m a) -> b -> m b
    walkM (WriterOptions -> Inline -> StateT EPUBState m Inline
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Inline -> E m Inline
    transformInline WriterOptions
    opts) Pandoc
    doc StateT EPUBState m Pandoc
    -> (Pandoc -> StateT EPUBState m Pandoc)
    -> StateT EPUBState m Pandoc
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>=
                            (Block -> StateT EPUBState m Block)
    -> Pandoc -> StateT EPUBState m Pandoc
    forall a b (m :: * -> *).
    (Walkable a b, Monad m, Applicative m, Functor m) =>
    (a -> m a) -> b -> m b
    walkM Block -> StateT EPUBState m Block
    forall (m :: * -> *). PandocMonad m => Block -> E m Block
    transformBlock
      [Entry]
    picEntries <- ((String, (String, Maybe Entry)) -> Maybe Entry)
    -> [(String, (String, Maybe Entry))] -> [Entry]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe ((String, Maybe Entry) -> Maybe Entry
    forall a b. (a, b) -> b
    snd ((String, Maybe Entry) -> Maybe Entry)
    -> ((String, (String, Maybe Entry)) -> (String, Maybe Entry))
    -> (String, (String, Maybe Entry))
    -> Maybe Entry
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String, (String, Maybe Entry)) -> (String, Maybe Entry)
    forall a b. (a, b) -> b
    snd) ([(String, (String, Maybe Entry))] -> [Entry])
    -> StateT EPUBState m [(String, (String, Maybe Entry))]
    -> StateT EPUBState m [Entry]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (EPUBState -> [(String, (String, Maybe Entry))])
    -> StateT EPUBState m [(String, (String, Maybe Entry))]
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets EPUBState -> [(String, (String, Maybe Entry))]
    stMediaPaths

      String
    epubSubdir <- (EPUBState -> String) -> StateT EPUBState m String
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets EPUBState -> String
    stEpubSubdir
      let epub3 :: Bool
    epub3 = EPUBVersion
    version EPUBVersion -> EPUBVersion -> Bool
    forall a. Eq a => a -> a -> Bool
    == EPUBVersion
    EPUB3
      let writeHtml :: WriterOptions -> Pandoc -> f ByteString
    writeHtml o :: WriterOptions
    o = (Text -> ByteString) -> f Text -> f ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Text -> ByteString
    UTF8.fromTextLazy (Text -> ByteString) -> (Text -> Text) -> Text -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Text
    TL.fromStrict) (f Text -> f ByteString)
    -> (Pandoc -> f Text) -> Pandoc -> f ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                          EPUBVersion -> WriterOptions -> Pandoc -> f Text
    forall (m :: * -> *).
    PandocMonad m =>
    EPUBVersion -> WriterOptions -> Pandoc -> m Text
    writeHtmlStringForEPUB EPUBVersion
    version WriterOptions
    o
      EPUBMetadata
    metadata <- WriterOptions -> Meta -> E m EPUBMetadata
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Meta -> E m EPUBMetadata
    getEPUBMetadata WriterOptions
    opts Meta
    meta

      let plainTitle :: String
    plainTitle = case Meta -> [Inline]
    docTitle' Meta
    meta of
                            [] -> case EPUBMetadata -> [Title]
    epubTitle EPUBMetadata
    metadata of
                                       []    -> "UNTITLED"
                                       (x :: Title
    x:_) -> Title -> String
    titleText Title
    x
                            x :: [Inline]
    x  -> Text -> String
    TS.unpack (Text -> String) -> Text -> String
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Text
    forall a. Walkable Inline a => a -> Text
    stringify [Inline]
    x

      -- stylesheet
      [ByteString]
    stylesheets <- case EPUBMetadata -> [String]
    epubStylesheets EPUBMetadata
    metadata of
                          [] -> (\x :: ByteString
    x -> [[ByteString] -> ByteString
    B.fromChunks [ByteString
    x]]) (ByteString -> [ByteString])
    -> StateT EPUBState m ByteString -> StateT EPUBState m [ByteString]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                                 String -> StateT EPUBState m ByteString
    forall (m :: * -> *). PandocMonad m => String -> m ByteString
    P.readDataFile "epub.css"
                          fs :: [String]
    fs -> (String -> E m ByteString)
    -> [String] -> StateT EPUBState m [ByteString]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM String -> E m ByteString
    forall (m :: * -> *). PandocMonad m => String -> m ByteString
    P.readFileLazy [String]
    fs
      [Entry]
    stylesheetEntries <- (ByteString -> Int -> StateT EPUBState m Entry)
    -> [ByteString] -> [Int] -> StateT EPUBState m [Entry]
    forall (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> m c) -> [a] -> [b] -> m [c]
    zipWithM
            (\bs :: ByteString
    bs n :: Int
    n -> String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry ("styles/stylesheet" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    n String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ".css") ByteString
    bs)
            [ByteString]
    stylesheets [(1 :: Int)..]

      let vars :: Context Text
    vars = Map Text (Val Text) -> Context Text
    forall a. Map Text (Val a) -> Context a
    Context (Map Text (Val Text) -> Context Text)
    -> Map Text (Val Text) -> Context Text
    forall a b. (a -> b) -> a -> b
    $
                   Text -> Map Text (Val Text) -> Map Text (Val Text)
    forall k a. Ord k => k -> Map k a -> Map k a
    M.delete "css" (Map Text (Val Text) -> Map Text (Val Text))
    -> (Map Text (Val Text) -> Map Text (Val Text))
    -> Map Text (Val Text)
    -> Map Text (Val Text)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                   Text -> Val Text -> Map Text (Val Text) -> Map Text (Val Text)
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    M.insert "epub3"
                     (String -> Val Text
    toVal' (String -> Val Text) -> String -> Val Text
    forall a b. (a -> b) -> a -> b
    $ if Bool
    epub3 then "true" else "false") (Map Text (Val Text) -> Map Text (Val Text))
    -> (Map Text (Val Text) -> Map Text (Val Text))
    -> Map Text (Val Text)
    -> Map Text (Val Text)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                   Text -> Val Text -> Map Text (Val Text) -> Map Text (Val Text)
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    M.insert "lang" (String -> Val Text
    toVal' (String -> Val Text) -> String -> Val Text
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> String
    epubLanguage EPUBMetadata
    metadata)
                 (Map Text (Val Text) -> Map Text (Val Text))
    -> Map Text (Val Text) -> Map Text (Val Text)
    forall a b. (a -> b) -> a -> b
    $ Context Text -> Map Text (Val Text)
    forall a. Context a -> Map Text (Val a)
    unContext (Context Text -> Map Text (Val Text))
    -> Context Text -> Map Text (Val Text)
    forall a b. (a -> b) -> a -> b
    $ WriterOptions -> Context Text
    writerVariables WriterOptions
    opts

      let cssvars :: Bool -> Context Text
    cssvars useprefix :: Bool
    useprefix = Map Text (Val Text) -> Context Text
    forall a. Map Text (Val a) -> Context a
    Context (Map Text (Val Text) -> Context Text)
    -> Map Text (Val Text) -> Context Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Val Text -> Map Text (Val Text) -> Map Text (Val Text)
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    M.insert "css"
                               ([Val Text] -> Val Text
    forall a. [Val a] -> Val a
    ListVal ([Val Text] -> Val Text) -> [Val Text] -> Val Text
    forall a b. (a -> b) -> a -> b
    $ (Entry -> Val Text) -> [Entry] -> [Val Text]
    forall a b. (a -> b) -> [a] -> [b]
    map
                                 (\e :: Entry
    e -> String -> Val Text
    toVal' (String -> Val Text) -> String -> Val Text
    forall a b. (a -> b) -> a -> b
    $
                                    (if Bool
    useprefix then "../" else "") String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <>
                                    String -> ShowS
    makeRelative String
    epubSubdir (Entry -> String
    eRelativePath Entry
    e))
                                 [Entry]
    stylesheetEntries)
                                 Map Text (Val Text)
    forall a. Monoid a => a
    mempty

      let opts' :: WriterOptions
    opts' = WriterOptions
    opts{ writerEmailObfuscation :: ObfuscationMethod
    writerEmailObfuscation = ObfuscationMethod
    NoObfuscation
                      , writerSectionDivs :: Bool
    writerSectionDivs = Bool
    True
                      , writerVariables :: Context Text
    writerVariables = Context Text
    vars
                      , writerHTMLMathMethod :: HTMLMathMethod
    writerHTMLMathMethod =
                           if Bool
    epub3
                              then HTMLMathMethod
    MathML
                              else WriterOptions -> HTMLMathMethod
    writerHTMLMathMethod WriterOptions
    opts
                      , writerWrapText :: WrapOption
    writerWrapText = WrapOption
    WrapAuto }

      -- cover page
      (cpgEntry :: [Entry]
    cpgEntry, cpicEntry :: [Entry]
    cpicEntry) <-
                    case EPUBMetadata -> Maybe String
    epubCoverImage EPUBMetadata
    metadata of
                         Nothing   -> ([Entry], [Entry]) -> StateT EPUBState m ([Entry], [Entry])
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([],[])
                         Just img :: String
    img  -> do
                           let coverImage :: String
    coverImage = ShowS
    takeFileName String
    img
                           ByteString
    imgContent <- m ByteString -> E m ByteString
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m ByteString -> E m ByteString) -> m ByteString -> E m ByteString
    forall a b. (a -> b) -> a -> b
    $ String -> m ByteString
    forall (m :: * -> *). PandocMonad m => String -> m ByteString
    P.readFileLazy String
    img
                           (coverImageWidth :: Integer
    coverImageWidth, coverImageHeight :: Integer
    coverImageHeight) <-
                                 case WriterOptions -> ByteString -> Either Text ImageSize
    imageSize WriterOptions
    opts' (ByteString -> ByteString
    B.toStrict ByteString
    imgContent) of
                                   Right sz :: ImageSize
    sz  -> (Integer, Integer) -> StateT EPUBState m (Integer, Integer)
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((Integer, Integer) -> StateT EPUBState m (Integer, Integer))
    -> (Integer, Integer) -> StateT EPUBState m (Integer, Integer)
    forall a b. (a -> b) -> a -> b
    $ ImageSize -> (Integer, Integer)
    sizeInPixels ImageSize
    sz
                                   Left err' :: Text
    err' -> (0, 0) (Integer, Integer)
    -> StateT EPUBState m () -> StateT EPUBState m (Integer, Integer)
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ LogMessage -> StateT EPUBState m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report
                                     (Text -> Text -> LogMessage
    CouldNotDetermineImageSize (String -> Text
    TS.pack String
    img) Text
    err')
                           ByteString
    cpContent <- m ByteString -> E m ByteString
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m ByteString -> E m ByteString) -> m ByteString -> E m ByteString
    forall a b. (a -> b) -> a -> b
    $ WriterOptions -> Pandoc -> m ByteString
    forall (f :: * -> *).
    PandocMonad f =>
    WriterOptions -> Pandoc -> f ByteString
    writeHtml
                                WriterOptions
    opts'{ writerVariables :: Context Text
    writerVariables =
                                       Map Text (Val Text) -> Context Text
    forall a. Map Text (Val a) -> Context a
    Context ([(Text, Val Text)] -> Map Text (Val Text)
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList [
                                        ("coverpage", String -> Val Text
    toVal' "true"),
                                        ("pagetitle", Text -> Val Text
    forall a b. ToContext a b => b -> Val a
    toVal (Text -> Val Text) -> Text -> Val Text
    forall a b. (a -> b) -> a -> b
    $
                                          Text -> Text
    escapeStringForXML (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ String -> Text
    TS.pack String
    plainTitle),
                                        ("cover-image", String -> Val Text
    toVal' String
    coverImage),
                                        ("cover-image-width", String -> Val Text
    toVal' (String -> Val Text) -> String -> Val Text
    forall a b. (a -> b) -> a -> b
    $
                                           Integer -> String
    forall a. Show a => a -> String
    show Integer
    coverImageWidth),
                                        ("cover-image-height", String -> Val Text
    toVal' (String -> Val Text) -> String -> Val Text
    forall a b. (a -> b) -> a -> b
    $
                                           Integer -> String
    forall a. Show a => a -> String
    show Integer
    coverImageHeight)]) Context Text -> Context Text -> Context Text
    forall a. Semigroup a => a -> a -> a
    <>
                                         Bool -> Context Text
    cssvars Bool
    True Context Text -> Context Text -> Context Text
    forall a. Semigroup a => a -> a -> a
    <> Context Text
    vars }
                                (Meta -> [Block] -> Pandoc
    Pandoc Meta
    meta [])
                           Entry
    coverEntry <- String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry "text/cover.xhtml" ByteString
    cpContent
                           Entry
    coverImageEntry <- String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry ("media/" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    coverImage)
                                                 ByteString
    imgContent
                           ([Entry], [Entry]) -> StateT EPUBState m ([Entry], [Entry])
    forall (m :: * -> *) a. Monad m => a -> m a
    return ( [ Entry
    coverEntry ]
                                  , [ Entry
    coverImageEntry ] )

      -- title page
      ByteString
    tpContent <- m ByteString -> E m ByteString
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m ByteString -> E m ByteString) -> m ByteString -> E m ByteString
    forall a b. (a -> b) -> a -> b
    $ WriterOptions -> Pandoc -> m ByteString
    forall (f :: * -> *).
    PandocMonad f =>
    WriterOptions -> Pandoc -> f ByteString
    writeHtml WriterOptions
    opts'{
                                      writerVariables :: Context Text
    writerVariables =
                                          Map Text (Val Text) -> Context Text
    forall a. Map Text (Val a) -> Context a
    Context ([(Text, Val Text)] -> Map Text (Val Text)
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList [
                                            ("titlepage", String -> Val Text
    toVal' "true"),
                                            ("body-type",  String -> Val Text
    toVal' "frontmatter"),
                                            ("pagetitle", Text -> Val Text
    forall a b. ToContext a b => b -> Val a
    toVal (Text -> Val Text) -> Text -> Val Text
    forall a b. (a -> b) -> a -> b
    $
                                                Text -> Text
    escapeStringForXML (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ String -> Text
    TS.pack String
    plainTitle)])
                                          Context Text -> Context Text -> Context Text
    forall a. Semigroup a => a -> a -> a
    <> Bool -> Context Text
    cssvars Bool
    True Context Text -> Context Text -> Context Text
    forall a. Semigroup a => a -> a -> a
    <> Context Text
    vars }
                                   (Meta -> [Block] -> Pandoc
    Pandoc Meta
    meta [])
      Entry
    tpEntry <- String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry "text/title_page.xhtml" ByteString
    tpContent

      -- handle fonts
      let matchingGlob :: String -> t m [String]
    matchingGlob f :: String
    f = do
            [String]
    xs <- m [String] -> t m [String]
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m [String] -> t m [String]) -> m [String] -> t m [String]
    forall a b. (a -> b) -> a -> b
    $ String -> m [String]
    forall (m :: * -> *). PandocMonad m => String -> m [String]
    P.glob String
    f
            Bool -> t m () -> t m ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when ([String] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [String]
    xs) (t m () -> t m ()) -> t m () -> t m ()
    forall a b. (a -> b) -> a -> b
    $
              LogMessage -> t m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> t m ()) -> LogMessage -> t m ()
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> LogMessage
    CouldNotFetchResource (String -> Text
    TS.pack String
    f) "glob did not match any font files"
            [String] -> t m [String]
    forall (m :: * -> *) a. Monad m => a -> m a
    return [String]
    xs
      let mkFontEntry :: String -> StateT EPUBState m Entry
    mkFontEntry f :: String
    f = String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry ("fonts/" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ShowS
    takeFileName String
    f) (ByteString -> StateT EPUBState m Entry)
    -> StateT EPUBState m ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<<
                            m ByteString -> StateT EPUBState m ByteString
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (String -> m ByteString
    forall (m :: * -> *). PandocMonad m => String -> m ByteString
    P.readFileLazy String
    f)
      [String]
    fontFiles <- [[String]] -> [String]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[String]] -> [String])
    -> StateT EPUBState m [[String]] -> StateT EPUBState m [String]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (String -> StateT EPUBState m [String])
    -> [String] -> StateT EPUBState m [[String]]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM String -> StateT EPUBState m [String]
    forall (t :: (* -> *) -> * -> *) (m :: * -> *).
    (MonadTrans t, PandocMonad m, PandocMonad (t m)) =>
    String -> t m [String]
    matchingGlob (WriterOptions -> [String]
    writerEpubFonts WriterOptions
    opts')
      [Entry]
    fontEntries <- (String -> StateT EPUBState m Entry)
    -> [String] -> StateT EPUBState m [Entry]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM String -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> StateT EPUBState m Entry
    mkFontEntry [String]
    fontFiles

      -- set page progression direction attribution
      let progressionDirection :: [(String, String)]
    progressionDirection = case EPUBMetadata -> Maybe ProgressionDirection
    epubPageDirection EPUBMetadata
    metadata of
                                      Just LTR | Bool
    epub3 ->
                                        [("page-progression-direction", "ltr")]
                                      Just RTL | Bool
    epub3 ->
                                        [("page-progression-direction", "rtl")]
                                      _  -> []

      -- body pages

      let chapterHeaderLevel :: Int
    chapterHeaderLevel = WriterOptions -> Int
    writerEpubChapterLevel WriterOptions
    opts

      let isChapterHeader :: Block -> Bool
    isChapterHeader (Div _ (Header n :: Int
    n _ _:_)) = Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    chapterHeaderLevel
          isChapterHeader _ = Bool
    False

      let secsToChapters :: [Block] -> [Chapter]
          secsToChapters :: [Block] -> [Chapter]
    secsToChapters [] = []
          secsToChapters (d :: Block
    d@(Div attr :: Attr
    attr (h :: Block
    h@(Header lvl :: Int
    lvl _ _) : bs :: [Block]
    bs)) : rest :: [Block]
    rest)
            | Int
    chapterHeaderLevel Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    lvl =
               [Block] -> Chapter
    Chapter [Block
    d] Chapter -> [Chapter] -> [Chapter]
    forall a. a -> [a] -> [a]
    : [Block] -> [Chapter]
    secsToChapters [Block]
    rest
            | Int
    chapterHeaderLevel Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    lvl =
               [Block] -> Chapter
    Chapter [Attr -> [Block] -> Block
    Div Attr
    attr (Block
    hBlock -> [Block] -> [Block]
    forall a. a -> [a] -> [a]
    :[Block]
    xs)] Chapter -> [Chapter] -> [Chapter]
    forall a. a -> [a] -> [a]
    :
               [Block] -> [Chapter]
    secsToChapters [Block]
    ys [Chapter] -> [Chapter] -> [Chapter]
    forall a. [a] -> [a] -> [a]
    ++ [Block] -> [Chapter]
    secsToChapters [Block]
    rest
                 where (xs :: [Block]
    xs, ys :: [Block]
    ys) = (Block -> Bool) -> [Block] -> ([Block], [Block])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break Block -> Bool
    isChapterHeader [Block]
    bs
          secsToChapters bs :: [Block]
    bs =
              (if [Block] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Block]
    xs then [Chapter] -> [Chapter]
    forall a. a -> a
    id else ([Block] -> Chapter
    Chapter [Block]
    xs Chapter -> [Chapter] -> [Chapter]
    forall a. a -> [a] -> [a]
    :)) ([Chapter] -> [Chapter]) -> [Chapter] -> [Chapter]
    forall a b. (a -> b) -> a -> b
    $ [Block] -> [Chapter]
    secsToChapters [Block]
    ys
                where (xs :: [Block]
    xs, ys :: [Block]
    ys) = (Block -> Bool) -> [Block] -> ([Block], [Block])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break Block -> Bool
    isChapterHeader [Block]
    bs

      -- add level 1 header to beginning if none there
      let secs :: [Block]
    secs = Bool -> Maybe Int -> [Block] -> [Block]
    makeSections Bool
    True Maybe Int
    forall a. Maybe a
    Nothing
                  ([Block] -> [Block]) -> [Block] -> [Block]
    forall a b. (a -> b) -> a -> b
    $ WriterOptions -> [Block] -> [Block]
    addIdentifiers WriterOptions
    opts
                  ([Block] -> [Block]) -> [Block] -> [Block]
    forall a b. (a -> b) -> a -> b
    $ case [Block]
    blocks of
                      (Div _
                        (Header{}:_) : _) -> [Block]
    blocks
                      (Header 1 _ _ : _)  -> [Block]
    blocks
                      _                   -> Int -> Attr -> [Inline] -> Block
    Header 1 ("",["unnumbered"],[])
                                                 (Meta -> [Inline]
    docTitle' Meta
    meta) Block -> [Block] -> [Block]
    forall a. a -> [a] -> [a]
    : [Block]
    blocks

      let chapters' :: [Chapter]
    chapters' = [Block] -> [Chapter]
    secsToChapters [Block]
    secs

      let extractLinkURL' :: Int -> Inline -> [(TS.Text, TS.Text)]
          extractLinkURL' :: Int -> Inline -> [(Text, Text)]
    extractLinkURL' num :: Int
    num (Span (ident :: Text
    ident, _, _) _)
            | Bool -> Bool
    not (Text -> Bool
    TS.null Text
    ident) = [(Text
    ident, String -> Text
    TS.pack (Int -> String
    showChapter Int
    num) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "#" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    ident)]
          extractLinkURL' _ _ = []

      let extractLinkURL :: Int -> Block -> [(TS.Text, TS.Text)]
          extractLinkURL :: Int -> Block -> [(Text, Text)]
    extractLinkURL num :: Int
    num (Div (ident :: Text
    ident, _, _) _)
            | Bool -> Bool
    not (Text -> Bool
    TS.null Text
    ident) = [(Text
    ident, String -> Text
    TS.pack (Int -> String
    showChapter Int
    num) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "#" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    ident)]
          extractLinkURL num :: Int
    num (Header _ (ident :: Text
    ident, _, _) _)
            | Bool -> Bool
    not (Text -> Bool
    TS.null Text
    ident) = [(Text
    ident, String -> Text
    TS.pack (Int -> String
    showChapter Int
    num) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "#" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    ident)]
          extractLinkURL num :: Int
    num b :: Block
    b = (Inline -> [(Text, Text)]) -> Block -> [(Text, Text)]
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query (Int -> Inline -> [(Text, Text)]
    extractLinkURL' Int
    num) Block
    b

      let reftable :: [(Text, Text)]
    reftable = [[(Text, Text)]] -> [(Text, Text)]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[(Text, Text)]] -> [(Text, Text)])
    -> [[(Text, Text)]] -> [(Text, Text)]
    forall a b. (a -> b) -> a -> b
    $ (Chapter -> Int -> [(Text, Text)])
    -> [Chapter] -> [Int] -> [[(Text, Text)]]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (\(Chapter bs :: [Block]
    bs) num :: Int
    num ->
                                        (Block -> [(Text, Text)]) -> [Block] -> [(Text, Text)]
    forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
    query (Int -> Block -> [(Text, Text)]
    extractLinkURL Int
    num) [Block]
    bs)
                              [Chapter]
    chapters' [1..]

      let fixInternalReferences :: Inline -> Inline
          fixInternalReferences :: Inline -> Inline
    fixInternalReferences (Link attr :: Attr
    attr lab :: [Inline]
    lab (src :: Text
    src, tit :: Text
    tit))
            | Just ('#', xs :: Text
    xs) <- Text -> Maybe (Char, Text)
    TS.uncons Text
    src = case Text -> [(Text, Text)] -> Maybe Text
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Text
    xs [(Text, Text)]
    reftable of
                 Just ys :: Text
    ys -> Attr -> [Inline] -> (Text, Text) -> Inline
    Link Attr
    attr [Inline]
    lab (Text
    ys, Text
    tit)
                 Nothing -> Attr -> [Inline] -> (Text, Text) -> Inline
    Link Attr
    attr [Inline]
    lab (Text
    src, Text
    tit)
          fixInternalReferences x :: Inline
    x = Inline
    x

      -- internal reference IDs change when we chunk the file,
      -- so that '#my-header-1' might turn into 'chap004.xhtml#my-header'.
      -- this fixes that:
      let chapters :: [Chapter]
    chapters = (Chapter -> Chapter) -> [Chapter] -> [Chapter]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Chapter bs :: [Block]
    bs) ->
                             [Block] -> Chapter
    Chapter ([Block] -> Chapter) -> [Block] -> Chapter
    forall a b. (a -> b) -> a -> b
    $ (Inline -> Inline) -> [Block] -> [Block]
    forall a b. Walkable a b => (a -> a) -> b -> b
    walk Inline -> Inline
    fixInternalReferences [Block]
    bs)
                     [Chapter]
    chapters'

      let chapToEntry :: Int -> Chapter -> StateT EPUBState m Entry
    chapToEntry num :: Int
    num (Chapter bs :: [Block]
    bs) =
            String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry ("text/" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    showChapter Int
    num) (ByteString -> StateT EPUBState m Entry)
    -> StateT EPUBState m ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<<
            WriterOptions -> Pandoc -> StateT EPUBState m ByteString
    forall (f :: * -> *).
    PandocMonad f =>
    WriterOptions -> Pandoc -> f ByteString
    writeHtml WriterOptions
    opts'{ writerVariables :: Context Text
    writerVariables =
                                Map Text (Val Text) -> Context Text
    forall a. Map Text (Val a) -> Context a
    Context ([(Text, Val Text)] -> Map Text (Val Text)
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList
                                         [("body-type", String -> Val Text
    toVal' String
    bodyType),
                                          ("pagetitle", String -> Val Text
    toVal' (String -> Val Text) -> String -> Val Text
    forall a b. (a -> b) -> a -> b
    $
                                               Int -> String
    showChapter Int
    num)])
                                Context Text -> Context Text -> Context Text
    forall a. Semigroup a => a -> a -> a
    <> Bool -> Context Text
    cssvars Bool
    True Context Text -> Context Text -> Context Text
    forall a. Semigroup a => a -> a -> a
    <> Context Text
    vars } Pandoc
    pdoc
             where (pdoc :: Pandoc
    pdoc, bodyType :: String
    bodyType) =
                     case [Block]
    bs of
                         (Div (_,"section":_,kvs :: [(Text, Text)]
    kvs)
                           (Header _ _ xs :: [Inline]
    xs : _) : _) ->
                           -- remove notes or we get doubled footnotes
                           (Meta -> [Block] -> Pandoc
    Pandoc (Text -> Many Inline -> Meta -> Meta
    forall a b. (HasMeta a, ToMetaValue b) => Text -> b -> a -> a
    setMeta "title"
                               ((Inline -> Inline) -> Many Inline -> Many Inline
    forall a b. Walkable a b => (a -> a) -> b -> b
    walk Inline -> Inline
    removeNote (Many Inline -> Many Inline) -> Many Inline -> Many Inline
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Many Inline
    forall a. [a] -> Many a
    fromList [Inline]
    xs) Meta
    nullMeta) [Block]
    bs,
                            case Text -> [(Text, Text)] -> Maybe Text
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup "epub:type" [(Text, Text)]
    kvs of
                                 Nothing -> "bodymatter"
                                 Just x :: Text
    x
                                   | Text
    x Text -> [Text] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Text]
    frontMatterTypes -> "frontmatter"
                                   | Text
    x Text -> [Text] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Text]
    backMatterTypes  -> "backmatter"
                                   | Bool
    otherwise                 -> "bodymatter")
                         _                   -> (Meta -> [Block] -> Pandoc
    Pandoc Meta
    nullMeta [Block]
    bs, "bodymatter")
                   frontMatterTypes :: [Text]
    frontMatterTypes = ["prologue", "abstract", "acknowledgments",
                                       "copyright-page", "dedication",
                                       "credits", "keywords", "imprint",
                                       "contributors", "other-credits",
                                       "errata", "revision-history",
                                       "titlepage", "halftitlepage", "seriespage",
                                       "foreword", "preface",
                                       "seriespage", "titlepage"]
                   backMatterTypes :: [Text]
    backMatterTypes = ["appendix", "colophon", "bibliography",
                                      "index"]

      [Entry]
    chapterEntries <- (Int -> Chapter -> StateT EPUBState m Entry)
    -> [Int] -> [Chapter] -> StateT EPUBState m [Entry]
    forall (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> m c) -> [a] -> [b] -> m [c]
    zipWithM Int -> Chapter -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Chapter -> StateT EPUBState m Entry
    chapToEntry [1..] [Chapter]
    chapters

      -- incredibly inefficient (TODO):
      let containsMathML :: Entry -> Bool
    containsMathML ent :: Entry
    ent = Bool
    epub3 Bool -> Bool -> Bool
    &&
                               "<math" String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isInfixOf`
            ByteString -> String
    B8.unpack (Entry -> ByteString
    fromEntry Entry
    ent)
      let containsSVG :: Entry -> Bool
    containsSVG ent :: Entry
    ent    = Bool
    epub3 Bool -> Bool -> Bool
    &&
                               "<svg" String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isInfixOf`
            ByteString -> String
    B8.unpack (Entry -> ByteString
    fromEntry Entry
    ent)
      let props :: Entry -> [a]
    props ent :: Entry
    ent = ["mathml" | Entry -> Bool
    containsMathML Entry
    ent] [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    ++ ["svg" | Entry -> Bool
    containsSVG Entry
    ent]

      -- contents.opf
      let chapterNode :: Entry -> Element
    chapterNode ent :: Entry
    ent = String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "item" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                               ([("id", ShowS
    toId ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ String -> ShowS
    makeRelative String
    epubSubdir
                                             ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ Entry -> String
    eRelativePath Entry
    ent),
                                 ("href", String -> ShowS
    makeRelative String
    epubSubdir
                                          ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ Entry -> String
    eRelativePath Entry
    ent),
                                 ("media-type", "application/xhtml+xml")]
                                [(String, String)] -> [(String, String)] -> [(String, String)]
    forall a. [a] -> [a] -> [a]
    ++ case Entry -> [String]
    forall a. IsString a => Entry -> [a]
    props Entry
    ent of
                                        [] -> []
                                        xs :: [String]
    xs -> [("properties", [String] -> String
    unwords [String]
    xs)])
                            (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()

      let chapterRefNode :: Entry -> Element
    chapterRefNode ent :: Entry
    ent = String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "itemref" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                                 [("idref", ShowS
    toId ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ String -> ShowS
    makeRelative String
    epubSubdir
                                                 ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ Entry -> String
    eRelativePath Entry
    ent)] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
      let pictureNode :: Entry -> Element
    pictureNode ent :: Entry
    ent = String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "item" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                               [("id", ShowS
    toId ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ String -> ShowS
    makeRelative String
    epubSubdir
                                            ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ Entry -> String
    eRelativePath Entry
    ent),
                                ("href", String -> ShowS
    makeRelative String
    epubSubdir
                                         ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ Entry -> String
    eRelativePath Entry
    ent),
                                ("media-type",
                                   String -> (Text -> String) -> Maybe Text -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe "application/octet-stream" Text -> String
    TS.unpack
                                   (Maybe Text -> String) -> Maybe Text -> String
    forall a b. (a -> b) -> a -> b
    $ String -> Maybe Text
    mediaTypeOf (String -> Maybe Text) -> String -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Entry -> String
    eRelativePath Entry
    ent)] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
      let fontNode :: Entry -> Element
    fontNode ent :: Entry
    ent = String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "item" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                               [("id", ShowS
    toId ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ String -> ShowS
    makeRelative String
    epubSubdir
                                            ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ Entry -> String
    eRelativePath Entry
    ent),
                                ("href", String -> ShowS
    makeRelative String
    epubSubdir
                                         ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ Entry -> String
    eRelativePath Entry
    ent),
                                ("media-type", String -> (Text -> String) -> Maybe Text -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe "" Text -> String
    TS.unpack (Maybe Text -> String) -> Maybe Text -> String
    forall a b. (a -> b) -> a -> b
    $
                                      String -> Maybe Text
    getMimeType (String -> Maybe Text) -> String -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Entry -> String
    eRelativePath Entry
    ent)] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()

      let tocTitle :: String
    tocTitle = String -> (MetaValue -> String) -> Maybe MetaValue -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe String
    plainTitle
                       MetaValue -> String
    metaValueToString (Maybe MetaValue -> String) -> Maybe MetaValue -> String
    forall a b. (a -> b) -> a -> b
    $ Text -> Meta -> Maybe MetaValue
    lookupMeta "toc-title" Meta
    meta
      String
    uuid <- case EPUBMetadata -> [Identifier]
    epubIdentifier EPUBMetadata
    metadata of
                (x :: Identifier
    x:_) -> String -> StateT EPUBState m String
    forall (m :: * -> *) a. Monad m => a -> m a
    return (String -> StateT EPUBState m String)
    -> String -> StateT EPUBState m String
    forall a b. (a -> b) -> a -> b
    $ Identifier -> String
    identifierText Identifier
    x  -- use first identifier as UUID
                []    -> PandocError -> StateT EPUBState m String
    forall e (m :: * -> *) a. MonadError e m => e -> m a
    throwError (PandocError -> StateT EPUBState m String)
    -> PandocError -> StateT EPUBState m String
    forall a b. (a -> b) -> a -> b
    $ Text -> PandocError
    PandocShouldNeverHappenError "epubIdentifier is null"  -- shouldn't happen
      UTCTime
    currentTime <- m UTCTime -> StateT EPUBState m UTCTime
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m UTCTime
    forall (m :: * -> *). PandocMonad m => m UTCTime
    P.getCurrentTime
      let contentsData :: ByteString
    contentsData = String -> ByteString
    UTF8.fromStringLazy (String -> ByteString) -> String -> ByteString
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    ppTopElement (Element -> String) -> Element -> String
    forall a b. (a -> b) -> a -> b
    $
            String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "package" ([Element] -> Element)
    -> [(String, String)] -> [Element] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
              ([("version", case EPUBVersion
    version of
                                 EPUB2 -> "2.0"
                                 EPUB3 -> "3.0")
               ,("xmlns","http://www.idpf.org/2007/opf")
               ,("unique-identifier","epub-id-1")
               ] [(String, String)] -> [(String, String)] -> [(String, String)]
    forall a. [a] -> [a] -> [a]
    ++
               [("prefix","ibooks: http://vocabulary.itunes.apple.com/rdf/ibooks/vocabulary-extensions-1.0/") | EPUBVersion
    version EPUBVersion -> EPUBVersion -> Bool
    forall a. Eq a => a -> a -> Bool
    == EPUBVersion
    EPUB3]) ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
              [ EPUBVersion -> EPUBMetadata -> UTCTime -> Element
    metadataElement EPUBVersion
    version EPUBMetadata
    metadata UTCTime
    currentTime
              , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "manifest" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
                 [ String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "item" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("id","ncx"), ("href","toc.ncx")
                                  ,("media-type","application/x-dtbncx+xml")] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
                 , String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "item" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! ([("id","nav")
                                   ,("href","nav.xhtml")
                                   ,("media-type","application/xhtml+xml")] [(String, String)] -> [(String, String)] -> [(String, String)]
    forall a. [a] -> [a] -> [a]
    ++
                                   [("properties","nav") | Bool
    epub3 ]) (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
                 ] [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                 [ String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "item" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("id","stylesheet" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    n), ("href",String
    fp)
                                  ,("media-type","text/css")] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ () |
                                 (Int
    n :: Int, fp :: String
    fp) <- [Int] -> [String] -> [(Int, String)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [1..] ((Entry -> String) -> [Entry] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map
                                   (String -> ShowS
    makeRelative String
    epubSubdir ShowS -> (Entry -> String) -> Entry -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Entry -> String
    eRelativePath)
                                   [Entry]
    stylesheetEntries) ] [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                 (Entry -> Element) -> [Entry] -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map Entry -> Element
    chapterNode ([Entry]
    cpgEntry [Entry] -> [Entry] -> [Entry]
    forall a. [a] -> [a] -> [a]
    ++ (Entry
    tpEntry Entry -> [Entry] -> [Entry]
    forall a. a -> [a] -> [a]
    : [Entry]
    chapterEntries)) [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                 (case [Entry]
    cpicEntry of
                        []    -> []
                        (x :: Entry
    x:_) -> [[Attr] -> Element -> Element
    add_attrs
                                  [QName -> String -> Attr
    Attr (String -> QName
    unqual "properties") "cover-image" | Bool
    epub3]
                                  (Entry -> Element
    pictureNode Entry
    x)]) [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                 (Entry -> Element) -> [Entry] -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map Entry -> Element
    pictureNode [Entry]
    picEntries [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                 (Entry -> Element) -> [Entry] -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map Entry -> Element
    fontNode [Entry]
    fontEntries
              , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "spine" ([Element] -> Element)
    -> [(String, String)] -> [Element] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! (
                 ("toc","ncx") (String, String) -> [(String, String)] -> [(String, String)]
    forall a. a -> [a] -> [a]
    : [(String, String)]
    progressionDirection) ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
                  case EPUBMetadata -> Maybe String
    epubCoverImage EPUBMetadata
    metadata of
                        Nothing -> []
                        Just _ -> [ String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "itemref" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                                    [("idref", "cover_xhtml")] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ () ]
                  [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ ((String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "itemref" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("idref", "title_page_xhtml")
                                         ,("linear",
                                             case Text -> Meta -> Maybe MetaValue
    lookupMeta "title" Meta
    meta of
                                                   Just _  -> "yes"
                                                   Nothing -> "no")] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()) Element -> [Element] -> [Element]
    forall a. a -> [a] -> [a]
    :
                      [String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "itemref" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("idref", "nav")] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
                             | WriterOptions -> Bool
    writerTableOfContents WriterOptions
    opts ] [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                      (Entry -> Element) -> [Entry] -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map Entry -> Element
    chapterRefNode [Entry]
    chapterEntries)
              , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "guide" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
                 [ String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "reference" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                       [("type","toc"),("title", String
    tocTitle),
                        ("href","nav.xhtml")] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
                 ] [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                 [ String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "reference" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                       [("type","cover")
                       ,("title","Cover")
                       ,("href","text/cover.xhtml")] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
                   | Maybe String -> Bool
    forall a. Maybe a -> Bool
    isJust (EPUBMetadata -> Maybe String
    epubCoverImage EPUBMetadata
    metadata)
                 ]
              ]
      Entry
    contentsEntry <- String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry "content.opf" ByteString
    contentsData

      -- toc.ncx
      let tocLevel :: Int
    tocLevel = WriterOptions -> Int
    writerTOCDepth WriterOptions
    opts

      let navPointNode :: PandocMonad m
                       => (Int -> [Inline] -> TS.Text -> [Element] -> Element)
                       -> Block -> StateT Int m [Element]
          navPointNode :: (Int -> [Inline] -> Text -> [Element] -> Element)
    -> Block -> StateT Int m [Element]
    navPointNode formatter :: Int -> [Inline] -> Text -> [Element] -> Element
    formatter (Div (ident :: Text
    ident,_,_)
                                    (Header lvl :: Int
    lvl (_,_,kvs :: [(Text, Text)]
    kvs) ils :: [Inline]
    ils : children :: [Block]
    children)) =
            if Int
    lvl Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    tocLevel
               then [Element] -> StateT Int m [Element]
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
               else do
                 Int
    n <- StateT Int m Int
    forall s (m :: * -> *). MonadState s m => m s
    get
                 (Int -> Int) -> StateT Int m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify (Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +1)
                 let num :: Text
    num = Text -> Maybe Text -> Text
    forall a. a -> Maybe a -> a
    fromMaybe "" (Maybe Text -> Text) -> Maybe Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text -> [(Text, Text)] -> Maybe Text
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup "number" [(Text, Text)]
    kvs
                 let tit :: [Inline]
    tit = if WriterOptions -> Bool
    writerNumberSections WriterOptions
    opts Bool -> Bool -> Bool
    && Bool -> Bool
    not (Text -> Bool
    TS.null Text
    num)
                              then Attr -> [Inline] -> Inline
    Span ("", ["section-header-number"], [])
                                    [Text -> Inline
    Str Text
    num] Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    : Inline
    Space Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    : [Inline]
    ils
                              else [Inline]
    ils
                 Text
    src <- case Text -> [(Text, Text)] -> Maybe Text
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Text
    ident [(Text, Text)]
    reftable of
                          Just x :: Text
    x  -> Text -> StateT Int m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    x
                          Nothing -> PandocError -> StateT Int m Text
    forall e (m :: * -> *) a. MonadError e m => e -> m a
    throwError (PandocError -> StateT Int m Text)
    -> PandocError -> StateT Int m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> PandocError
    PandocSomeError (Text -> PandocError) -> Text -> PandocError
    forall a b. (a -> b) -> a -> b
    $
                                        Text
    ident Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> " not found in reftable"
                 [Element]
    subs <- [[Element]] -> [Element]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[Element]] -> [Element])
    -> StateT Int m [[Element]] -> StateT Int m [Element]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Block -> StateT Int m [Element])
    -> [Block] -> StateT Int m [[Element]]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM ((Int -> [Inline] -> Text -> [Element] -> Element)
    -> Block -> StateT Int m [Element]
    forall (m :: * -> *).
    PandocMonad m =>
    (Int -> [Inline] -> Text -> [Element] -> Element)
    -> Block -> StateT Int m [Element]
    navPointNode Int -> [Inline] -> Text -> [Element] -> Element
    formatter) [Block]
    children
                 [Element] -> StateT Int m [Element]
    forall (m :: * -> *) a. Monad m => a -> m a
    return [Int -> [Inline] -> Text -> [Element] -> Element
    formatter Int
    n [Inline]
    tit Text
    src [Element]
    subs]
          navPointNode formatter :: Int -> [Inline] -> Text -> [Element] -> Element
    formatter (Div _ bs :: [Block]
    bs) =
            [[Element]] -> [Element]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[Element]] -> [Element])
    -> StateT Int m [[Element]] -> StateT Int m [Element]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Block -> StateT Int m [Element])
    -> [Block] -> StateT Int m [[Element]]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM ((Int -> [Inline] -> Text -> [Element] -> Element)
    -> Block -> StateT Int m [Element]
    forall (m :: * -> *).
    PandocMonad m =>
    (Int -> [Inline] -> Text -> [Element] -> Element)
    -> Block -> StateT Int m [Element]
    navPointNode Int -> [Inline] -> Text -> [Element] -> Element
    formatter) [Block]
    bs
          navPointNode _ _ = [Element] -> StateT Int m [Element]
    forall (m :: * -> *) a. Monad m => a -> m a
    return []

      let navMapFormatter :: Int -> [Inline] -> TS.Text -> [Element] -> Element
          navMapFormatter :: Int -> [Inline] -> Text -> [Element] -> Element
    navMapFormatter n :: Int
    n tit :: [Inline]
    tit src :: Text
    src subs :: [Element]
    subs = String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "navPoint" ([Element] -> Element)
    -> [(String, String)] -> [Element] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                   [("id", "navPoint-" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    n)] ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
                      [ String -> Element -> Element
    forall t. Node t => String -> t -> Element
    unode "navLabel" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "text" (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ Text -> String
    TS.unpack (Text -> String) -> Text -> String
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Text
    forall a. Walkable Inline a => a -> Text
    stringify [Inline]
    tit
                      , String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "content" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("src", "text/" String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> Text -> String
    TS.unpack Text
    src)] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
                      ] [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    subs

      let tpNode :: Element
    tpNode = String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "navPoint" ([Element] -> Element)
    -> [(String, String)] -> [Element] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !  [("id", "navPoint-0")] ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
                      [ String -> Element -> Element
    forall t. Node t => String -> t -> Element
    unode "navLabel" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "text" (Text -> String
    TS.unpack (Text -> String) -> Text -> String
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Text
    forall a. Walkable Inline a => a -> Text
    stringify ([Inline] -> Text) -> [Inline] -> Text
    forall a b. (a -> b) -> a -> b
    $ Meta -> [Inline]
    docTitle' Meta
    meta)
                      , String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "content" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("src", "text/title_page.xhtml")]
                      (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ () ]

      [Element]
    navMap <- m [Element] -> StateT EPUBState m [Element]
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m [Element] -> StateT EPUBState m [Element])
    -> m [Element] -> StateT EPUBState m [Element]
    forall a b. (a -> b) -> a -> b
    $ StateT Int m [Element] -> Int -> m [Element]
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT
                 ([[Element]] -> [Element]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[Element]] -> [Element])
    -> StateT Int m [[Element]] -> StateT Int m [Element]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Block -> StateT Int m [Element])
    -> [Block] -> StateT Int m [[Element]]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM ((Int -> [Inline] -> Text -> [Element] -> Element)
    -> Block -> StateT Int m [Element]
    forall (m :: * -> *).
    PandocMonad m =>
    (Int -> [Inline] -> Text -> [Element] -> Element)
    -> Block -> StateT Int m [Element]
    navPointNode Int -> [Inline] -> Text -> [Element] -> Element
    navMapFormatter) [Block]
    secs) 1
      let tocData :: ByteString
    tocData = String -> ByteString
    UTF8.fromStringLazy (String -> ByteString) -> String -> ByteString
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    ppTopElement (Element -> String) -> Element -> String
    forall a b. (a -> b) -> a -> b
    $
            String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "ncx" ([Element] -> Element)
    -> [(String, String)] -> [Element] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("version","2005-1")
                           ,("xmlns","http://www.daisy.org/z3986/2005/ncx/")] ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
              [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "head" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
                 [ String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("name","dtb:uid")
                                  ,("content", String
    uuid)] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
                 , String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("name","dtb:depth")
                                  ,("content", "1")] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
                 , String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("name","dtb:totalPageCount")
                                  ,("content", "0")] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
                 , String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("name","dtb:maxPageNumber")
                                  ,("content", "0")] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
                 ] [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ case EPUBMetadata -> Maybe String
    epubCoverImage EPUBMetadata
    metadata of
                            Nothing  -> []
                            Just img :: String
    img -> [String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("name","cover"),
                                                ("content", ShowS
    toId String
    img)] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()]
              , String -> Element -> Element
    forall t. Node t => String -> t -> Element
    unode "docTitle" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "text" String
    plainTitle
              , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "navMap" ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
                  Element
    tpNode Element -> [Element] -> [Element]
    forall a. a -> [a] -> [a]
    : [Element]
    navMap
              ]
      Entry
    tocEntry <- String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry "toc.ncx" ByteString
    tocData

      let navXhtmlFormatter :: Int -> [Inline] -> TS.Text -> [Element] -> Element
          navXhtmlFormatter :: Int -> [Inline] -> Text -> [Element] -> Element
    navXhtmlFormatter n :: Int
    n tit :: [Inline]
    tit src :: Text
    src subs :: [Element]
    subs = String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "li" ([Element] -> Element)
    -> [(String, String)] -> [Element] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                                           [("id", "toc-li-" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    n)] ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
                                                (String -> [Content] -> Element
    forall t. Node t => String -> t -> Element
    unode "a" ([Content] -> Element)
    -> [(String, String)] -> [Content] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                                                    [("href", "text/" String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> Text -> String
    TS.unpack Text
    src)]
                                                 ([Content] -> Element) -> [Content] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Content]
    titElements)
                                                Element -> [Element] -> [Element]
    forall a. a -> [a] -> [a]
    : case [Element]
    subs of
                                                     []    -> []
                                                     (_:_) -> [String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "ol" ([Element] -> Element)
    -> [(String, String)] -> [Element] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("class","toc")] ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element]
    subs]
              where titElements :: [Content]
    titElements = Text -> [Content]
    forall s. XmlSource s => s -> [Content]
    parseXML Text
    titRendered
                    titRendered :: Text
    titRendered = case PandocPure Text -> Either PandocError Text
    forall a. PandocPure a -> Either PandocError a
    P.runPure
                                   (EPUBVersion -> WriterOptions -> Pandoc -> PandocPure Text
    forall (m :: * -> *).
    PandocMonad m =>
    EPUBVersion -> WriterOptions -> Pandoc -> m Text
    writeHtmlStringForEPUB EPUBVersion
    version
                                     WriterOptions
    opts{ writerTemplate :: Maybe (Template Text)
    writerTemplate = Maybe (Template Text)
    forall a. Maybe a
    Nothing
                                         , writerVariables :: Context Text
    writerVariables =
                                             Map Text (Val Text) -> Context Text
    forall a. Map Text (Val a) -> Context a
    Context ([(Text, Val Text)] -> Map Text (Val Text)
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList
                                               [("pagetitle", Text -> Val Text
    forall a b. ToContext a b => b -> Val a
    toVal (Text -> Val Text) -> Text -> Val Text
    forall a b. (a -> b) -> a -> b
    $
                                                 Text -> Text
    escapeStringForXML (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ String -> Text
    TS.pack String
    plainTitle)])
                                           Context Text -> Context Text -> Context Text
    forall a. Semigroup a => a -> a -> a
    <> WriterOptions -> Context Text
    writerVariables WriterOptions
    opts}
                                     (Meta -> [Block] -> Pandoc
    Pandoc Meta
    nullMeta
                                       [[Inline] -> Block
    Plain ([Inline] -> Block) -> [Inline] -> Block
    forall a b. (a -> b) -> a -> b
    $ (Inline -> Inline) -> [Inline] -> [Inline]
    forall a b. Walkable a b => (a -> a) -> b -> b
    walk Inline -> Inline
    clean [Inline]
    tit])) of
                                    Left _  -> [Inline] -> Text
    forall a. Walkable Inline a => a -> Text
    stringify [Inline]
    tit
                                    Right x :: Text
    x -> Text
    x
                    -- can't have <a> elements inside generated links...
                    clean :: Inline -> Inline
    clean (Link _ ils :: [Inline]
    ils _) = Attr -> [Inline] -> Inline
    Span ("", [], []) [Inline]
    ils
                    clean (Note _)       = Text -> Inline
    Str ""
                    clean x :: Inline
    x              = Inline
    x

      let navtag :: String
    navtag = if Bool
    epub3 then "nav" else "div"
      [Element]
    tocBlocks <- m [Element] -> StateT EPUBState m [Element]
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m [Element] -> StateT EPUBState m [Element])
    -> m [Element] -> StateT EPUBState m [Element]
    forall a b. (a -> b) -> a -> b
    $ StateT Int m [Element] -> Int -> m [Element]
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT
                     ([[Element]] -> [Element]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[Element]] -> [Element])
    -> StateT Int m [[Element]] -> StateT Int m [Element]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Block -> StateT Int m [Element])
    -> [Block] -> StateT Int m [[Element]]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM ((Int -> [Inline] -> Text -> [Element] -> Element)
    -> Block -> StateT Int m [Element]
    forall (m :: * -> *).
    PandocMonad m =>
    (Int -> [Inline] -> Text -> [Element] -> Element)
    -> Block -> StateT Int m [Element]
    navPointNode Int -> [Inline] -> Text -> [Element] -> Element
    navXhtmlFormatter) [Block]
    secs) 1
      let navBlocks :: [Block]
    navBlocks = [Format -> Text -> Block
    RawBlock (Text -> Format
    Format "html")
                      (Text -> Block) -> Text -> Block
    forall a b. (a -> b) -> a -> b
    $ String -> Text
    TS.pack (String -> Text) -> String -> Text
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    showElement (Element -> String) -> Element -> String
    forall a b. (a -> b) -> a -> b
    $ -- prettyprinting introduces bad spaces
                       String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode String
    navtag ([Element] -> Element)
    -> [(String, String)] -> [Element] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! ([("epub:type","toc") | Bool
    epub3] [(String, String)] -> [(String, String)] -> [(String, String)]
    forall a. [a] -> [a] -> [a]
    ++
                                       [("id","toc")]) ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
                        [ String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "h1" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("id","toc-title")] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ String
    tocTitle
                        , String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "ol" ([Element] -> Element)
    -> [(String, String)] -> [Element] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("class","toc")] ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element]
    tocBlocks ]]
      let landmarkItems :: [Element]
    landmarkItems = if Bool
    epub3
                             then [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "li"
                                    [ String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "a" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("href", "text/cover.xhtml")
                                                  ,("epub:type", "cover")] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $
                                      ("Cover" :: String)] |
                                      Maybe String -> Bool
    forall a. Maybe a -> Bool
    isJust (EPUBMetadata -> Maybe String
    epubCoverImage EPUBMetadata
    metadata)
                                  ] [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                                  [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "li"
                                    [ String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "a" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("href", "#toc")
                                                  ,("epub:type", "toc")] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $
                                        ("Table of contents" :: String)
                                    ] | WriterOptions -> Bool
    writerTableOfContents WriterOptions
    opts
                                  ]
                             else []
      let landmarks :: [Block]
    landmarks = if [Element] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Element]
    landmarkItems
                         then []
                         else [Format -> Text -> Block
    RawBlock (Text -> Format
    Format "html") (Text -> Block) -> Text -> Block
    forall a b. (a -> b) -> a -> b
    $ String -> Text
    TS.pack (String -> Text) -> String -> Text
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    ppElement (Element -> String) -> Element -> String
    forall a b. (a -> b) -> a -> b
    $
                                String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "nav" ([Element] -> Element)
    -> [(String, String)] -> [Element] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("epub:type","landmarks")
                                              ,("id","landmarks")
                                              ,("hidden","hidden")] ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $
                                [ String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "ol" [Element]
    landmarkItems ]
                              ]
      ByteString
    navData <- m ByteString -> E m ByteString
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m ByteString -> E m ByteString) -> m ByteString -> E m ByteString
    forall a b. (a -> b) -> a -> b
    $ WriterOptions -> Pandoc -> m ByteString
    forall (f :: * -> *).
    PandocMonad f =>
    WriterOptions -> Pandoc -> f ByteString
    writeHtml WriterOptions
    opts'{ writerVariables :: Context Text
    writerVariables =
                         Map Text (Val Text) -> Context Text
    forall a. Map Text (Val a) -> Context a
    Context ([(Text, Val Text)] -> Map Text (Val Text)
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList [("navpage", String -> Val Text
    toVal' "true")])
                         Context Text -> Context Text -> Context Text
    forall a. Semigroup a => a -> a -> a
    <> Bool -> Context Text
    cssvars Bool
    False Context Text -> Context Text -> Context Text
    forall a. Semigroup a => a -> a -> a
    <> Context Text
    vars }
                (Meta -> [Block] -> Pandoc
    Pandoc (Text -> Many Inline -> Meta -> Meta
    forall a b. (HasMeta a, ToMetaValue b) => Text -> b -> a -> a
    setMeta "title"
                         ((Inline -> Inline) -> Many Inline -> Many Inline
    forall a b. Walkable a b => (a -> a) -> b -> b
    walk Inline -> Inline
    removeNote (Many Inline -> Many Inline) -> Many Inline -> Many Inline
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Many Inline
    forall a. [a] -> Many a
    fromList ([Inline] -> Many Inline) -> [Inline] -> Many Inline
    forall a b. (a -> b) -> a -> b
    $ Meta -> [Inline]
    docTitle' Meta
    meta) Meta
    nullMeta)
                   ([Block]
    navBlocks [Block] -> [Block] -> [Block]
    forall a. [a] -> [a] -> [a]
    ++ [Block]
    landmarks))
      Entry
    navEntry <- String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry "nav.xhtml" ByteString
    navData

      -- mimetype
      Entry
    mimetypeEntry <- String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry "mimetype" (ByteString -> StateT EPUBState m Entry)
    -> ByteString -> StateT EPUBState m Entry
    forall a b. (a -> b) -> a -> b
    $
                            String -> ByteString
    UTF8.fromStringLazy "application/epub+zip"

      -- container.xml
      let containerData :: ByteString
    containerData = String -> ByteString
    UTF8.fromStringLazy (String -> ByteString) -> String -> ByteString
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    ppTopElement (Element -> String) -> Element -> String
    forall a b. (a -> b) -> a -> b
    $
           String -> Element -> Element
    forall t. Node t => String -> t -> Element
    unode "container" (Element -> Element) -> [(String, String)] -> Element -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("version","1.0")
                  ,("xmlns","urn:oasis:names:tc:opendocument:xmlns:container")] (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
             String -> Element -> Element
    forall t. Node t => String -> t -> Element
    unode "rootfiles" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
               String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "rootfile" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("full-path",
                        (if String -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    epubSubdir
                            then ""
                            else String
    epubSubdir String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ "/") String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ "content.opf")
                   ,("media-type","application/oebps-package+xml")] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
      Entry
    containerEntry <- String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry "META-INF/container.xml" ByteString
    containerData

      -- com.apple.ibooks.display-options.xml
      let apple :: ByteString
    apple = String -> ByteString
    UTF8.fromStringLazy (String -> ByteString) -> String -> ByteString
    forall a b. (a -> b) -> a -> b
    $ Element -> String
    ppTopElement (Element -> String) -> Element -> String
    forall a b. (a -> b) -> a -> b
    $
            String -> Element -> Element
    forall t. Node t => String -> t -> Element
    unode "display_options" (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
              String -> Element -> Element
    forall t. Node t => String -> t -> Element
    unode "platform" (Element -> Element) -> [(String, String)] -> Element -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("name","*")] (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
                String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "option" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("name","specified-fonts")] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ ("true" :: String)
      Entry
    appleEntry <- String -> ByteString -> StateT EPUBState m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry "META-INF/com.apple.ibooks.display-options.xml" ByteString
    apple

      -- construct archive
      let archive :: Archive
    archive = (Entry -> Archive -> Archive) -> Archive -> [Entry] -> Archive
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Entry -> Archive -> Archive
    addEntryToArchive Archive
    emptyArchive ([Entry] -> Archive) -> [Entry] -> Archive
    forall a b. (a -> b) -> a -> b
    $
                     [Entry
    mimetypeEntry, Entry
    containerEntry, Entry
    appleEntry,
                      Entry
    contentsEntry, Entry
    tocEntry, Entry
    navEntry, Entry
    tpEntry] [Entry] -> [Entry] -> [Entry]
    forall a. [a] -> [a] -> [a]
    ++
                      [Entry]
    stylesheetEntries [Entry] -> [Entry] -> [Entry]
    forall a. [a] -> [a] -> [a]
    ++ [Entry]
    picEntries [Entry] -> [Entry] -> [Entry]
    forall a. [a] -> [a] -> [a]
    ++ [Entry]
    cpicEntry [Entry] -> [Entry] -> [Entry]
    forall a. [a] -> [a] -> [a]
    ++
                      [Entry]
    cpgEntry [Entry] -> [Entry] -> [Entry]
    forall a. [a] -> [a] -> [a]
    ++ [Entry]
    chapterEntries [Entry] -> [Entry] -> [Entry]
    forall a. [a] -> [a] -> [a]
    ++ [Entry]
    fontEntries
      ByteString -> E m ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ByteString -> E m ByteString) -> ByteString -> E m ByteString
    forall a b. (a -> b) -> a -> b
    $ Archive -> ByteString
    fromArchive Archive
    archive

    metadataElement :: EPUBVersion -> EPUBMetadata -> UTCTime -> Element
    metadataElement :: EPUBVersion -> EPUBMetadata -> UTCTime -> Element
    metadataElement version :: EPUBVersion
    version md :: EPUBMetadata
    md currentTime :: UTCTime
    currentTime =
      String -> [Element] -> Element
    forall t. Node t => String -> t -> Element
    unode "metadata" ([Element] -> Element)
    -> [(String, String)] -> [Element] -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("xmlns:dc","http://purl.org/dc/elements/1.1/")
                         ,("xmlns:opf","http://www.idpf.org/2007/opf")] ([Element] -> Element) -> [Element] -> Element
    forall a b. (a -> b) -> a -> b
    $ [Element]
    mdNodes
      where mdNodes :: [Element]
    mdNodes = [Element]
    identifierNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    titleNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    dateNodes
                      [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    languageNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    ibooksNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    calibreNodes
                      [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    creatorNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    contributorNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    subjectNodes
                      [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    descriptionNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    typeNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    formatNodes
                      [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    publisherNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    sourceNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    relationNodes
                      [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    coverageNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    rightsNodes [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    coverImageNodes
                      [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++ [Element]
    modifiedNodes
            withIds :: String -> (String -> b -> [a]) -> [b] -> [a]
    withIds base :: String
    base f :: String -> b -> [a]
    f = [[a]] -> [a]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[a]] -> [a]) -> ([b] -> [[a]]) -> [b] -> [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String -> b -> [a]) -> [String] -> [b] -> [[a]]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith String -> b -> [a]
    f ((Int -> String) -> [Int] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (\x :: Int
    x -> String
    base String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ('-' Char -> ShowS
    forall a. a -> [a] -> [a]
    : Int -> String
    forall a. Show a => a -> String
    show Int
    x))
                             ([1..] :: [Int]))
            identifierNodes :: [Element]
    identifierNodes = String
    -> (String -> Identifier -> [Element]) -> [Identifier] -> [Element]
    forall b a. String -> (String -> b -> [a]) -> [b] -> [a]
    withIds "epub-id" String -> Identifier -> [Element]
    toIdentifierNode ([Identifier] -> [Element]) -> [Identifier] -> [Element]
    forall a b. (a -> b) -> a -> b
    $
                              EPUBMetadata -> [Identifier]
    epubIdentifier EPUBMetadata
    md
            titleNodes :: [Element]
    titleNodes = String -> (String -> Title -> [Element]) -> [Title] -> [Element]
    forall b a. String -> (String -> b -> [a]) -> [b] -> [a]
    withIds "epub-title" String -> Title -> [Element]
    toTitleNode ([Title] -> [Element]) -> [Title] -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> [Title]
    epubTitle EPUBMetadata
    md
            dateNodes :: [Element]
    dateNodes = if EPUBVersion
    version EPUBVersion -> EPUBVersion -> Bool
    forall a. Eq a => a -> a -> Bool
    == EPUBVersion
    EPUB2
                           then String -> (String -> Date -> [Element]) -> [Date] -> [Element]
    forall b a. String -> (String -> b -> [a]) -> [b] -> [a]
    withIds "epub-date" String -> Date -> [Element]
    toDateNode ([Date] -> [Element]) -> [Date] -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> [Date]
    epubDate EPUBMetadata
    md
                           else -- epub3 allows only one dc:date
                                -- http://www.idpf.org/epub/30/spec/epub30-publications.html#sec-opf-dcdate
                                case EPUBMetadata -> [Date]
    epubDate EPUBMetadata
    md of
                                     [] -> []
                                     (x :: Date
    x:_) -> [String -> String -> Element
    forall t. Node t => String -> t -> Element
    dcNode "date" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("id","epub-date")]
                                                (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ Date -> String
    dateText Date
    x]
            ibooksNodes :: [Element]
    ibooksNodes = ((String, String) -> Element) -> [(String, String)] -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map (String, String) -> Element
    forall t. Node t => (String, t) -> Element
    ibooksNode (EPUBMetadata -> [(String, String)]
    epubIbooksFields EPUBMetadata
    md)
            ibooksNode :: (String, t) -> Element
    ibooksNode (k :: String
    k, v :: t
    v) = String -> t -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (t -> Element) -> [(String, String)] -> t -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("property", "ibooks:" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    k)] (t -> Element) -> t -> Element
    forall a b. (a -> b) -> a -> b
    $ t
    v
            calibreNodes :: [Element]
    calibreNodes = ((String, String) -> Element) -> [(String, String)] -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map (String, String) -> Element
    calibreNode (EPUBMetadata -> [(String, String)]
    epubCalibreFields EPUBMetadata
    md)
            calibreNode :: (String, String) -> Element
    calibreNode (k :: String
    k, v :: String
    v) = String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("name", "calibre:" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    k),
                                                 ("content", String
    v)] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()
            languageNodes :: [Element]
    languageNodes = [String -> String -> Element
    forall t. Node t => String -> t -> Element
    dcTag "language" (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> String
    epubLanguage EPUBMetadata
    md]
            creatorNodes :: [Element]
    creatorNodes = String
    -> (String -> Creator -> [Element]) -> [Creator] -> [Element]
    forall b a. String -> (String -> b -> [a]) -> [b] -> [a]
    withIds "epub-creator" (String -> String -> Creator -> [Element]
    toCreatorNode "creator") ([Creator] -> [Element]) -> [Creator] -> [Element]
    forall a b. (a -> b) -> a -> b
    $
                           EPUBMetadata -> [Creator]
    epubCreator EPUBMetadata
    md
            contributorNodes :: [Element]
    contributorNodes = String
    -> (String -> Creator -> [Element]) -> [Creator] -> [Element]
    forall b a. String -> (String -> b -> [a]) -> [b] -> [a]
    withIds "epub-contributor"
                               (String -> String -> Creator -> [Element]
    toCreatorNode "contributor") ([Creator] -> [Element]) -> [Creator] -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> [Creator]
    epubContributor EPUBMetadata
    md
            subjectNodes :: [Element]
    subjectNodes = (String -> Element) -> [String] -> [Element]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> String -> Element
    forall t. Node t => String -> t -> Element
    dcTag "subject") ([String] -> [Element]) -> [String] -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> [String]
    epubSubject EPUBMetadata
    md
            descriptionNodes :: [Element]
    descriptionNodes = [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (String -> String -> [Element]
    forall t. Node t => String -> t -> [Element]
    dcTag' "description") (Maybe String -> [Element]) -> Maybe String -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> Maybe String
    epubDescription EPUBMetadata
    md
            typeNodes :: [Element]
    typeNodes = [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (String -> String -> [Element]
    forall t. Node t => String -> t -> [Element]
    dcTag' "type") (Maybe String -> [Element]) -> Maybe String -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> Maybe String
    epubType EPUBMetadata
    md
            formatNodes :: [Element]
    formatNodes = [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (String -> String -> [Element]
    forall t. Node t => String -> t -> [Element]
    dcTag' "format") (Maybe String -> [Element]) -> Maybe String -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> Maybe String
    epubFormat EPUBMetadata
    md
            publisherNodes :: [Element]
    publisherNodes = [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (String -> String -> [Element]
    forall t. Node t => String -> t -> [Element]
    dcTag' "publisher") (Maybe String -> [Element]) -> Maybe String -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> Maybe String
    epubPublisher EPUBMetadata
    md
            sourceNodes :: [Element]
    sourceNodes = [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (String -> String -> [Element]
    forall t. Node t => String -> t -> [Element]
    dcTag' "source") (Maybe String -> [Element]) -> Maybe String -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> Maybe String
    epubSource EPUBMetadata
    md
            relationNodes :: [Element]
    relationNodes = [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (String -> String -> [Element]
    forall t. Node t => String -> t -> [Element]
    dcTag' "relation") (Maybe String -> [Element]) -> Maybe String -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> Maybe String
    epubRelation EPUBMetadata
    md
            coverageNodes :: [Element]
    coverageNodes = [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (String -> String -> [Element]
    forall t. Node t => String -> t -> [Element]
    dcTag' "coverage") (Maybe String -> [Element]) -> Maybe String -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> Maybe String
    epubCoverage EPUBMetadata
    md
            rightsNodes :: [Element]
    rightsNodes = [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (String -> String -> [Element]
    forall t. Node t => String -> t -> [Element]
    dcTag' "rights") (Maybe String -> [Element]) -> Maybe String -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> Maybe String
    epubRights EPUBMetadata
    md
            coverImageNodes :: [Element]
    coverImageNodes = [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe []
                (\img :: String
    img -> [String -> () -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (() -> Element) -> [(String, String)] -> () -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !  [("name","cover"),
                                           ("content",ShowS
    toId String
    img)] (() -> Element) -> () -> Element
    forall a b. (a -> b) -> a -> b
    $ ()])
                (Maybe String -> [Element]) -> Maybe String -> [Element]
    forall a b. (a -> b) -> a -> b
    $ EPUBMetadata -> Maybe String
    epubCoverImage EPUBMetadata
    md
            modifiedNodes :: [Element]
    modifiedNodes = [ String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("property", "dcterms:modified")] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $
                   UTCTime -> String
    showDateTimeISO8601 UTCTime
    currentTime | EPUBVersion
    version EPUBVersion -> EPUBVersion -> Bool
    forall a. Eq a => a -> a -> Bool
    == EPUBVersion
    EPUB3 ]
            dcTag :: String -> t -> Element
    dcTag n :: String
    n s :: t
    s = String -> t -> Element
    forall t. Node t => String -> t -> Element
    unode ("dc:" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    n) t
    s
            dcTag' :: String -> t -> [Element]
    dcTag' n :: String
    n s :: t
    s = [String -> t -> Element
    forall t. Node t => String -> t -> Element
    dcTag String
    n t
    s]
            toIdentifierNode :: String -> Identifier -> [Element]
    toIdentifierNode id' :: String
    id' (Identifier txt :: String
    txt scheme :: Maybe String
    scheme)
              | EPUBVersion
    version EPUBVersion -> EPUBVersion -> Bool
    forall a. Eq a => a -> a -> Bool
    == EPUBVersion
    EPUB2 = [String -> String -> Element
    forall t. Node t => String -> t -> Element
    dcNode "identifier" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                  (("id",String
    id') (String, String) -> [(String, String)] -> [(String, String)]
    forall a. a -> [a] -> [a]
    : [(String, String)]
    -> (String -> [(String, String)])
    -> Maybe String
    -> [(String, String)]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\x :: String
    x -> [("opf:scheme", String
    x)]) Maybe String
    scheme) (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $
                  String
    txt]
              | Bool
    otherwise = [String -> String -> Element
    forall t. Node t => String -> t -> Element
    dcNode "identifier" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("id",String
    id')] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ String
    txt] [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                  [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] ((\x :: String
    x -> [String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                                    [ ("refines",'#'Char -> ShowS
    forall a. a -> [a] -> [a]
    :String
    id')
                                    , ("property","identifier-type")
                                    , ("scheme","onix:codelist5")
                                    ]
                                    (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ String
    x
                                   ])
                            (String -> [Element]) -> ShowS -> String -> [Element]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ShowS
    schemeToOnix)
                        Maybe String
    scheme
            toCreatorNode :: String -> String -> Creator -> [Element]
    toCreatorNode s :: String
    s id' :: String
    id' creator :: Creator
    creator
              | EPUBVersion
    version EPUBVersion -> EPUBVersion -> Bool
    forall a. Eq a => a -> a -> Bool
    == EPUBVersion
    EPUB2 = [String -> String -> Element
    forall t. Node t => String -> t -> Element
    dcNode String
    s (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                 (("id",String
    id') (String, String) -> [(String, String)] -> [(String, String)]
    forall a. a -> [a] -> [a]
    :
                  [(String, String)]
    -> (String -> [(String, String)])
    -> Maybe String
    -> [(String, String)]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\x :: String
    x -> [("opf:file-as",String
    x)]) (Creator -> Maybe String
    creatorFileAs Creator
    creator) [(String, String)] -> [(String, String)] -> [(String, String)]
    forall a. [a] -> [a] -> [a]
    ++
                  [(String, String)]
    -> (String -> [(String, String)])
    -> Maybe String
    -> [(String, String)]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\x :: String
    x -> [("opf:role",String
    x)])
                   (Creator -> Maybe String
    creatorRole Creator
    creator Maybe String -> (String -> Maybe String) -> Maybe String
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= String -> Maybe String
    toRelator)) (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ Creator -> String
    creatorText Creator
    creator]
              | Bool
    otherwise = [String -> String -> Element
    forall t. Node t => String -> t -> Element
    dcNode String
    s (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("id",String
    id')] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ Creator -> String
    creatorText Creator
    creator] [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                  [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\x :: String
    x -> [String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                       [("refines",'#'Char -> ShowS
    forall a. a -> [a] -> [a]
    :String
    id'),("property","file-as")] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ String
    x])
                       (Creator -> Maybe String
    creatorFileAs Creator
    creator) [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                  [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\x :: String
    x -> [String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                       [("refines",'#'Char -> ShowS
    forall a. a -> [a] -> [a]
    :String
    id'),("property","role"),
                         ("scheme","marc:relators")] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ String
    x])
                       (Creator -> Maybe String
    creatorRole Creator
    creator Maybe String -> (String -> Maybe String) -> Maybe String
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= String -> Maybe String
    toRelator)
            toTitleNode :: String -> Title -> [Element]
    toTitleNode id' :: String
    id' title :: Title
    title
              | EPUBVersion
    version EPUBVersion -> EPUBVersion -> Bool
    forall a. Eq a => a -> a -> Bool
    == EPUBVersion
    EPUB2 = [String -> String -> Element
    forall t. Node t => String -> t -> Element
    dcNode "title" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                 (("id",String
    id') (String, String) -> [(String, String)] -> [(String, String)]
    forall a. a -> [a] -> [a]
    :
                  -- note: EPUB2 doesn't accept opf:title-type
                  [(String, String)]
    -> (String -> [(String, String)])
    -> Maybe String
    -> [(String, String)]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\x :: String
    x -> [("opf:file-as",String
    x)]) (Title -> Maybe String
    titleFileAs Title
    title)) (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $
                  Title -> String
    titleText Title
    title]
              | Bool
    otherwise = [String -> String -> Element
    forall t. Node t => String -> t -> Element
    dcNode "title" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    ! [("id",String
    id')] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ Title -> String
    titleText Title
    title]
                  [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                  [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\x :: String
    x -> [String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                       [("refines",'#'Char -> ShowS
    forall a. a -> [a] -> [a]
    :String
    id'),("property","file-as")] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ String
    x])
                       (Title -> Maybe String
    titleFileAs Title
    title) [Element] -> [Element] -> [Element]
    forall a. [a] -> [a] -> [a]
    ++
                  [Element] -> (String -> [Element]) -> Maybe String -> [Element]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\x :: String
    x -> [String -> String -> Element
    forall t. Node t => String -> t -> Element
    unode "meta" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                       [("refines",'#'Char -> ShowS
    forall a. a -> [a] -> [a]
    :String
    id'),("property","title-type")] (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $ String
    x])
                       (Title -> Maybe String
    titleType Title
    title)
            toDateNode :: String -> Date -> [Element]
    toDateNode id' :: String
    id' date :: Date
    date = [String -> String -> Element
    forall t. Node t => String -> t -> Element
    dcNode "date" (String -> Element) -> [(String, String)] -> String -> Element
    forall t. (t -> Element) -> [(String, String)] -> t -> Element
    !
                 (("id",String
    id') (String, String) -> [(String, String)] -> [(String, String)]
    forall a. a -> [a] -> [a]
    :
                    [(String, String)]
    -> (String -> [(String, String)])
    -> Maybe String
    -> [(String, String)]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\x :: String
    x -> [("opf:event",String
    x)]) (Date -> Maybe String
    dateEvent Date
    date)) (String -> Element) -> String -> Element
    forall a b. (a -> b) -> a -> b
    $
                     Date -> String
    dateText Date
    date]
            schemeToOnix :: String -> String
            schemeToOnix :: ShowS
    schemeToOnix "ISBN-10"              = "02"
            schemeToOnix "GTIN-13"              = "03"
            schemeToOnix "UPC"                  = "04"
            schemeToOnix "ISMN-10"              = "05"
            schemeToOnix "DOI"                  = "06"
            schemeToOnix "LCCN"                 = "13"
            schemeToOnix "GTIN-14"              = "14"
            schemeToOnix "ISBN-13"              = "15"
            schemeToOnix "Legal deposit number" = "17"
            schemeToOnix "URN"                  = "22"
            schemeToOnix "OCLC"                 = "23"
            schemeToOnix "ISMN-13"              = "25"
            schemeToOnix "ISBN-A"               = "26"
            schemeToOnix "JP"                   = "27"
            schemeToOnix "OLCC"                 = "28"
            schemeToOnix _                      = "01"

    showDateTimeISO8601 :: UTCTime -> String
    showDateTimeISO8601 :: UTCTime -> String
    showDateTimeISO8601 = TimeLocale -> String -> UTCTime -> String
    forall t. FormatTime t => TimeLocale -> String -> t -> String
    formatTime TimeLocale
    defaultTimeLocale "%FT%TZ"

    transformTag :: PandocMonad m
                 => Tag TS.Text
                 -> E m (Tag TS.Text)
    transformTag :: Tag Text -> E m (Tag Text)
    transformTag tag :: Tag Text
    tag@(TagOpen name :: Text
    name attr :: [(Text, Text)]
    attr)
      | Text
    name Text -> [Text] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` ["video", "source", "img", "audio"] Bool -> Bool -> Bool
    &&
        Maybe Text -> Bool
    forall a. Maybe a -> Bool
    isNothing (Text -> [(Text, Text)] -> Maybe Text
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup "data-external" [(Text, Text)]
    attr) = do
      let src :: Text
    src = Text -> Tag Text -> Text
    forall str.
    (Show str, Eq str, StringLike str) =>
    str -> Tag str -> str
    fromAttrib "src" Tag Text
    tag
      let poster :: Text
    poster = Text -> Tag Text -> Text
    forall str.
    (Show str, Eq str, StringLike str) =>
    str -> Tag str -> str
    fromAttrib "poster" Tag Text
    tag
      Text
    newsrc <- String -> E m Text
    forall (m :: * -> *). PandocMonad m => String -> E m Text
    modifyMediaRef (String -> E m Text) -> String -> E m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> String
    TS.unpack Text
    src
      Text
    newposter <- String -> E m Text
    forall (m :: * -> *). PandocMonad m => String -> E m Text
    modifyMediaRef (String -> E m Text) -> String -> E m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> String
    TS.unpack Text
    poster
      let attr' :: [(Text, Text)]
    attr' = ((Text, Text) -> Bool) -> [(Text, Text)] -> [(Text, Text)]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\(x :: Text
    x,_) -> Text
    x Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "src" Bool -> Bool -> Bool
    && Text
    x Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "poster") [(Text, Text)]
    attr [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
    forall a. [a] -> [a] -> [a]
    ++
                  [("src", "../" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    newsrc) | Bool -> Bool
    not (Text -> Bool
    TS.null Text
    newsrc)] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
    forall a. [a] -> [a] -> [a]
    ++
                  [("poster", "../" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    newposter) | Bool -> Bool
    not (Text -> Bool
    TS.null Text
    newposter)]
      Tag Text -> E m (Tag Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Tag Text -> E m (Tag Text)) -> Tag Text -> E m (Tag Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> [(Text, Text)] -> Tag Text
    forall str. str -> [Attribute str] -> Tag str
    TagOpen Text
    name [(Text, Text)]
    attr'
    transformTag tag :: Tag Text
    tag = Tag Text -> E m (Tag Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Tag Text
    tag

    modifyMediaRef :: PandocMonad m
                   => FilePath
                   -> E m TS.Text
    modifyMediaRef :: String -> E m Text
    modifyMediaRef "" = Text -> E m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""
    modifyMediaRef oldsrc :: String
    oldsrc = do
      [(String, (String, Maybe Entry))]
    media <- (EPUBState -> [(String, (String, Maybe Entry))])
    -> StateT EPUBState m [(String, (String, Maybe Entry))]
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets EPUBState -> [(String, (String, Maybe Entry))]
    stMediaPaths
      case String
    -> [(String, (String, Maybe Entry))] -> Maybe (String, Maybe Entry)
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup String
    oldsrc [(String, (String, Maybe Entry))]
    media of
             Just (n :: String
    n,_) -> Text -> E m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> E m Text) -> Text -> E m Text
    forall a b. (a -> b) -> a -> b
    $ String -> Text
    TS.pack String
    n
             Nothing    -> E m Text -> (PandocError -> E m Text) -> E m Text
    forall e (m :: * -> *) a.
    MonadError e m =>
    m a -> (e -> m a) -> m a
    catchError
               (do (img :: ByteString
    img, mbMime :: Maybe Text
    mbMime) <- Text -> StateT EPUBState m (ByteString, Maybe Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text -> m (ByteString, Maybe Text)
    P.fetchItem (Text -> StateT EPUBState m (ByteString, Maybe Text))
    -> Text -> StateT EPUBState m (ByteString, Maybe Text)
    forall a b. (a -> b) -> a -> b
    $ String -> Text
    TS.pack String
    oldsrc
                   let ext :: String
    ext = String -> (Text -> String) -> Maybe Text -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (ShowS
    takeExtension ((Char -> Bool) -> ShowS
    forall a. (a -> Bool) -> [a] -> [a]
    takeWhile (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /='?') String
    oldsrc)) Text -> String
    TS.unpack
                             (("." Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>) (Text -> Text) -> Maybe Text -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Maybe Text
    mbMime Maybe Text -> (Text -> Maybe Text) -> Maybe Text
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Text -> Maybe Text
    extensionFromMimeType))
                   String
    newName <- String -> E m String
    forall (m :: * -> *). PandocMonad m => String -> E m String
    getMediaNextNewName String
    ext
                   let newPath :: String
    newPath = "media/" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    newName
                   Entry
    entry <- String -> ByteString -> E m Entry
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> E m Entry
    mkEntry String
    newPath ([ByteString] -> ByteString
    B.fromChunks ([ByteString] -> ByteString)
    -> (ByteString -> [ByteString]) -> ByteString -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ByteString -> [ByteString] -> [ByteString]
    forall a. a -> [a] -> [a]
    :[]) (ByteString -> ByteString) -> ByteString -> ByteString
    forall a b. (a -> b) -> a -> b
    $ ByteString
    img)
                   (EPUBState -> EPUBState) -> StateT EPUBState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((EPUBState -> EPUBState) -> StateT EPUBState m ())
    -> (EPUBState -> EPUBState) -> StateT EPUBState m ()
    forall a b. (a -> b) -> a -> b
    $ \st :: EPUBState
    st -> EPUBState
    st{ stMediaPaths :: [(String, (String, Maybe Entry))]
    stMediaPaths =
                                (String
    oldsrc, (String
    newPath, Entry -> Maybe Entry
    forall a. a -> Maybe a
    Just Entry
    entry))(String, (String, Maybe Entry))
    -> [(String, (String, Maybe Entry))]
    -> [(String, (String, Maybe Entry))]
    forall a. a -> [a] -> [a]
    :[(String, (String, Maybe Entry))]
    media}
                   Text -> E m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> E m Text) -> Text -> E m Text
    forall a b. (a -> b) -> a -> b
    $ String -> Text
    TS.pack String
    newPath)
               (\e :: PandocError
    e -> do
                    LogMessage -> StateT EPUBState m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> StateT EPUBState m ())
    -> LogMessage -> StateT EPUBState m ()
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> LogMessage
    CouldNotFetchResource (String -> Text
    TS.pack String
    oldsrc) (PandocError -> Text
    forall a. Show a => a -> Text
    tshow PandocError
    e)
                    Text -> E m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> E m Text) -> Text -> E m Text
    forall a b. (a -> b) -> a -> b
    $ String -> Text
    TS.pack String
    oldsrc)

    getMediaNextNewName :: PandocMonad m => String -> E m String
    getMediaNextNewName :: String -> E m String
    getMediaNextNewName ext :: String
    ext = do
      Int
    nextId <- (EPUBState -> Int) -> StateT EPUBState m Int
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets EPUBState -> Int
    stMediaNextId
      (EPUBState -> EPUBState) -> StateT EPUBState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((EPUBState -> EPUBState) -> StateT EPUBState m ())
    -> (EPUBState -> EPUBState) -> StateT EPUBState m ()
    forall a b. (a -> b) -> a -> b
    $ \st :: EPUBState
    st -> EPUBState
    st { stMediaNextId :: Int
    stMediaNextId = Int
    nextId Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + 1 }
      let nextName :: String
    nextName = "file" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    nextId String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    ext
      (Text -> StateT EPUBState m (ByteString, Maybe Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text -> m (ByteString, Maybe Text)
    P.fetchItem (String -> Text
    TS.pack String
    nextName) StateT EPUBState m (ByteString, Maybe Text)
    -> E m String -> E m String
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> String -> E m String
    forall (m :: * -> *). PandocMonad m => String -> E m String
    getMediaNextNewName String
    ext) E m String -> (PandocError -> E m String) -> E m String
    forall e (m :: * -> *) a.
    MonadError e m =>
    m a -> (e -> m a) -> m a
    `catchError` E m String -> PandocError -> E m String
    forall a b. a -> b -> a
    const (String -> E m String
    forall (m :: * -> *) a. Monad m => a -> m a
    return String
    nextName)

    transformBlock  :: PandocMonad m
                    => Block
                    -> E m Block
    transformBlock :: Block -> E m Block
    transformBlock (RawBlock fmt :: Format
    fmt raw :: Text
    raw)
      | Format
    fmt Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format "html" = do
      let tags :: [Tag Text]
    tags = Text -> [Tag Text]
    forall str. StringLike str => str -> [Tag str]
    parseTags Text
    raw
      [Tag Text]
    tags' <- (Tag Text -> StateT EPUBState m (Tag Text))
    -> [Tag Text] -> StateT EPUBState m [Tag Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM Tag Text -> StateT EPUBState m (Tag Text)
    forall (m :: * -> *). PandocMonad m => Tag Text -> E m (Tag Text)
    transformTag [Tag Text]
    tags
      Block -> E m Block
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Block -> E m Block) -> Block -> E m Block
    forall a b. (a -> b) -> a -> b
    $ Format -> Text -> Block
    RawBlock Format
    fmt ([Tag Text] -> Text
    renderTags' [Tag Text]
    tags')
    transformBlock b :: Block
    b = Block -> E m Block
    forall (m :: * -> *) a. Monad m => a -> m a
    return Block
    b

    transformInline  :: PandocMonad m
                     => WriterOptions
                     -> Inline
                     -> E m Inline
    transformInline :: WriterOptions -> Inline -> E m Inline
    transformInline _opts :: WriterOptions
    _opts (Image attr :: Attr
    attr lab :: [Inline]
    lab (src :: Text
    src,tit :: Text
    tit)) = do
        Text
    newsrc <- String -> E m Text
    forall (m :: * -> *). PandocMonad m => String -> E m Text
    modifyMediaRef (String -> E m Text) -> String -> E m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> String
    TS.unpack Text
    src
        Inline -> E m Inline
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Inline -> E m Inline) -> Inline -> E m Inline
    forall a b. (a -> b) -> a -> b
    $ Attr -> [Inline] -> (Text, Text) -> Inline
    Image Attr
    attr [Inline]
    lab ("../" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    newsrc, Text
    tit)
    transformInline opts :: WriterOptions
    opts x :: Inline
    x@(Math t :: MathType
    t m :: Text
    m)
      | WebTeX url :: Text
    url <- WriterOptions -> HTMLMathMethod
    writerHTMLMathMethod WriterOptions
    opts = do
        Text
    newsrc <- String -> E m Text
    forall (m :: * -> *). PandocMonad m => String -> E m Text
    modifyMediaRef (Text -> String
    TS.unpack Text
    url String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> ShowS
    urlEncode (Text -> String
    TS.unpack Text
    m))
        let mathclass :: Text
    mathclass = if MathType
    t MathType -> MathType -> Bool
    forall a. Eq a => a -> a -> Bool
    == MathType
    DisplayMath then "display" else "inline"
        Inline -> E m Inline
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Inline -> E m Inline) -> Inline -> E m Inline
    forall a b. (a -> b) -> a -> b
    $ Attr -> [Inline] -> Inline
    Span ("",["math",Text
    mathclass],[])
                    [Attr -> [Inline] -> (Text, Text) -> Inline
    Image Attr
    nullAttr [Inline
    x] ("../" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    newsrc, "")]
    transformInline _opts :: WriterOptions
    _opts (RawInline fmt :: Format
    fmt raw :: Text
    raw)
      | Format
    fmt Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format "html" = do
      let tags :: [Tag Text]
    tags = Text -> [Tag Text]
    forall str. StringLike str => str -> [Tag str]
    parseTags Text
    raw
      [Tag Text]
    tags' <- (Tag Text -> StateT EPUBState m (Tag Text))
    -> [Tag Text] -> StateT EPUBState m [Tag Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM Tag Text -> StateT EPUBState m (Tag Text)
    forall (m :: * -> *). PandocMonad m => Tag Text -> E m (Tag Text)
    transformTag [Tag Text]
    tags
      Inline -> E m Inline
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Inline -> E m Inline) -> Inline -> E m Inline
    forall a b. (a -> b) -> a -> b
    $ Format -> Text -> Inline
    RawInline Format
    fmt ([Tag Text] -> Text
    renderTags' [Tag Text]
    tags')
    transformInline _ x :: Inline
    x = Inline -> E m Inline
    forall (m :: * -> *) a. Monad m => a -> m a
    return Inline
    x

    (!) :: (t -> Element) -> [(String, String)] -> t -> Element
    (!) f :: t -> Element
    f attrs :: [(String, String)]
    attrs n :: t
    n = [Attr] -> Element -> Element
    add_attrs (((String, String) -> Attr) -> [(String, String)] -> [Attr]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(k :: String
    k,v :: String
    v) -> QName -> String -> Attr
    Attr (String -> QName
    unqual String
    k) String
    v) [(String, String)]
    attrs) (t -> Element
    f t
    n)

    -- | Version of 'ppTopElement' that specifies UTF-8 encoding.
    ppTopElement :: Element -> String
    ppTopElement :: Element -> String
    ppTopElement = ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++) ShowS -> (Element -> String) -> Element -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ShowS
    unEntity ShowS -> (Element -> String) -> Element -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Element -> String
    ppElement
      -- unEntity removes numeric  entities introduced by ppElement
      -- (kindlegen seems to choke on these).
      where unEntity :: ShowS
    unEntity [] = ""
            unEntity ('&':'#':xs :: String
    xs) =
                       let (ds :: String
    ds,ys :: String
    ys) = (Char -> Bool) -> String -> (String, String)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    ==';') String
    xs
                           rest :: String
    rest = Int -> ShowS
    forall a. Int -> [a] -> [a]
    drop 1 String
    ys
                       in  case Text -> Maybe Char
    forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
    safeRead (String -> Text
    TS.pack (String -> Text) -> String -> Text
    forall a b. (a -> b) -> a -> b
    $ "'\\" String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> String
    ds String -> ShowS
    forall a. Semigroup a => a -> a -> a
    <> "'") of
                              Just x :: Char
    x  -> Char
    x Char -> ShowS
    forall a. a -> [a] -> [a]
    : ShowS
    unEntity String
    rest
                              Nothing -> '&'Char -> ShowS
    forall a. a -> [a] -> [a]
    :'#'Char -> ShowS
    forall a. a -> [a] -> [a]
    :ShowS
    unEntity String
    xs
            unEntity (x :: Char
    x:xs :: String
    xs) = Char
    x Char -> ShowS
    forall a. a -> [a] -> [a]
    : ShowS
    unEntity String
    xs

    mediaTypeOf :: FilePath -> Maybe MimeType
    mediaTypeOf :: String -> Maybe Text
    mediaTypeOf x :: String
    x =
      let mediaPrefixes :: [Text]
    mediaPrefixes = ["image", "video", "audio"] in
      case String -> Maybe Text
    getMimeType String
    x of
        Just y :: Text
    y | (Text -> Bool) -> [Text] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (Text -> Text -> Bool
    `TS.isPrefixOf` Text
    y) [Text]
    mediaPrefixes -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    y
        _      -> Maybe Text
    forall a. Maybe a
    Nothing

    -- Returns filename for chapter number.
    showChapter :: Int -> String
    showChapter :: Int -> String
    showChapter = String -> Int -> String
    forall r. PrintfType r => String -> r
    printf "ch%03d.xhtml"

    -- Add identifiers to any headers without them.
    addIdentifiers :: WriterOptions -> [Block] -> [Block]
    addIdentifiers :: WriterOptions -> [Block] -> [Block]
    addIdentifiers opts :: WriterOptions
    opts bs :: [Block]
    bs = State (Set Text) [Block] -> Set Text -> [Block]
    forall s a. State s a -> s -> a
    evalState ((Block -> StateT (Set Text) Identity Block)
    -> [Block] -> State (Set Text) [Block]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM Block -> StateT (Set Text) Identity Block
    forall (m :: * -> *). MonadState (Set Text) m => Block -> m Block
    go [Block]
    bs) Set Text
    forall a. Set a
    Set.empty
     where go :: Block -> m Block
    go (Header n :: Int
    n (ident :: Text
    ident,classes :: [Text]
    classes,kvs :: [(Text, Text)]
    kvs) ils :: [Inline]
    ils) = do
             Set Text
    ids <- m (Set Text)
    forall s (m :: * -> *). MonadState s m => m s
    get
             let ident' :: Text
    ident' = if Text -> Bool
    TS.null Text
    ident
                             then Extensions -> [Inline] -> Set Text -> Text
    uniqueIdent (WriterOptions -> Extensions
    writerExtensions WriterOptions
    opts) [Inline]
    ils Set Text
    ids
                             else Text
    ident
             (Set Text -> Set Text) -> m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((Set Text -> Set Text) -> m ()) -> (Set Text -> Set Text) -> m ()
    forall a b. (a -> b) -> a -> b
    $ Text -> Set Text -> Set Text
    forall a. Ord a => a -> Set a -> Set a
    Set.insert Text
    ident'
             Block -> m Block
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Block -> m Block) -> Block -> m Block
    forall a b. (a -> b) -> a -> b
    $ Int -> Attr -> [Inline] -> Block
    Header Int
    n (Text
    ident',[Text]
    classes,[(Text, Text)]
    kvs) [Inline]
    ils
           go x :: Block
    x = Block -> m Block
    forall (m :: * -> *) a. Monad m => a -> m a
    return Block
    x

    -- Variant of normalizeDate that allows partial dates: YYYY, YYYY-MM
    normalizeDate' :: String -> Maybe String
    normalizeDate' :: String -> Maybe String
    normalizeDate' = (Text -> String) -> Maybe Text -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Text -> String
    TS.unpack (Maybe Text -> Maybe String)
    -> (String -> Maybe Text) -> String -> Maybe String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Maybe Text
    go (Text -> Maybe Text) -> (String -> Text) -> String -> Maybe Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Text
    trim (Text -> Text) -> (String -> Text) -> String -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Text
    TS.pack
      where
        go :: Text -> Maybe Text
    go xs :: Text
    xs
          | Text -> Int
    TS.length Text
    xs Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 4            -- YYY
          , (Char -> Bool) -> Text -> Bool
    TS.all Char -> Bool
    isDigit Text
    xs = Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    xs
          | (y :: Text
    y, s :: Text
    s) <- Int -> Text -> (Text, Text)
    TS.splitAt 4 Text
    xs    -- YYY-MM
          , Just ('-', m :: Text
    m) <- Text -> Maybe (Char, Text)
    TS.uncons Text
    s
          , Text -> Int
    TS.length Text
    m Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 2
          , (Char -> Bool) -> Text -> Bool
    TS.all Char -> Bool
    isDigit Text
    y Bool -> Bool -> Bool
    && (Char -> Bool) -> Text -> Bool
    TS.all Char -> Bool
    isDigit Text
    m = Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    xs
          | Bool
    otherwise = Text -> Maybe Text
    normalizeDate Text
    xs

    toRelator :: String -> Maybe String
    toRelator :: String -> Maybe String
    toRelator x :: String
    x
      | String
    x String -> [String] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [String]
    relators = String -> Maybe String
    forall a. a -> Maybe a
    Just String
    x
      | Bool
    otherwise         = String -> [(String, String)] -> Maybe String
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup ((Char -> Char) -> ShowS
    forall a b. (a -> b) -> [a] -> [b]
    map Char -> Char
    toLower String
    x) [(String, String)]
    relatorMap

    relators :: [String]
    relators :: [String]
    relators = ((String, String) -> String) -> [(String, String)] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String, String) -> String
    forall a b. (a, b) -> b
    snd [(String, String)]
    relatorMap

    relatorMap :: [(String, String)]
    relatorMap :: [(String, String)]
    relatorMap =
               [("abridger", "abr")
               ,("actor", "act")
               ,("adapter", "adp")
               ,("addressee", "rcp")
               ,("analyst", "anl")
               ,("animator", "anm")
               ,("annotator", "ann")
               ,("appellant", "apl")
               ,("appellee", "ape")
               ,("applicant", "app")
               ,("architect", "arc")
               ,("arranger", "arr")
               ,("art copyist", "acp")
               ,("art director", "adi")
               ,("artist", "art")
               ,("artistic director", "ard")
               ,("assignee", "asg")
               ,("associated name", "asn")
               ,("attributed name", "att")
               ,("auctioneer", "auc")
               ,("author", "aut")
               ,("author in quotations or text abstracts", "aqt")
               ,("author of afterword, colophon, etc.", "aft")
               ,("author of dialog", "aud")
               ,("author of introduction, etc.", "aui")
               ,("autographer", "ato")
               ,("bibliographic antecedent", "ant")
               ,("binder", "bnd")
               ,("binding designer", "bdd")
               ,("blurb writer", "blw")
               ,("book designer", "bkd")
               ,("book producer", "bkp")
               ,("bookjacket designer", "bjd")
               ,("bookplate designer", "bpd")
               ,("bookseller", "bsl")
               ,("braille embosser", "brl")
               ,("broadcaster", "brd")
               ,("calligrapher", "cll")
               ,("cartographer", "ctg")
               ,("caster", "cas")
               ,("censor", "cns")
               ,("choreographer", "chr")
               ,("cinematographer", "cng")
               ,("client", "cli")
               ,("collection registrar", "cor")
               ,("collector", "col")
               ,("collotyper", "clt")
               ,("colorist", "clr")
               ,("commentator", "cmm")
               ,("commentator for written text", "cwt")
               ,("compiler", "com")
               ,("complainant", "cpl")
               ,("complainant-appellant", "cpt")
               ,("complainant-appellee", "cpe")
               ,("composer", "cmp")
               ,("compositor", "cmt")
               ,("conceptor", "ccp")
               ,("conductor", "cnd")
               ,("conservator", "con")
               ,("consultant", "csl")
               ,("consultant to a project", "csp")
               ,("contestant", "cos")
               ,("contestant-appellant", "cot")
               ,("contestant-appellee", "coe")
               ,("contestee", "cts")
               ,("contestee-appellant", "ctt")
               ,("contestee-appellee", "cte")
               ,("contractor", "ctr")
               ,("contributor", "ctb")
               ,("copyright claimant", "cpc")
               ,("copyright holder", "cph")
               ,("corrector", "crr")
               ,("correspondent", "crp")
               ,("costume designer", "cst")
               ,("court governed", "cou")
               ,("court reporter", "crt")
               ,("cover designer", "cov")
               ,("creator", "cre")
               ,("curator", "cur")
               ,("dancer", "dnc")
               ,("data contributor", "dtc")
               ,("data manager", "dtm")
               ,("dedicatee", "dte")
               ,("dedicator", "dto")
               ,("defendant", "dfd")
               ,("defendant-appellant", "dft")
               ,("defendant-appellee", "dfe")
               ,("degree granting institution", "dgg")
               ,("delineator", "dln")
               ,("depicted", "dpc")
               ,("depositor", "dpt")
               ,("designer", "dsr")
               ,("director", "drt")
               ,("dissertant", "dis")
               ,("distribution place", "dbp")
               ,("distributor", "dst")
               ,("donor", "dnr")
               ,("draftsman", "drm")
               ,("dubious author", "dub")
               ,("editor", "edt")
               ,("editor of compilation", "edc")
               ,("editor of moving image work", "edm")
               ,("electrician", "elg")
               ,("electrotyper", "elt")
               ,("enacting jurisdiction", "enj")
               ,("engineer", "eng")
               ,("engraver", "egr")
               ,("etcher", "etr")
               ,("event place", "evp")
               ,("expert", "exp")
               ,("facsimilist", "fac")
               ,("field director", "fld")
               ,("film director", "fmd")
               ,("film distributor", "fds")
               ,("film editor", "flm")
               ,("film producer", "fmp")
               ,("filmmaker", "fmk")
               ,("first party", "fpy")
               ,("forger", "frg")
               ,("former owner", "fmo")
               ,("funder", "fnd")
               ,("geographic information specialist", "gis")
               ,("honoree", "hnr")
               ,("host", "hst")
               ,("host institution", "his")
               ,("illuminator", "ilu")
               ,("illustrator", "ill")
               ,("inscriber", "ins")
               ,("instrumentalist", "itr")
               ,("interviewee", "ive")
               ,("interviewer", "ivr")
               ,("inventor", "inv")
               ,("issuing body", "isb")
               ,("judge", "jud")
               ,("jurisdiction governed", "jug")
               ,("laboratory", "lbr")
               ,("laboratory director", "ldr")
               ,("landscape architect", "lsa")
               ,("lead", "led")
               ,("lender", "len")
               ,("libelant", "lil")
               ,("libelant-appellant", "lit")
               ,("libelant-appellee", "lie")
               ,("libelee", "lel")
               ,("libelee-appellant", "let")
               ,("libelee-appellee", "lee")
               ,("librettist", "lbt")
               ,("licensee", "lse")
               ,("licensor", "lso")
               ,("lighting designer", "lgd")
               ,("lithographer", "ltg")
               ,("lyricist", "lyr")
               ,("manufacture place", "mfp")
               ,("manufacturer", "mfr")
               ,("marbler", "mrb")
               ,("markup editor", "mrk")
               ,("metadata contact", "mdc")
               ,("metal-engraver", "mte")
               ,("moderator", "mod")
               ,("monitor", "mon")
               ,("music copyist", "mcp")
               ,("musical director", "msd")
               ,("musician", "mus")
               ,("narrator", "nrt")
               ,("onscreen presenter", "osp")
               ,("opponent", "opn")
               ,("organizer of meeting", "orm")
               ,("originator", "org")
               ,("other", "oth")
               ,("owner", "own")
               ,("panelist", "pan")
               ,("papermaker", "ppm")
               ,("patent applicant", "pta")
               ,("patent holder", "pth")
               ,("patron", "pat")
               ,("performer", "prf")
               ,("permitting agency", "pma")
               ,("photographer", "pht")
               ,("plaintiff", "ptf")
               ,("plaintiff-appellant", "ptt")
               ,("plaintiff-appellee", "pte")
               ,("platemaker", "plt")
               ,("praeses", "pra")
               ,("presenter", "pre")
               ,("printer", "prt")
               ,("printer of plates", "pop")
               ,("printmaker", "prm")
               ,("process contact", "prc")
               ,("producer", "pro")
               ,("production company", "prn")
               ,("production designer", "prs")
               ,("production manager", "pmn")
               ,("production personnel", "prd")
               ,("production place", "prp")
               ,("programmer", "prg")
               ,("project director", "pdr")
               ,("proofreader", "pfr")
               ,("provider", "prv")
               ,("publication place", "pup")
               ,("publisher", "pbl")
               ,("publishing director", "pbd")
               ,("puppeteer", "ppt")
               ,("radio director", "rdd")
               ,("radio producer", "rpc")
               ,("recording engineer", "rce")
               ,("recordist", "rcd")
               ,("redaktor", "red")
               ,("renderer", "ren")
               ,("reporter", "rpt")
               ,("repository", "rps")
               ,("research team head", "rth")
               ,("research team member", "rtm")
               ,("researcher", "res")
               ,("respondent", "rsp")
               ,("respondent-appellant", "rst")
               ,("respondent-appellee", "rse")
               ,("responsible party", "rpy")
               ,("restager", "rsg")
               ,("restorationist", "rsr")
               ,("reviewer", "rev")
               ,("rubricator", "rbr")
               ,("scenarist", "sce")
               ,("scientific advisor", "sad")
               ,("screenwriter", "aus")
               ,("scribe", "scr")
               ,("sculptor", "scl")
               ,("second party", "spy")
               ,("secretary", "sec")
               ,("seller", "sll")
               ,("set designer", "std")
               ,("setting", "stg")
               ,("signer", "sgn")
               ,("singer", "sng")
               ,("sound designer", "sds")
               ,("speaker", "spk")
               ,("sponsor", "spn")
               ,("stage director", "sgd")
               ,("stage manager", "stm")
               ,("standards body", "stn")
               ,("stereotyper", "str")
               ,("storyteller", "stl")
               ,("supporting host", "sht")
               ,("surveyor", "srv")
               ,("teacher", "tch")
               ,("technical director", "tcd")
               ,("television director", "tld")
               ,("television producer", "tlp")
               ,("thesis advisor", "ths")
               ,("transcriber", "trc")
               ,("translator", "trl")
               ,("type designer", "tyd")
               ,("typographer", "tyg")
               ,("university place", "uvp")
               ,("videographer", "vdg")
               ,("witness", "wit")
               ,("wood engraver", "wde")
               ,("woodcutter", "wdc")
               ,("writer of accompanying material", "wam")
               ,("writer of added commentary", "wac")
               ,("writer of added lyrics", "wal")
               ,("writer of added text", "wat")
               ]

    docTitle' :: Meta -> [Inline]
    docTitle' :: Meta -> [Inline]
    docTitle' meta :: Meta
    meta = [Inline] -> (MetaValue -> [Inline]) -> Maybe MetaValue -> [Inline]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] MetaValue -> [Inline]
    go (Maybe MetaValue -> [Inline]) -> Maybe MetaValue -> [Inline]
    forall a b. (a -> b) -> a -> b
    $ Text -> Meta -> Maybe MetaValue
    lookupMeta "title" Meta
    meta
      where go :: MetaValue -> [Inline]
    go (MetaString s :: Text
    s) = [Text -> Inline
    Str Text
    s]
            go (MetaInlines xs :: [Inline]
    xs) = [Inline]
    xs
            go (MetaBlocks [Para xs :: [Inline]
    xs]) = [Inline]
    xs
            go (MetaBlocks [Plain xs :: [Inline]
    xs]) = [Inline]
    xs
            go (MetaMap m :: Map Text MetaValue
    m) =
                  case Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "type" Map Text MetaValue
    m of
                       Just x :: MetaValue
    x | MetaValue -> Text
    forall a. Walkable Inline a => a -> Text
    stringify MetaValue
    x Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == "main" ->
                                  [Inline] -> (MetaValue -> [Inline]) -> Maybe MetaValue -> [Inline]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] MetaValue -> [Inline]
    go (Maybe MetaValue -> [Inline]) -> Maybe MetaValue -> [Inline]
    forall a b. (a -> b) -> a -> b
    $ Text -> Map Text MetaValue -> Maybe MetaValue
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup "text" Map Text MetaValue
    m
                       _ -> []
            go (MetaList xs :: [MetaValue]
    xs) = (MetaValue -> [Inline]) -> [MetaValue] -> [Inline]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap MetaValue -> [Inline]
    go [MetaValue]
    xs
            go _ = []