    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE ViewPatterns #-}

    {- |
       Module      : Text.Pandoc.Writers.ICML
       Copyright   : Copyright (C) 2013-2020 github.com/mb21
       License     : GNU GPL, version 2 or above

       Stability   : alpha

    Conversion of 'Pandoc' documents to Adobe InCopy ICML, a stand-alone XML format
    which is a subset of the zipped IDML format for which the documentation is
    available here: http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/indesign/sdk/cs6/idml/idml-specification.pdf
    InCopy is the companion word-processor to Adobe InDesign and ICML documents can be integrated
    into InDesign with File -> Place.
    -}
    module Text.Pandoc.Writers.ICML (writeICML) where
    import Control.Monad.Except (catchError)
    import Control.Monad.State.Strict
    import Data.List (intersperse)
    import Data.Maybe (fromMaybe, maybeToList)
    import qualified Data.Set as Set
    import qualified Data.Text as Text
    import Data.Text (Text)
    import Text.Pandoc.Class.PandocMonad (PandocMonad, fetchItem, report)
    import Text.Pandoc.Definition
    import Text.Pandoc.ImageSize
    import Text.Pandoc.Logging
    import Text.Pandoc.Options
    import Text.DocLayout
    import Text.Pandoc.Shared
    import Text.Pandoc.Templates (renderTemplate)
    import Text.Pandoc.Writers.Math (texMathToInlines)
    import Text.Pandoc.Writers.Shared
    import Text.Pandoc.XML

    type Style = [Text]
    type Hyperlink = [(Int, Text)]

    data WriterState = WriterState{
        WriterState -> Set Text
    blockStyles  :: Set.Set Text
      , WriterState -> Set Text
    inlineStyles :: Set.Set Text
      , WriterState -> Hyperlink
    links        :: Hyperlink
      , WriterState -> Int
    listDepth    :: Int
      , WriterState -> Int
    maxListDepth :: Int
      }

    type WS m = StateT WriterState m

    defaultWriterState :: WriterState
    defaultWriterState :: WriterState
    defaultWriterState = WriterState :: Set Text -> Set Text -> Hyperlink -> Int -> Int -> WriterState
    WriterState{
        blockStyles :: Set Text
    blockStyles  = Set Text
    forall a. Set a
    Set.empty
      , inlineStyles :: Set Text
    inlineStyles = Set Text
    forall a. Set a
    Set.empty
      , links :: Hyperlink
    links        = []
      , listDepth :: Int
    listDepth    = 1
      , maxListDepth :: Int
    maxListDepth = 0
      }

    -- inline names (appear in InDesign's character styles pane)
    emphName        :: Text
    strongName      :: Text
    strikeoutName   :: Text
    superscriptName :: Text
    subscriptName   :: Text
    smallCapsName   :: Text
    codeName        :: Text
    linkName        :: Text
    emphName :: Text
    emphName        = "Italic"
    strongName :: Text
    strongName      = "Bold"
    strikeoutName :: Text
    strikeoutName   = "Strikeout"
    superscriptName :: Text
    superscriptName = "Superscript"
    subscriptName :: Text
    subscriptName   = "Subscript"
    smallCapsName :: Text
    smallCapsName   = "SmallCaps"
    codeName :: Text
    codeName        = "Code"
    linkName :: Text
    linkName        = "Link"

    -- block element names (appear in InDesign's paragraph styles pane)
    paragraphName     :: Text
    figureName        :: Text
    imgCaptionName    :: Text
    codeBlockName     :: Text
    blockQuoteName    :: Text
    orderedListName   :: Text
    bulletListName    :: Text
    defListTermName   :: Text
    defListDefName    :: Text
    headerName        :: Text
    tableName         :: Text
    tableHeaderName   :: Text
    tableCaptionName  :: Text
    alignLeftName     :: Text
    alignRightName    :: Text
    alignCenterName   :: Text
    firstListItemName :: Text
    beginsWithName    :: Text
    lowerRomanName    :: Text
    upperRomanName    :: Text
    lowerAlphaName    :: Text
    upperAlphaName    :: Text
    subListParName    :: Text
    footnoteName      :: Text
    citeName          :: Text
    paragraphName :: Text
    paragraphName     = "Paragraph"
    figureName :: Text
    figureName        = "Figure"
    imgCaptionName :: Text
    imgCaptionName    = "Caption"
    codeBlockName :: Text
    codeBlockName     = "CodeBlock"
    blockQuoteName :: Text
    blockQuoteName    = "Blockquote"
    orderedListName :: Text
    orderedListName   = "NumList"
    bulletListName :: Text
    bulletListName    = "BulList"
    defListTermName :: Text
    defListTermName   = "DefListTerm"
    defListDefName :: Text
    defListDefName    = "DefListDef"
    headerName :: Text
    headerName        = "Header"
    tableName :: Text
    tableName         = "TablePar"
    tableHeaderName :: Text
    tableHeaderName   = "TableHeader"
    tableCaptionName :: Text
    tableCaptionName  = "TableCaption"
    alignLeftName :: Text
    alignLeftName     = "LeftAlign"
    alignRightName :: Text
    alignRightName    = "RightAlign"
    alignCenterName :: Text
    alignCenterName   = "CenterAlign"
    firstListItemName :: Text
    firstListItemName = "first"
    beginsWithName :: Text
    beginsWithName    = "beginsWith-"
    lowerRomanName :: Text
    lowerRomanName    = "lowerRoman"
    upperRomanName :: Text
    upperRomanName    = "upperRoman"
    lowerAlphaName :: Text
    lowerAlphaName    = "lowerAlpha"
    upperAlphaName :: Text
    upperAlphaName    = "upperAlpha"
    subListParName :: Text
    subListParName    = "subParagraph"
    footnoteName :: Text
    footnoteName      = "Footnote"
    citeName :: Text
    citeName          = "Cite"

    -- | Convert Pandoc document to string in ICML format.
    writeICML :: PandocMonad m => WriterOptions -> Pandoc -> m Text
    writeICML :: WriterOptions -> Pandoc -> m Text
    writeICML opts :: WriterOptions
    opts (Pandoc meta :: Meta
    meta blocks :: [Block]
    blocks) = do
      let colwidth :: Maybe Int
    colwidth = if WriterOptions -> WrapOption
    writerWrapText WriterOptions
    opts WrapOption -> WrapOption -> Bool
    forall a. Eq a => a -> a -> Bool
    == WrapOption
    WrapAuto
                        then Int -> Maybe Int
    forall a. a -> Maybe a
    Just (Int -> Maybe Int) -> Int -> Maybe Int
    forall a b. (a -> b) -> a -> b
    $ WriterOptions -> Int
    writerColumns WriterOptions
    opts
                        else Maybe Int
    forall a. Maybe a
    Nothing
          renderMeta :: (WriterOptions -> [a] -> t -> StateT WriterState f b) -> t -> f b
    renderMeta f :: WriterOptions -> [a] -> t -> StateT WriterState f b
    f s :: t
    s = (b, WriterState) -> b
    forall a b. (a, b) -> a
    fst ((b, WriterState) -> b) -> f (b, WriterState) -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> StateT WriterState f b -> WriterState -> f (b, WriterState)
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
    runStateT (WriterOptions -> [a] -> t -> StateT WriterState f b
    f WriterOptions
    opts [] t
    s) WriterState
    defaultWriterState
      Context Text
    metadata <- WriterOptions
    -> ([Block] -> m (Doc Text))
    -> ([Inline] -> m (Doc Text))
    -> Meta
    -> m (Context Text)
    forall (m :: * -> *) a.
    (Monad m, TemplateTarget a) =>
    WriterOptions
    -> ([Block] -> m (Doc a))
    -> ([Inline] -> m (Doc a))
    -> Meta
    -> m (Context a)
    metaToContext WriterOptions
    opts
                 ((WriterOptions
     -> [Text] -> [Block] -> StateT WriterState m (Doc Text))
    -> [Block] -> m (Doc Text)
    forall (f :: * -> *) a t b.
    Functor f =>
    (WriterOptions -> [a] -> t -> StateT WriterState f b) -> t -> f b
    renderMeta WriterOptions
    -> [Text] -> [Block] -> StateT WriterState m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    blocksToICML)
                 ((WriterOptions
     -> [Text] -> [Inline] -> StateT WriterState m (Doc Text))
    -> [Inline] -> m (Doc Text)
    forall (f :: * -> *) a t b.
    Functor f =>
    (WriterOptions -> [a] -> t -> StateT WriterState f b) -> t -> f b
    renderMeta WriterOptions
    -> [Text] -> [Inline] -> StateT WriterState m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML)
                 Meta
    meta
      (main :: Doc Text
    main, st :: WriterState
    st) <- StateT WriterState m (Doc Text)
    -> WriterState -> m (Doc Text, WriterState)
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
    runStateT (WriterOptions
    -> [Text] -> [Block] -> StateT WriterState m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    blocksToICML WriterOptions
    opts [] [Block]
    blocks) WriterState
    defaultWriterState
      let context :: Context Text
    context = Text -> Doc Text -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField "body" Doc Text
    main
                  (Context Text -> Context Text) -> Context Text -> Context Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField "charStyles" (WriterState -> Doc Text
    charStylesToDoc WriterState
    st)
                  (Context Text -> Context Text) -> Context Text -> Context Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField "parStyles"  (WriterState -> Doc Text
    parStylesToDoc WriterState
    st)
                  (Context Text -> Context Text) -> Context Text -> Context Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField "hyperlinks" (Hyperlink -> Doc Text
    hyperlinksToDoc (Hyperlink -> Doc Text) -> Hyperlink -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ WriterState -> Hyperlink
    links WriterState
    st) Context Text
    metadata
      Text -> m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> m Text) -> Text -> m Text
    forall a b. (a -> b) -> a -> b
    $ Maybe Int -> Doc Text -> Text
    forall a. HasChars a => Maybe Int -> Doc a -> a
    render Maybe Int
    colwidth (Doc Text -> Text) -> Doc Text -> Text
    forall a b. (a -> b) -> a -> b
    $
        (if WriterOptions -> Bool
    writerPreferAscii WriterOptions
    opts then (Text -> Text) -> Doc Text -> Doc Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Text -> Text
    toEntities else Doc Text -> Doc Text
    forall a. a -> a
    id) (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $
        case WriterOptions -> Maybe (Template Text)
    writerTemplate WriterOptions
    opts of
           Nothing  -> Doc Text
    main
           Just tpl :: Template Text
    tpl -> Template Text -> Context Text -> Doc Text
    forall a b.
    (TemplateTarget a, ToContext a b) =>
    Template a -> b -> Doc a
    renderTemplate Template Text
    tpl Context Text
    context

    -- | Auxiliary functions for parStylesToDoc and charStylesToDoc.
    contains :: Text -> (Text, (Text, Text)) -> [(Text, Text)]
    contains :: Text -> (Text, (Text, Text)) -> [(Text, Text)]
    contains s :: Text
    s rule :: (Text, (Text, Text))
    rule =
      [(Text, (Text, Text)) -> (Text, Text)
    forall a b. (a, b) -> b
    snd (Text, (Text, Text))
    rule | (Text, (Text, Text)) -> Text
    forall a b. (a, b) -> a
    fst (Text, (Text, Text))
    rule Text -> Text -> Bool
    `Text.isInfixOf` Text
    s]

    -- | The monospaced font to use as default.
    monospacedFont :: Doc Text
    monospacedFont :: Doc Text
    monospacedFont = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    False "AppliedFont" [("type", "string")] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ String -> Doc Text
    forall a. HasChars a => String -> Doc a
    text "Courier New"

    -- | How much to indent blockquotes etc.
    defaultIndent :: Int
    defaultIndent :: Int
    defaultIndent = 20

    -- | How much to indent numbered lists before the number.
    defaultListIndent :: Int
    defaultListIndent :: Int
    defaultListIndent = 10

    -- other constants
    lineSeparator :: Text
    lineSeparator :: Text
    lineSeparator = "&#x2028;"

    -- | Convert a WriterState with its block styles to the ICML listing of Paragraph Styles.
    parStylesToDoc :: WriterState -> Doc Text
    parStylesToDoc :: WriterState -> Doc Text
    parStylesToDoc st :: WriterState
    st = [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat ([Doc Text] -> Doc Text) -> [Doc Text] -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ (Text -> Doc Text) -> [Text] -> [Doc Text]
    forall a b. (a -> b) -> [a] -> [b]
    map Text -> Doc Text
    makeStyle ([Text] -> [Doc Text]) -> [Text] -> [Doc Text]
    forall a b. (a -> b) -> a -> b
    $ Set Text -> [Text]
    forall a. Set a -> [a]
    Set.toAscList (Set Text -> [Text]) -> Set Text -> [Text]
    forall a b. (a -> b) -> a -> b
    $ WriterState -> Set Text
    blockStyles WriterState
    st
      where
        makeStyle :: Text -> Doc Text
    makeStyle s :: Text
    s =
          let countSubStrs :: Text -> Text -> Int
    countSubStrs sub :: Text
    sub str :: Text
    str = [(Text, Text)] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length ([(Text, Text)] -> Int) -> [(Text, Text)] -> Int
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> [(Text, Text)]
    Text.breakOnAll Text
    sub Text
    str
              attrs :: [(Text, Text)]
    attrs = ((Text, (Text, Text)) -> [(Text, Text)])
    -> [(Text, (Text, Text))] -> [(Text, Text)]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (Text -> (Text, (Text, Text)) -> [(Text, Text)]
    contains Text
    s) [
                                   (Text
    defListTermName, ("BulletsAndNumberingListType", "BulletList"))
                                 , (Text
    defListTermName, ("FontStyle", "Bold"))
                                 , (Text
    tableHeaderName, ("FontStyle", "Bold"))
                                 , (Text
    alignLeftName,   ("Justification", "LeftAlign"))
                                 , (Text
    alignRightName,  ("Justification", "RightAlign"))
                                 , (Text
    alignCenterName, ("Justification", "CenterAlign"))
                                 , (Text
    headerNameText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>"1", ("PointSize", "36"))
                                 , (Text
    headerNameText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>"2", ("PointSize", "30"))
                                 , (Text
    headerNameText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>"3", ("PointSize", "24"))
                                 , (Text
    headerNameText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>"4", ("PointSize", "18"))
                                 , (Text
    headerNameText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>"5", ("PointSize", "14"))
                                 ]
              -- what is the most nested list type, if any?
              (isBulletList :: Bool
    isBulletList, isOrderedList :: Bool
    isOrderedList) = [Text] -> (Bool, Bool)
    findList ([Text] -> (Bool, Bool)) -> [Text] -> (Bool, Bool)
    forall a b. (a -> b) -> a -> b
    $ [Text] -> [Text]
    forall a. [a] -> [a]
    reverse ([Text] -> [Text]) -> [Text] -> [Text]
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> Text -> [Text]
    splitTextBy (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    ==' ') Text
    s
                where
                  findList :: [Text] -> (Bool, Bool)
    findList [] = (Bool
    False, Bool
    False)
                  findList (x :: Text
    x:xs :: [Text]
    xs) | Text
    x Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    bulletListName  = (Bool
    True, Bool
    False)
                                  | Text
    x Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    orderedListName = (Bool
    False, Bool
    True)
                                  | Bool
    otherwise = [Text] -> (Bool, Bool)
    findList [Text]
    xs
              nBuls :: Int
    nBuls = Text -> Text -> Int
    countSubStrs Text
    bulletListName Text
    s
              nOrds :: Int
    nOrds = Text -> Text -> Int
    countSubStrs Text
    orderedListName Text
    s
              attrs' :: [(Text, Text)]
    attrs' = [(Text, Text)]
    numbering [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
    forall a. Semigroup a => a -> a -> a
    <> [(Text, Text)]
    listType [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
    forall a. Semigroup a => a -> a -> a
    <> [(Text, Text)]
    indent [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
    forall a. Semigroup a => a -> a -> a
    <> [(Text, Text)]
    attrs
                where
                  numbering :: [(Text, Text)]
    numbering | Bool
    isOrderedList = [("NumberingExpression", "^#.^t"), ("NumberingLevel", Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    nOrds)]
                            | Bool
    otherwise     = []
                  listType :: [(Text, Text)]
    listType | Bool
    isOrderedList Bool -> Bool -> Bool
    && Bool -> Bool
    not (Text
    subListParName Text -> Text -> Bool
    `Text.isInfixOf` Text
    s)
                               = [("BulletsAndNumberingListType", "NumberedList")]
                           | Bool
    isBulletList Bool -> Bool -> Bool
    && Bool -> Bool
    not (Text
    subListParName Text -> Text -> Bool
    `Text.isInfixOf` Text
    s)
                               = [("BulletsAndNumberingListType", "BulletList")]
                           | Bool
    otherwise = []
                  indent :: [(Text, Text)]
    indent = [("LeftIndent", Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    indt)]
                    where
                      nBlockQuotes :: Int
    nBlockQuotes = Text -> Text -> Int
    countSubStrs Text
    blockQuoteName Text
    s
                      nDefLists :: Int
    nDefLists = Text -> Text -> Int
    countSubStrs Text
    defListDefName Text
    s
                      indt :: Int
    indt = Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max 0 (Int -> Int) -> Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Int
    defaultListIndentInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *(Int
    nBuls Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    nOrds Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1) Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    defaultIndentInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *(Int
    nBlockQuotes Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    nDefLists)
              props :: Doc Text
    props = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Properties" [] (Doc Text
    basedOn Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    $$ Doc Text
    tabList Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    $$ Doc Text
    numbForm)
                where
                  font :: Doc Text
    font = if Text
    codeBlockName Text -> Text -> Bool
    `Text.isInfixOf` Text
    s
                            then Doc Text
    monospacedFont
                            else Doc Text
    forall a. Doc a
    empty
                  basedOn :: Doc Text
    basedOn = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    False "BasedOn" [("type", "object")] (String -> Doc Text
    forall a. HasChars a => String -> Doc a
    text "$ID/NormalParagraphStyle") Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    $$ Doc Text
    font
                  tabList :: Doc Text
    tabList = if Bool
    isBulletList
                               then Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "TabList" [("type","list")] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "ListItem" [("type","record")]
                                    (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat [
                                        Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    False "Alignment" [("type","enumeration")] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ String -> Doc Text
    forall a. HasChars a => String -> Doc a
    text "LeftAlign"
                                      , Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    False "AlignmentCharacter" [("type","string")] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ String -> Doc Text
    forall a. HasChars a => String -> Doc a
    text "."
                                      , Text -> [(Text, Text)] -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Text -> [(Text, Text)] -> Doc a
    selfClosingTag "Leader" [("type","string")]
                                      , Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    False "Position" [("type","unit")] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ String -> Doc Text
    forall a. HasChars a => String -> Doc a
    text
                                          (String -> Doc Text) -> String -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Int -> String
    forall a. Show a => a -> String
    show (Int -> String) -> Int -> String
    forall a b. (a -> b) -> a -> b
    $ Int
    defaultListIndent Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * (Int
    nBuls Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    nOrds)
                                      ]
                               else Doc Text
    forall a. Doc a
    empty
                  makeNumb :: String -> Doc a
    makeNumb name :: String
    name = Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    False "NumberingFormat" [("type", "string")] (String -> Doc a
    forall a. HasChars a => String -> Doc a
    text String
    name)
                  numbForm :: Doc Text
    numbForm | Text -> Text -> Bool
    Text.isInfixOf Text
    lowerRomanName Text
    s = String -> Doc Text
    forall a. HasChars a => String -> Doc a
    makeNumb "i, ii, iii, iv..."
                           | Text -> Text -> Bool
    Text.isInfixOf Text
    upperRomanName Text
    s = String -> Doc Text
    forall a. HasChars a => String -> Doc a
    makeNumb "I, II, III, IV..."
                           | Text -> Text -> Bool
    Text.isInfixOf Text
    lowerAlphaName Text
    s = String -> Doc Text
    forall a. HasChars a => String -> Doc a
    makeNumb "a, b, c, d..."
                           | Text -> Text -> Bool
    Text.isInfixOf Text
    upperAlphaName Text
    s = String -> Doc Text
    forall a. HasChars a => String -> Doc a
    makeNumb "A, B, C, D..."
                           | Bool
    otherwise = Doc Text
    forall a. Doc a
    empty
          in  Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "ParagraphStyle" ([("Self", "ParagraphStyle/"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    s), ("Name", Text
    s)] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
    forall a. [a] -> [a] -> [a]
    ++ [(Text, Text)]
    attrs') Doc Text
    props

    -- | Convert a WriterState with its inline styles to the ICML listing of Character Styles.
    charStylesToDoc :: WriterState -> Doc Text
    charStylesToDoc :: WriterState -> Doc Text
    charStylesToDoc st :: WriterState
    st = [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat ([Doc Text] -> Doc Text) -> [Doc Text] -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ (Text -> Doc Text) -> [Text] -> [Doc Text]
    forall a b. (a -> b) -> [a] -> [b]
    map Text -> Doc Text
    makeStyle ([Text] -> [Doc Text]) -> [Text] -> [Doc Text]
    forall a b. (a -> b) -> a -> b
    $ Set Text -> [Text]
    forall a. Set a -> [a]
    Set.toAscList (Set Text -> [Text]) -> Set Text -> [Text]
    forall a b. (a -> b) -> a -> b
    $ WriterState -> Set Text
    inlineStyles WriterState
    st
      where
        makeStyle :: Text -> Doc Text
    makeStyle s :: Text
    s =
          let attrs :: [(Text, Text)]
    attrs = ((Text, (Text, Text)) -> [(Text, Text)])
    -> [(Text, (Text, Text))] -> [(Text, Text)]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (Text -> (Text, (Text, Text)) -> [(Text, Text)]
    contains Text
    s) [
                                   (Text
    strikeoutName,   ("StrikeThru", "true"))
                                 , (Text
    superscriptName, ("Position", "Superscript"))
                                 , (Text
    subscriptName,   ("Position", "Subscript"))
                                 , (Text
    smallCapsName,   ("Capitalization", "SmallCaps"))
                                 ]
              attrs' :: [(Text, Text)]
    attrs' | Text -> Text -> Bool
    Text.isInfixOf Text
    emphName Text
    s Bool -> Bool -> Bool
    && Text -> Text -> Bool
    Text.isInfixOf Text
    strongName Text
    s
                                                   = ("FontStyle", "Bold Italic") (Text, Text) -> [(Text, Text)] -> [(Text, Text)]
    forall a. a -> [a] -> [a]
    : [(Text, Text)]
    attrs
                     | Text -> Text -> Bool
    Text.isInfixOf Text
    strongName Text
    s = ("FontStyle", "Bold") (Text, Text) -> [(Text, Text)] -> [(Text, Text)]
    forall a. a -> [a] -> [a]
    : [(Text, Text)]
    attrs
                     | Text -> Text -> Bool
    Text.isInfixOf Text
    emphName Text
    s   = ("FontStyle", "Italic") (Text, Text) -> [(Text, Text)] -> [(Text, Text)]
    forall a. a -> [a] -> [a]
    : [(Text, Text)]
    attrs
                     | Bool
    otherwise                   = [(Text, Text)]
    attrs
              props :: Doc Text
    props = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Properties" [] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $
                        Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    False "BasedOn" [("type", "object")] (String -> Doc Text
    forall a. HasChars a => String -> Doc a
    text "$ID/NormalCharacterStyle") Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    $$ Doc Text
    font
                      where
                        font :: Doc Text
    font =
                          if Text
    codeName Text -> Text -> Bool
    `Text.isInfixOf` Text
    s
                             then Doc Text
    monospacedFont
                             else Doc Text
    forall a. Doc a
    empty
          in  Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "CharacterStyle" ([("Self", "CharacterStyle/"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    s), ("Name", Text
    s)] [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
    forall a. [a] -> [a] -> [a]
    ++ [(Text, Text)]
    attrs') Doc Text
    props

    -- | Escape colon characters as %3a
    escapeColons :: Text -> Text
    escapeColons :: Text -> Text
    escapeColons = (Char -> Text) -> Text -> Text
    Text.concatMap ((Char -> Text) -> Text -> Text) -> (Char -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ \x :: Char
    x -> case Char
    x of
      ':' -> "%3a"
      _   -> Char -> Text
    Text.singleton Char
    x

    -- | Convert a list of (identifier, url) pairs to the ICML listing of hyperlinks.
    hyperlinksToDoc :: Hyperlink -> Doc Text
    hyperlinksToDoc :: Hyperlink -> Doc Text
    hyperlinksToDoc []     = Doc Text
    forall a. Doc a
    empty
    hyperlinksToDoc (x :: (Int, Text)
    x:xs :: Hyperlink
    xs) = (Int, Text) -> Doc Text
    forall a. Show a => (a, Text) -> Doc Text
    hyp (Int, Text)
    x Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    $$ Hyperlink -> Doc Text
    hyperlinksToDoc Hyperlink
    xs
      where
        hyp :: (a, Text) -> Doc Text
    hyp (ident :: a
    ident, url :: Text
    url) = Doc Text
    hdest Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    $$ Doc Text
    hlink
          where
            hdest :: Doc Text
    hdest = Text -> [(Text, Text)] -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Text -> [(Text, Text)] -> Doc a
    selfClosingTag "HyperlinkURLDestination"
                      [("Self", "HyperlinkURLDestination/"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text -> Text
    escapeColons Text
    url), ("Name","link"), ("DestinationURL",Text
    url), ("DestinationUniqueKey","1")] -- HyperlinkURLDestination with more than one colon crashes CS6
            hlink :: Doc Text
    hlink = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Hyperlink" [("Self","uf-"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>a -> Text
    forall a. Show a => a -> Text
    tshow a
    ident),  ("Name",Text
    url),
                        ("Source","htss-"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>a -> Text
    forall a. Show a => a -> Text
    tshow a
    ident), ("Visible","true"), ("DestinationUniqueKey","1")]
                      (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Properties" []
                      (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    False "BorderColor" [("type","enumeration")] (String -> Doc Text
    forall a. HasChars a => String -> Doc a
    text "Black")
                      Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    $$ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    False "Destination" [("type","object")] (Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text -> Doc Text) -> Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ "HyperlinkURLDestination/"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text -> Text
    escapeColons (Text -> Text
    escapeStringForXML Text
    url)) -- HyperlinkURLDestination with more than one colon crashes CS6

    -- | Key for specifying user-defined styles
    dynamicStyleKey :: Text
    dynamicStyleKey :: Text
    dynamicStyleKey = "custom-style"

    -- | Convert a list of Pandoc blocks to ICML.
    blocksToICML :: PandocMonad m => WriterOptions -> Style -> [Block] -> WS m (Doc Text)
    blocksToICML :: WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    blocksToICML opts :: WriterOptions
    opts style :: [Text]
    style lst :: [Block]
    lst = do
      [Doc Text]
    docs <- (Block -> WS m (Doc Text))
    -> [Block] -> StateT WriterState m [Doc Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    blockToICML WriterOptions
    opts [Text]
    style) [Block]
    lst
      Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    intersperseBrs [Doc Text]
    docs

    -- | Convert a Pandoc block element to ICML.
    blockToICML :: PandocMonad m => WriterOptions -> Style -> Block -> WS m (Doc Text)
    blockToICML :: WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (Plain lst :: [Inline]
    lst) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    parStyle WriterOptions
    opts [Text]
    style [Inline]
    lst
    -- title beginning with fig: indicates that the image is a figure
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (Para img :: [Inline]
    img@[Image _ txt :: [Inline]
    txt (_,Text -> Text -> Maybe Text
    Text.stripPrefix "fig:" -> Just _)]) = do
      Doc Text
    figure  <- WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    parStyle WriterOptions
    opts (Text
    figureNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    img
      Doc Text
    caption <- WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    parStyle WriterOptions
    opts (Text
    imgCaptionNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    txt
      Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    intersperseBrs [Doc Text
    figure, Doc Text
    caption]
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (Para lst :: [Inline]
    lst) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    parStyle WriterOptions
    opts (Text
    paragraphNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    lst
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (LineBlock lns :: [[Inline]]
    lns) =
      WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    blockToICML WriterOptions
    opts [Text]
    style (Block -> WS m (Doc Text)) -> Block -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [[Inline]] -> Block
    linesToPara [[Inline]]
    lns
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (CodeBlock _ str :: Text
    str) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    parStyle WriterOptions
    opts (Text
    codeBlockNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Text -> Inline
    Str Text
    str]
    blockToICML _ _ b :: Block
    b@(RawBlock f :: Format
    f str :: Text
    str)
      | Format
    f Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format "icml" = Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    str
      | Bool
    otherwise          = do
          LogMessage -> StateT WriterState m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> StateT WriterState m ())
    -> LogMessage -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ Block -> LogMessage
    BlockNotRendered Block
    b
          Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    empty
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (BlockQuote blocks :: [Block]
    blocks) = WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    blocksToICML WriterOptions
    opts (Text
    blockQuoteNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Block]
    blocks
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (OrderedList attribs :: ListAttributes
    attribs lst :: [[Block]]
    lst) = WriterOptions
    -> Text
    -> [Text]
    -> Maybe ListAttributes
    -> [[Block]]
    -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions
    -> Text
    -> [Text]
    -> Maybe ListAttributes
    -> [[Block]]
    -> WS m (Doc Text)
    listItemsToICML WriterOptions
    opts Text
    orderedListName [Text]
    style (ListAttributes -> Maybe ListAttributes
    forall a. a -> Maybe a
    Just ListAttributes
    attribs) [[Block]]
    lst
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (BulletList lst :: [[Block]]
    lst) = WriterOptions
    -> Text
    -> [Text]
    -> Maybe ListAttributes
    -> [[Block]]
    -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions
    -> Text
    -> [Text]
    -> Maybe ListAttributes
    -> [[Block]]
    -> WS m (Doc Text)
    listItemsToICML WriterOptions
    opts Text
    bulletListName [Text]
    style Maybe ListAttributes
    forall a. Maybe a
    Nothing [[Block]]
    lst
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (DefinitionList lst :: [([Inline], [[Block]])]
    lst) = [Doc Text] -> Doc Text
    intersperseBrs ([Doc Text] -> Doc Text)
    -> StateT WriterState m [Doc Text] -> WS m (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` (([Inline], [[Block]]) -> WS m (Doc Text))
    -> [([Inline], [[Block]])] -> StateT WriterState m [Doc Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Text] -> ([Inline], [[Block]]) -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> ([Inline], [[Block]]) -> WS m (Doc Text)
    definitionListItemToICML WriterOptions
    opts [Text]
    style) [([Inline], [[Block]])]
    lst
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (Header lvl :: Int
    lvl (_, cls :: [Text]
    cls, _) lst :: [Inline]
    lst) =
      let stl :: [Text]
    stl = (Text
    headerName Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    lvl Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    unnumbered)Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style
          unnumbered :: Text
    unnumbered = if "unnumbered" Text -> [Text] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Text]
    cls
                       then " (unnumbered)"
                       else ""
      in WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    parStyle WriterOptions
    opts [Text]
    stl [Inline]
    lst
    blockToICML _ _ HorizontalRule = Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    empty -- we could insert a page break instead
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (Table caption :: [Inline]
    caption aligns :: [Alignment]
    aligns widths :: [Double]
    widths headers :: [[Block]]
    headers rows :: [[[Block]]]
    rows) =
      let style' :: [Text]
    style' = Text
    tableName Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    : [Text]
    style
          noHeader :: Bool
    noHeader  = ([Block] -> Bool) -> [[Block]] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all [Block] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [[Block]]
    headers
          nrHeaders :: Text
    nrHeaders = if Bool
    noHeader
                         then "0"
                         else "1"
          nrRows :: Int
    nrRows = [[[Block]]] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [[[Block]]]
    rows
          nrCols :: Int
    nrCols = if [[[Block]]] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [[[Block]]]
    rows
                      then 0
                      else [[Block]] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length ([[Block]] -> Int) -> [[Block]] -> Int
    forall a b. (a -> b) -> a -> b
    $ [[[Block]]] -> [[Block]]
    forall a. [a] -> a
    head [[[Block]]]
    rows
          rowsToICML :: [[[Block]]] -> t -> StateT WriterState m (Doc Text)
    rowsToICML [] _ = Doc Text -> StateT WriterState m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    empty
          rowsToICML (col :: [[Block]]
    col:rest :: [[[Block]]]
    rest) rowNr :: t
    rowNr =
            (Doc Text -> Doc Text -> Doc Text)
    -> StateT WriterState m (Doc Text)
    -> StateT WriterState m (Doc Text)
    -> StateT WriterState m (Doc Text)
    forall (m :: * -> *) a1 a2 r.
    Monad m =>
    (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    ($$) ([[Block]]
    -> [Alignment] -> t -> Int -> StateT WriterState m (Doc Text)
    forall (m :: * -> *) a a.
    (PandocMonad m, Num a, Eq a, Num a, Show a, Show a) =>
    [[Block]]
    -> [Alignment] -> a -> a -> StateT WriterState m (Doc Text)
    colsToICML [[Block]]
    col [Alignment]
    aligns t
    rowNr (0::Int)) (StateT WriterState m (Doc Text)
     -> StateT WriterState m (Doc Text))
    -> StateT WriterState m (Doc Text)
    -> StateT WriterState m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [[[Block]]] -> t -> StateT WriterState m (Doc Text)
    rowsToICML [[[Block]]]
    rest (t
    rowNrt -> t -> t
    forall a. Num a => a -> a -> a
    +1)
          colsToICML :: [[Block]]
    -> [Alignment] -> a -> a -> StateT WriterState m (Doc Text)
    colsToICML [] _ _ _ = Doc Text -> StateT WriterState m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    empty
          colsToICML _ [] _ _ = Doc Text -> StateT WriterState m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    empty
          colsToICML (cell :: [Block]
    cell:rest :: [[Block]]
    rest) (alig :: Alignment
    alig:restAligns :: [Alignment]
    restAligns) rowNr :: a
    rowNr colNr :: a
    colNr = do
            let stl :: [Text]
    stl  = if a
    rowNr a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0 Bool -> Bool -> Bool
    && Bool -> Bool
    not Bool
    noHeader
                          then Text
    tableHeaderNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style'
                          else [Text]
    style'
                stl' :: [Text]
    stl' | Alignment
    alig Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignLeft = Text
    alignLeftName Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    : [Text]
    stl
                     | Alignment
    alig Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignRight = Text
    alignRightName Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    : [Text]
    stl
                     | Alignment
    alig Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignCenter = Text
    alignCenterName Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    : [Text]
    stl
                     | Bool
    otherwise = [Text]
    stl
            Doc Text
    c <- WriterOptions
    -> [Text] -> [Block] -> StateT WriterState m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    blocksToICML WriterOptions
    opts [Text]
    stl' [Block]
    cell
            let cl :: StateT WriterState m (Doc Text)
    cl = Doc Text -> StateT WriterState m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> StateT WriterState m (Doc Text))
    -> Doc Text -> StateT WriterState m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Cell"
                       [("Name", a -> Text
    forall a. Show a => a -> Text
    tshow a
    colNr Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>":"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> a -> Text
    forall a. Show a => a -> Text
    tshow a
    rowNr), ("AppliedCellStyle","CellStyle/Cell")] Doc Text
    c
            (Doc Text -> Doc Text -> Doc Text)
    -> StateT WriterState m (Doc Text)
    -> StateT WriterState m (Doc Text)
    -> StateT WriterState m (Doc Text)
    forall (m :: * -> *) a1 a2 r.
    Monad m =>
    (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    ($$) StateT WriterState m (Doc Text)
    cl (StateT WriterState m (Doc Text)
     -> StateT WriterState m (Doc Text))
    -> StateT WriterState m (Doc Text)
    -> StateT WriterState m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [[Block]]
    -> [Alignment] -> a -> a -> StateT WriterState m (Doc Text)
    colsToICML [[Block]]
    rest [Alignment]
    restAligns a
    rowNr (a
    colNra -> a -> a
    forall a. Num a => a -> a -> a
    +1)
      in  do
          let tabl :: [[[Block]]]
    tabl = if Bool
    noHeader
                        then [[[Block]]]
    rows
                        else [[Block]]
    headers[[Block]] -> [[[Block]]] -> [[[Block]]]
    forall a. a -> [a] -> [a]
    :[[[Block]]]
    rows
          Doc Text
    cells <- [[[Block]]] -> Int -> WS m (Doc Text)
    forall (m :: * -> *) t.
    (PandocMonad m, Eq t, Num t, Show t) =>
    [[[Block]]] -> t -> StateT WriterState m (Doc Text)
    rowsToICML [[[Block]]]
    tabl (0::Int)
          let colWidths :: a -> [(a, Text)]
    colWidths w :: a
    w =
                [("SingleColumnWidth",a -> Text
    forall a. Show a => a -> Text
    tshow (a -> Text) -> a -> Text
    forall a b. (a -> b) -> a -> b
    $ 500 a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    w) | a
    w a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    > 0]
          let tupToDoc :: (a, a) -> Doc a
    tupToDoc tup :: (a, a)
    tup = Text -> [(Text, Text)] -> Doc a
    forall a.
    (HasChars a, IsString a) =>
    Text -> [(Text, Text)] -> Doc a
    selfClosingTag "Column" ([(Text, Text)] -> Doc a) -> [(Text, Text)] -> Doc a
    forall a b. (a -> b) -> a -> b
    $ ("Name",a -> Text
    forall a. Show a => a -> Text
    tshow (a -> Text) -> a -> Text
    forall a b. (a -> b) -> a -> b
    $ (a, a) -> a
    forall a b. (a, b) -> a
    fst (a, a)
    tup) (Text, Text) -> [(Text, Text)] -> [(Text, Text)]
    forall a. a -> [a] -> [a]
    : a -> [(Text, Text)]
    forall a a. (Ord a, Num a, IsString a, Show a) => a -> [(a, Text)]
    colWidths ((a, a) -> a
    forall a b. (a, b) -> b
    snd (a, a)
    tup)
          let colDescs :: Doc Text
    colDescs = [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat ([Doc Text] -> Doc Text) -> [Doc Text] -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ (Int -> Double -> Doc Text) -> [Int] -> [Double] -> [Doc Text]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (((Int, Double) -> Doc Text) -> Int -> Double -> Doc Text
    forall a b c. ((a, b) -> c) -> a -> b -> c
    curry (Int, Double) -> Doc Text
    forall a a a.
    (HasChars a, Ord a, Num a, Show a, Show a) =>
    (a, a) -> Doc a
    tupToDoc) [0..Int
    nrColsInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -1] [Double]
    widths
          let tableDoc :: WS m (Doc Text)
    tableDoc = Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Table" [
                             ("AppliedTableStyle","TableStyle/Table")
                           , ("HeaderRowCount", Text
    nrHeaders)
                           , ("BodyRowCount", Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    nrRows)
                           , ("ColumnCount", Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    nrCols)
                           ] (Doc Text
    colDescs Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    $$ Doc Text
    cells)
          (Doc Text -> Doc Text -> Doc Text)
    -> WS m (Doc Text) -> WS m (Doc Text) -> WS m (Doc Text)
    forall (m :: * -> *) a1 a2 r.
    Monad m =>
    (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    ($$) WS m (Doc Text)
    tableDoc (WS m (Doc Text) -> WS m (Doc Text))
    -> WS m (Doc Text) -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    parStyle WriterOptions
    opts (Text
    tableCaptionNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    caption
    blockToICML opts :: WriterOptions
    opts style :: [Text]
    style (Div (_, _, kvs :: [(Text, Text)]
    kvs) lst :: [Block]
    lst) =
      let dynamicStyle :: [Text]
    dynamicStyle = Maybe Text -> [Text]
    forall a. Maybe a -> [a]
    maybeToList (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 Text
    dynamicStyleKey [(Text, Text)]
    kvs
      in  WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    blocksToICML WriterOptions
    opts ([Text]
    dynamicStyle [Text] -> [Text] -> [Text]
    forall a. Semigroup a => a -> a -> a
    <> [Text]
    style) [Block]
    lst
    blockToICML _ _ Null = Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    empty

    -- | Convert a list of lists of blocks to ICML list items.
    listItemsToICML :: PandocMonad m => WriterOptions -> Text -> Style -> Maybe ListAttributes -> [[Block]] -> WS m (Doc Text)
    listItemsToICML :: WriterOptions
    -> Text
    -> [Text]
    -> Maybe ListAttributes
    -> [[Block]]
    -> WS m (Doc Text)
    listItemsToICML _ _ _ _ [] = Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    empty
    listItemsToICML opts :: WriterOptions
    opts listType :: Text
    listType style :: [Text]
    style attribs :: Maybe ListAttributes
    attribs (first :: [Block]
    first:rest :: [[Block]]
    rest) = do
      WriterState
    st <- StateT WriterState m WriterState
    forall s (m :: * -> *). MonadState s m => m s
    get
      WriterState -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => s -> m ()
    put WriterState
    st{ listDepth :: Int
    listDepth = 1 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + WriterState -> Int
    listDepth WriterState
    st}
      let stl :: [Text]
    stl = Text
    listTypeText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style
      let f :: WS m (Doc Text)
    f = WriterOptions
    -> [Text]
    -> Bool
    -> Maybe ListAttributes
    -> [Block]
    -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions
    -> [Text]
    -> Bool
    -> Maybe ListAttributes
    -> [Block]
    -> WS m (Doc Text)
    listItemToICML WriterOptions
    opts [Text]
    stl Bool
    True Maybe ListAttributes
    attribs [Block]
    first
      let r :: [WS m (Doc Text)]
    r = ([Block] -> WS m (Doc Text)) -> [[Block]] -> [WS m (Doc Text)]
    forall a b. (a -> b) -> [a] -> [b]
    map (WriterOptions
    -> [Text]
    -> Bool
    -> Maybe ListAttributes
    -> [Block]
    -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions
    -> [Text]
    -> Bool
    -> Maybe ListAttributes
    -> [Block]
    -> WS m (Doc Text)
    listItemToICML WriterOptions
    opts [Text]
    stl Bool
    False Maybe ListAttributes
    attribs) [[Block]]
    rest
      [Doc Text]
    docs <- [WS m (Doc Text)] -> StateT WriterState m [Doc Text]
    forall (t :: * -> *) (m :: * -> *) a.
    (Traversable t, Monad m) =>
    t (m a) -> m (t a)
    sequence ([WS m (Doc Text)] -> StateT WriterState m [Doc Text])
    -> [WS m (Doc Text)] -> StateT WriterState m [Doc Text]
    forall a b. (a -> b) -> a -> b
    $ WS m (Doc Text)
    fWS m (Doc Text) -> [WS m (Doc Text)] -> [WS m (Doc Text)]
    forall a. a -> [a] -> [a]
    :[WS m (Doc Text)]
    r
      WriterState
    s    <- StateT WriterState m WriterState
    forall s (m :: * -> *). MonadState s m => m s
    get
      let maxD :: Int
    maxD = Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max (WriterState -> Int
    maxListDepth WriterState
    s) (WriterState -> Int
    listDepth WriterState
    s)
      WriterState -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => s -> m ()
    put WriterState
    s{ listDepth :: Int
    listDepth = 1, maxListDepth :: Int
    maxListDepth = Int
    maxD }
      Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    intersperseBrs [Doc Text]
    docs

    -- | Convert a list of blocks to ICML list items.
    listItemToICML :: PandocMonad m => WriterOptions -> Style -> Bool-> Maybe ListAttributes -> [Block] -> WS m (Doc Text)
    listItemToICML :: WriterOptions
    -> [Text]
    -> Bool
    -> Maybe ListAttributes
    -> [Block]
    -> WS m (Doc Text)
    listItemToICML opts :: WriterOptions
    opts style :: [Text]
    style isFirst :: Bool
    isFirst attribs :: Maybe ListAttributes
    attribs item :: [Block]
    item =
      let makeNumbStart :: Maybe (a, ListNumberStyle, c) -> [Text]
    makeNumbStart (Just (beginsWith :: a
    beginsWith, numbStl :: ListNumberStyle
    numbStl, _)) =
            let doN :: ListNumberStyle -> [Text]
    doN DefaultStyle = []
                doN LowerRoman   = [Text
    lowerRomanName]
                doN UpperRoman   = [Text
    upperRomanName]
                doN LowerAlpha   = [Text
    lowerAlphaName]
                doN UpperAlpha   = [Text
    upperAlphaName]
                doN _            = []
                bw :: [Text]
    bw =
                  [Text
    beginsWithName Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> a -> Text
    forall a. Show a => a -> Text
    tshow a
    beginsWith | a
    beginsWith a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    > 1]
            in  ListNumberStyle -> [Text]
    doN ListNumberStyle
    numbStl [Text] -> [Text] -> [Text]
    forall a. [a] -> [a] -> [a]
    ++ [Text]
    bw
          makeNumbStart Nothing = []
          stl :: [Text]
    stl = if Bool
    isFirst
                   then Text
    firstListItemNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style
                   else [Text]
    style
          stl' :: [Text]
    stl' = Maybe ListAttributes -> [Text]
    forall a c.
    (Ord a, Num a, Show a) =>
    Maybe (a, ListNumberStyle, c) -> [Text]
    makeNumbStart Maybe ListAttributes
    attribs [Text] -> [Text] -> [Text]
    forall a. [a] -> [a] -> [a]
    ++ [Text]
    stl
      in  if [Block] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Block]
    item Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 1
             then do
               let insertTab :: Block -> WS m (Doc Text)
    insertTab (Para lst :: [Inline]
    lst) = WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    blockToICML WriterOptions
    opts (Text
    subListParNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) (Block -> WS m (Doc Text)) -> Block -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Block
    Para ([Inline] -> Block) -> [Inline] -> Block
    forall a b. (a -> b) -> a -> b
    $ Text -> Inline
    Str "\t"Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    :[Inline]
    lst
                   insertTab block :: Block
    block      = WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    blockToICML WriterOptions
    opts [Text]
    style Block
    block
               Doc Text
    f <- WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    blockToICML WriterOptions
    opts [Text]
    stl' (Block -> WS m (Doc Text)) -> Block -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Block] -> Block
    forall a. [a] -> a
    head [Block]
    item
               [Doc Text]
    r <- (Block -> WS m (Doc Text))
    -> [Block] -> StateT WriterState m [Doc Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM Block -> WS m (Doc Text)
    forall (m :: * -> *). PandocMonad m => Block -> WS m (Doc Text)
    insertTab ([Block] -> StateT WriterState m [Doc Text])
    -> [Block] -> StateT WriterState m [Doc Text]
    forall a b. (a -> b) -> a -> b
    $ [Block] -> [Block]
    forall a. [a] -> [a]
    tail [Block]
    item
               Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    intersperseBrs (Doc Text
    f Doc Text -> [Doc Text] -> [Doc Text]
    forall a. a -> [a] -> [a]
    : [Doc Text]
    r)
             else WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    blocksToICML WriterOptions
    opts [Text]
    stl' [Block]
    item

    definitionListItemToICML :: PandocMonad m => WriterOptions -> Style -> ([Inline],[[Block]]) -> WS m (Doc Text)
    definitionListItemToICML :: WriterOptions -> [Text] -> ([Inline], [[Block]]) -> WS m (Doc Text)
    definitionListItemToICML opts :: WriterOptions
    opts style :: [Text]
    style (term :: [Inline]
    term,defs :: [[Block]]
    defs) = do
      Doc Text
    term' <- WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    parStyle WriterOptions
    opts (Text
    defListTermNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    term
      [Doc Text]
    defs' <- ([Block] -> WS m (Doc Text))
    -> [[Block]] -> StateT WriterState m [Doc Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    blocksToICML WriterOptions
    opts (Text
    defListDefNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style)) [[Block]]
    defs
      Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    intersperseBrs (Doc Text
    term' Doc Text -> [Doc Text] -> [Doc Text]
    forall a. a -> [a] -> [a]
    : [Doc Text]
    defs')

    -- | Convert a list of inline elements to ICML.
    inlinesToICML :: PandocMonad m => WriterOptions -> Style -> [Inline] -> WS m (Doc Text)
    inlinesToICML :: WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML opts :: WriterOptions
    opts style :: [Text]
    style lst :: [Inline]
    lst = [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat ([Doc Text] -> Doc Text)
    -> StateT WriterState m [Doc Text] -> WS m (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` (Inline -> WS m (Doc Text))
    -> [Inline] -> StateT WriterState m [Doc Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Text] -> Inline -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> Inline -> WS m (Doc Text)
    inlineToICML WriterOptions
    opts [Text]
    style) (WriterOptions -> [Inline] -> [Inline]
    mergeStrings WriterOptions
    opts [Inline]
    lst)

    -- | Convert an inline element to ICML.
    inlineToICML :: PandocMonad m => WriterOptions -> Style -> Inline -> WS m (Doc Text)
    inlineToICML :: WriterOptions -> [Text] -> Inline -> WS m (Doc Text)
    inlineToICML _    style :: [Text]
    style (Str str :: Text
    str) = [Text] -> Doc Text -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Text] -> Doc Text -> WS m (Doc Text)
    charStyle [Text]
    style (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text -> Doc Text) -> Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    escapeStringForXML Text
    str
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Emph lst :: [Inline]
    lst) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts (Text
    emphNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    lst
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Strong lst :: [Inline]
    lst) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts (Text
    strongNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    lst
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Strikeout lst :: [Inline]
    lst) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts (Text
    strikeoutNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    lst
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Superscript lst :: [Inline]
    lst) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts (Text
    superscriptNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    lst
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Subscript lst :: [Inline]
    lst) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts (Text
    subscriptNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    lst
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (SmallCaps lst :: [Inline]
    lst) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts (Text
    smallCapsNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    lst
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Quoted SingleQuote lst :: [Inline]
    lst) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts [Text]
    style ([Inline] -> WS m (Doc Text)) -> [Inline] -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $
      WriterOptions -> [Inline] -> [Inline]
    mergeStrings WriterOptions
    opts ([Inline] -> [Inline]) -> [Inline] -> [Inline]
    forall a b. (a -> b) -> a -> b
    $ [Text -> Inline
    Str "‘"] [Inline] -> [Inline] -> [Inline]
    forall a. [a] -> [a] -> [a]
    ++ [Inline]
    lst [Inline] -> [Inline] -> [Inline]
    forall a. [a] -> [a] -> [a]
    ++ [Text -> Inline
    Str "’"]
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Quoted DoubleQuote lst :: [Inline]
    lst) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts [Text]
    style ([Inline] -> WS m (Doc Text)) -> [Inline] -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $
      WriterOptions -> [Inline] -> [Inline]
    mergeStrings WriterOptions
    opts ([Inline] -> [Inline]) -> [Inline] -> [Inline]
    forall a b. (a -> b) -> a -> b
    $ [Text -> Inline
    Str "“"] [Inline] -> [Inline] -> [Inline]
    forall a. [a] -> [a] -> [a]
    ++ [Inline]
    lst [Inline] -> [Inline] -> [Inline]
    forall a. [a] -> [a] -> [a]
    ++ [Text -> Inline
    Str "”"]
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Cite _ lst :: [Inline]
    lst) = WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts (Text
    citeNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    lst
    inlineToICML _    style :: [Text]
    style (Code _ str :: Text
    str) = [Text] -> Doc Text -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Text] -> Doc Text -> WS m (Doc Text)
    charStyle (Text
    codeNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text -> Doc Text) -> Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    escapeStringForXML Text
    str
    inlineToICML _    style :: [Text]
    style Space = [Text] -> Doc Text -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Text] -> Doc Text -> WS m (Doc Text)
    charStyle [Text]
    style Doc Text
    forall a. Doc a
    space
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style SoftBreak =
      case WriterOptions -> WrapOption
    writerWrapText WriterOptions
    opts of
           WrapAuto     -> [Text] -> Doc Text -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Text] -> Doc Text -> WS m (Doc Text)
    charStyle [Text]
    style Doc Text
    forall a. Doc a
    space
           WrapNone     -> [Text] -> Doc Text -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Text] -> Doc Text -> WS m (Doc Text)
    charStyle [Text]
    style Doc Text
    forall a. Doc a
    space
           WrapPreserve -> [Text] -> Doc Text -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Text] -> Doc Text -> WS m (Doc Text)
    charStyle [Text]
    style Doc Text
    forall a. Doc a
    cr
    inlineToICML _ style :: [Text]
    style LineBreak = [Text] -> Doc Text -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Text] -> Doc Text -> WS m (Doc Text)
    charStyle [Text]
    style (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    lineSeparator
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Math mt :: MathType
    mt str :: Text
    str) =
      m [Inline] -> StateT WriterState m [Inline]
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (MathType -> Text -> m [Inline]
    forall (m :: * -> *).
    PandocMonad m =>
    MathType -> Text -> m [Inline]
    texMathToInlines MathType
    mt Text
    str) StateT WriterState m [Inline]
    -> ([Inline] -> WS m (Doc Text)) -> WS m (Doc Text)
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>=
        (([Doc Text] -> Doc Text)
    -> StateT WriterState m [Doc Text] -> WS m (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat (StateT WriterState m [Doc Text] -> WS m (Doc Text))
    -> ([Inline] -> StateT WriterState m [Doc Text])
    -> [Inline]
    -> WS m (Doc Text)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Inline -> WS m (Doc Text))
    -> [Inline] -> StateT WriterState m [Doc Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Text] -> Inline -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> Inline -> WS m (Doc Text)
    inlineToICML WriterOptions
    opts [Text]
    style))
    inlineToICML _ _ il :: Inline
    il@(RawInline f :: Format
    f str :: Text
    str)
      | Format
    f Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format "icml" = Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    str
      | Bool
    otherwise          = do
          LogMessage -> StateT WriterState m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> StateT WriterState m ())
    -> LogMessage -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ Inline -> LogMessage
    InlineNotRendered Inline
    il
          Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    empty
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Link _ lst :: [Inline]
    lst (url :: Text
    url, title :: Text
    title)) = do
      Doc Text
    content <- WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts (Text
    linkNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) [Inline]
    lst
      (WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text)
    forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
    state ((WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text))
    -> (WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ \st :: WriterState
    st ->
                let ident :: Int
    ident = if Hyperlink -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (Hyperlink -> Bool) -> Hyperlink -> Bool
    forall a b. (a -> b) -> a -> b
    $ WriterState -> Hyperlink
    links WriterState
    st
                               then 1::Int
                               else 1 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + (Int, Text) -> Int
    forall a b. (a, b) -> a
    fst (Hyperlink -> (Int, Text)
    forall a. [a] -> a
    head (Hyperlink -> (Int, Text)) -> Hyperlink -> (Int, Text)
    forall a b. (a -> b) -> a -> b
    $ WriterState -> Hyperlink
    links WriterState
    st)
                    newst :: WriterState
    newst = WriterState
    st{ links :: Hyperlink
    links = (Int
    ident, Text
    url)(Int, Text) -> Hyperlink -> Hyperlink
    forall a. a -> [a] -> [a]
    :WriterState -> Hyperlink
    links WriterState
    st }
                    cont :: Doc Text
    cont  = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "HyperlinkTextSource"
                             [("Self","htss-"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    ident), ("Name",Text
    title), ("Hidden","false")] Doc Text
    content
                in  (Doc Text
    cont, WriterState
    newst)
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Image attr :: Attr
    attr _ target :: (Text, Text)
    target) = WriterOptions -> [Text] -> Attr -> (Text, Text) -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> Attr -> (Text, Text) -> WS m (Doc Text)
    imageICML WriterOptions
    opts [Text]
    style Attr
    attr (Text, Text)
    target
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Note lst :: [Block]
    lst) = WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    footnoteToICML WriterOptions
    opts [Text]
    style [Block]
    lst
    inlineToICML opts :: WriterOptions
    opts style :: [Text]
    style (Span (_, _, kvs :: [(Text, Text)]
    kvs) lst :: [Inline]
    lst) =
      let dynamicStyle :: [Text]
    dynamicStyle = Maybe Text -> [Text]
    forall a. Maybe a -> [a]
    maybeToList (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 Text
    dynamicStyleKey [(Text, Text)]
    kvs
      in  WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts ([Text]
    dynamicStyle [Text] -> [Text] -> [Text]
    forall a. Semigroup a => a -> a -> a
    <> [Text]
    style) [Inline]
    lst

    -- | Convert a list of block elements to an ICML footnote.
    footnoteToICML :: PandocMonad m => WriterOptions -> Style -> [Block] -> WS m (Doc Text)
    footnoteToICML :: WriterOptions -> [Text] -> [Block] -> WS m (Doc Text)
    footnoteToICML opts :: WriterOptions
    opts style :: [Text]
    style lst :: [Block]
    lst =
      let insertTab :: Block -> WS m (Doc Text)
    insertTab (Para ls :: [Inline]
    ls) = WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    blockToICML WriterOptions
    opts (Text
    footnoteNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) (Block -> WS m (Doc Text)) -> Block -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Block
    Para ([Inline] -> Block) -> [Inline] -> Block
    forall a b. (a -> b) -> a -> b
    $ Text -> Inline
    Str "\t"Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    :[Inline]
    ls
          insertTab block :: Block
    block     = WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> Block -> WS m (Doc Text)
    blockToICML WriterOptions
    opts (Text
    footnoteNameText -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    style) Block
    block
      in  do
        [Doc Text]
    contents <- (Block -> WS m (Doc Text))
    -> [Block] -> StateT WriterState m [Doc Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM Block -> WS m (Doc Text)
    forall (m :: * -> *). PandocMonad m => Block -> WS m (Doc Text)
    insertTab [Block]
    lst
        let number :: Doc Text
    number = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "ParagraphStyleRange" [] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $
                       Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "CharacterStyleRange" [] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text -> Doc Text
    forall a. (HasChars a, IsString a) => Text -> Doc a -> Doc a
    inTagsSimple "Content" "<?ACE 4?>"
        Doc Text -> WS m (Doc Text)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> WS m (Doc Text)) -> Doc Text -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "CharacterStyleRange"
          [("AppliedCharacterStyle","$ID/NormalCharacterStyle"), ("Position","Superscript")]
          (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Footnote" [] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Doc Text
    number Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    $$ [Doc Text] -> Doc Text
    intersperseBrs [Doc Text]
    contents

    -- | Auxiliary function to merge Space elements into the adjacent Strs.
    mergeStrings :: WriterOptions -> [Inline] -> [Inline]
    mergeStrings :: WriterOptions -> [Inline] -> [Inline]
    mergeStrings opts :: WriterOptions
    opts = [Inline] -> [Inline]
    mergeStrings' ([Inline] -> [Inline])
    -> ([Inline] -> [Inline]) -> [Inline] -> [Inline]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Inline -> Inline) -> [Inline] -> [Inline]
    forall a b. (a -> b) -> [a] -> [b]
    map Inline -> Inline
    spaceToStr
      where spaceToStr :: Inline -> Inline
    spaceToStr Space = Text -> Inline
    Str " "
            spaceToStr SoftBreak = case WriterOptions -> WrapOption
    writerWrapText WriterOptions
    opts of
                                        WrapPreserve  -> Text -> Inline
    Str "\n"
                                        _             -> Text -> Inline
    Str " "
            spaceToStr x :: Inline
    x = Inline
    x

            mergeStrings' :: [Inline] -> [Inline]
    mergeStrings' (Str x :: Text
    x : Str y :: Text
    y : zs :: [Inline]
    zs) = [Inline] -> [Inline]
    mergeStrings' (Text -> Inline
    Str (Text
    x Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    y) Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    : [Inline]
    zs)
            mergeStrings' (x :: Inline
    x : xs :: [Inline]
    xs) = Inline
    x Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    : [Inline] -> [Inline]
    mergeStrings' [Inline]
    xs
            mergeStrings' []       = []

    -- | Intersperse line breaks
    intersperseBrs :: [Doc Text] -> Doc Text
    intersperseBrs :: [Doc Text] -> Doc Text
    intersperseBrs = [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat ([Doc Text] -> Doc Text)
    -> ([Doc Text] -> [Doc Text]) -> [Doc Text] -> Doc Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Doc Text -> [Doc Text] -> [Doc Text]
    forall a. a -> [a] -> [a]
    intersperse (Text -> [(Text, Text)] -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Text -> [(Text, Text)] -> Doc a
    selfClosingTag "Br" []) ([Doc Text] -> [Doc Text])
    -> ([Doc Text] -> [Doc Text]) -> [Doc Text] -> [Doc Text]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Doc Text -> Bool) -> [Doc Text] -> [Doc Text]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (Doc Text -> Bool) -> Doc Text -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Doc Text -> Bool
    forall a. Doc a -> Bool
    isEmpty)

    -- | Wrap a list of inline elements in an ICML Paragraph Style
    parStyle :: PandocMonad m => WriterOptions -> Style -> [Inline] -> WS m (Doc Text)
    parStyle :: WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    parStyle opts :: WriterOptions
    opts style :: [Text]
    style lst :: [Inline]
    lst =
      let slipIn :: Text -> Text -> Text
    slipIn x :: Text
    x y :: Text
    y = if Text -> Bool
    Text.null Text
    y
                          then Text
    x
                          else Text
    x Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> " > " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    y
          stlStr :: Text
    stlStr = (Text -> Text -> Text) -> Text -> [Text] -> Text
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Text -> Text -> Text
    slipIn "" ([Text] -> Text) -> [Text] -> Text
    forall a b. (a -> b) -> a -> b
    $ [Text] -> [Text]
    forall a. [a] -> [a]
    reverse [Text]
    style
          stl :: Text
    stl    = if Text -> Bool
    Text.null Text
    stlStr
                      then ""
                      else "ParagraphStyle/" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    stlStr
          attrs :: (Text, Text)
    attrs  = ("AppliedParagraphStyle", Text
    stl)
          attrs' :: [(Text, Text)]
    attrs' =  if Text
    firstListItemName Text -> [Text] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Text]
    style
                       then let ats :: [(Text, Text)]
    ats = (Text, Text)
    attrs (Text, Text) -> [(Text, Text)] -> [(Text, Text)]
    forall a. a -> [a] -> [a]
    : [("NumberingContinue", "false")]
                                begins :: [Text]
    begins = (Text -> Bool) -> [Text] -> [Text]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Text -> Text -> Bool
    Text.isPrefixOf Text
    beginsWithName) [Text]
    style
                            in  if [Text] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Text]
    begins
                                   then [(Text, Text)]
    ats
                                   else let i :: Text
    i = 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 -> Maybe Text
    Text.stripPrefix Text
    beginsWithName
                                                             (Text -> Maybe Text) -> Text -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    forall a. [a] -> a
    head [Text]
    begins
                                        in  ("NumberingStartAt", Text
    i) (Text, Text) -> [(Text, Text)] -> [(Text, Text)]
    forall a. a -> [a] -> [a]
    : [(Text, Text)]
    ats
                       else [(Text, Text)
    attrs]
      in  do
          Doc Text
    content <- WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Text] -> [Inline] -> WS m (Doc Text)
    inlinesToICML WriterOptions
    opts [] [Inline]
    lst
          let cont :: Doc Text
    cont = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "ParagraphStyleRange" [(Text, Text)]
    attrs' Doc Text
    content
          (WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text)
    forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
    state ((WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text))
    -> (WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ \st :: WriterState
    st -> (Doc Text
    cont, WriterState
    st{ blockStyles :: Set Text
    blockStyles = Text -> Set Text -> Set Text
    forall a. Ord a => a -> Set a -> Set a
    Set.insert Text
    stlStr (Set Text -> Set Text) -> Set Text -> Set Text
    forall a b. (a -> b) -> a -> b
    $ WriterState -> Set Text
    blockStyles WriterState
    st })

    -- | Wrap a Doc in an ICML Character Style.
    charStyle :: PandocMonad m => Style -> Doc Text -> WS m (Doc Text)
    charStyle :: [Text] -> Doc Text -> WS m (Doc Text)
    charStyle style :: [Text]
    style content :: Doc Text
    content =
      let (stlStr :: Text
    stlStr, attrs :: [(Text, Text)]
    attrs) = [Text] -> (Text, [(Text, Text)])
    styleToStrAttr [Text]
    style
          doc :: Doc Text
    doc = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "CharacterStyleRange" [(Text, Text)]
    attrs (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text -> Doc Text
    forall a. (HasChars a, IsString a) => Text -> Doc a -> Doc a
    inTagsSimple "Content" (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Doc Text -> Doc Text
    forall a. Doc a -> Doc a
    flush Doc Text
    content
      in
          (WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text)
    forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
    state ((WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text))
    -> (WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ \st :: WriterState
    st ->
        let styles :: WriterState
    styles = if Text -> Bool
    Text.null Text
    stlStr
                        then WriterState
    st
                        else WriterState
    st{ inlineStyles :: Set Text
    inlineStyles = Text -> Set Text -> Set Text
    forall a. Ord a => a -> Set a -> Set a
    Set.insert Text
    stlStr (Set Text -> Set Text) -> Set Text -> Set Text
    forall a b. (a -> b) -> a -> b
    $ WriterState -> Set Text
    inlineStyles WriterState
    st }
        in  (Doc Text
    doc, WriterState
    styles)

    -- | Transform a Style to a tuple of String (eliminating duplicates and ordered) and corresponding attribute.
    styleToStrAttr :: Style -> (Text, [(Text, Text)])
    styleToStrAttr :: [Text] -> (Text, [(Text, Text)])
    styleToStrAttr style :: [Text]
    style =
      let stlStr :: Text
    stlStr = [Text] -> Text
    Text.unwords ([Text] -> Text) -> [Text] -> Text
    forall a b. (a -> b) -> a -> b
    $ Set Text -> [Text]
    forall a. Set a -> [a]
    Set.toAscList (Set Text -> [Text]) -> Set Text -> [Text]
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Set Text
    forall a. Ord a => [a] -> Set a
    Set.fromList [Text]
    style
          stl :: Text
    stl    = if [Text] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Text]
    style
                      then "$ID/NormalCharacterStyle"
                      else "CharacterStyle/" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    stlStr
          attrs :: [(Text, Text)]
    attrs = [("AppliedCharacterStyle", Text
    stl)]
      in  (Text
    stlStr, [(Text, Text)]
    attrs)

    -- | Assemble an ICML Image.
    imageICML :: PandocMonad m => WriterOptions -> Style -> Attr -> Target -> WS m (Doc Text)
    imageICML :: WriterOptions -> [Text] -> Attr -> (Text, Text) -> WS m (Doc Text)
    imageICML opts :: WriterOptions
    opts style :: [Text]
    style attr :: Attr
    attr (src :: Text
    src, _) = do
      ImageSize
    imgS <- StateT WriterState m ImageSize
    -> (PandocError -> StateT WriterState m ImageSize)
    -> StateT WriterState m ImageSize
    forall e (m :: * -> *) a.
    MonadError e m =>
    m a -> (e -> m a) -> m a
    catchError
              (do (img :: ByteString
    img, _) <- Text -> StateT WriterState m (ByteString, Maybe Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text -> m (ByteString, Maybe Text)
    fetchItem Text
    src
                  case WriterOptions -> ByteString -> Either Text ImageSize
    imageSize WriterOptions
    opts ByteString
    img of
                    Right size :: ImageSize
    size -> ImageSize -> StateT WriterState m ImageSize
    forall (m :: * -> *) a. Monad m => a -> m a
    return ImageSize
    size
                    Left msg :: Text
    msg   -> do
                      LogMessage -> StateT WriterState m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> StateT WriterState m ())
    -> LogMessage -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> LogMessage
    CouldNotDetermineImageSize Text
    src Text
    msg
                      ImageSize -> StateT WriterState m ImageSize
    forall (m :: * -> *) a. Monad m => a -> m a
    return ImageSize
    forall a. Default a => a
    def)
               (\e :: PandocError
    e -> do
                   LogMessage -> StateT WriterState m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> StateT WriterState m ())
    -> LogMessage -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> LogMessage
    CouldNotFetchResource Text
    src (Text -> LogMessage) -> Text -> LogMessage
    forall a b. (a -> b) -> a -> b
    $ PandocError -> Text
    forall a. Show a => a -> Text
    tshow PandocError
    e
                   ImageSize -> StateT WriterState m ImageSize
    forall (m :: * -> *) a. Monad m => a -> m a
    return ImageSize
    forall a. Default a => a
    def)
      let (ow :: Double
    ow, oh :: Double
    oh) = ImageSize -> (Double, Double)
    sizeInPoints ImageSize
    imgS
          (imgWidth :: Double
    imgWidth, imgHeight :: Double
    imgHeight) = WriterOptions -> Attr -> ImageSize -> (Double, Double)
    desiredSizeInPoints WriterOptions
    opts Attr
    attr ImageSize
    imgS
          hw :: Text
    hw = Double -> Text
    forall a. RealFloat a => a -> Text
    showFl (Double -> Text) -> Double -> Text
    forall a b. (a -> b) -> a -> b
    $ Double
    ow Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / 2
          hh :: Text
    hh = Double -> Text
    forall a. RealFloat a => a -> Text
    showFl (Double -> Text) -> Double -> Text
    forall a b. (a -> b) -> a -> b
    $ Double
    oh Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / 2
          scale :: Text
    scale = Double -> Text
    forall a. RealFloat a => a -> Text
    showFl (Double
    imgWidth Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    ow) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> " 0 0 " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Double -> Text
    forall a. RealFloat a => a -> Text
    showFl (Double
    imgHeight Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    oh)
          src' :: Text
    src' = if Text -> Bool
    isURI Text
    src then Text
    src else "file:" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    src
          (stlStr :: Text
    stlStr, attrs :: [(Text, Text)]
    attrs) = [Text] -> (Text, [(Text, Text)])
    styleToStrAttr [Text]
    style
          props :: Doc Text
    props  = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Properties" [] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "PathGeometry" []
                     (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "GeometryPathType" [("PathOpen","false")]
                     (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "PathPointArray" []
                     (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat [
                         Text -> [(Text, Text)] -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Text -> [(Text, Text)] -> Doc a
    selfClosingTag "PathPointType" [("Anchor", "-"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" -"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh),
                           ("LeftDirection", "-"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" -"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh), ("RightDirection", "-"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" -"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh)]
                       , Text -> [(Text, Text)] -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Text -> [(Text, Text)] -> Doc a
    selfClosingTag "PathPointType" [("Anchor", "-"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" "Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh),
                           ("LeftDirection", "-"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" "Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh), ("RightDirection", "-"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" "Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh)]
                       , Text -> [(Text, Text)] -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Text -> [(Text, Text)] -> Doc a
    selfClosingTag "PathPointType" [("Anchor", Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" "Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh),
                           ("LeftDirection", Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" "Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh), ("RightDirection", Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" "Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh)]
                       , Text -> [(Text, Text)] -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Text -> [(Text, Text)] -> Doc a
    selfClosingTag "PathPointType" [("Anchor", Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" -"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh),
                           ("LeftDirection", Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" -"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh), ("RightDirection", Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" -"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh)]
                       ]
          image :: Doc Text
    image  = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Image"
                       [("Self","ue6"), ("ItemTransform", Text
    scaleText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" -"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" -"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh)]
                     (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat [
                         Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Properties" [] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Profile" [("type","string")] (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ String -> Doc Text
    forall a. HasChars a => String -> Doc a
    text "$ID/Embedded"
                       , Text -> [(Text, Text)] -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Text -> [(Text, Text)] -> Doc a
    selfClosingTag "Link" [("Self", "ueb"), ("LinkResourceURI", Text
    src')]
                       ]
          doc :: Doc Text
    doc    = Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "CharacterStyleRange" [(Text, Text)]
    attrs
                     (Doc Text -> Doc Text) -> Doc Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Bool -> Text -> [(Text, Text)] -> Doc Text -> Doc Text
    forall a.
    (HasChars a, IsString a) =>
    Bool -> Text -> [(Text, Text)] -> Doc a -> Doc a
    inTags Bool
    True "Rectangle" [("Self","uec"), ("StrokeWeight", "0"),
                         ("ItemTransform", Text
    scaleText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" "Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hwText -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>" -"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    hh)] (Doc Text
    props Doc Text -> Doc Text -> Doc Text
    forall a. Doc a -> Doc a -> Doc a
    $$ Doc Text
    image)
      (WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text)
    forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
    state ((WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text))
    -> (WriterState -> (Doc Text, WriterState)) -> WS m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ \st :: WriterState
    st -> (Doc Text
    doc, WriterState
    st{ inlineStyles :: Set Text
    inlineStyles = Text -> Set Text -> Set Text
    forall a. Ord a => a -> Set a -> Set a
    Set.insert Text
    stlStr (Set Text -> Set Text) -> Set Text -> Set Text
    forall a b. (a -> b) -> a -> b
    $ WriterState -> Set Text
    inlineStyles WriterState
    st } )