    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE ViewPatterns      #-}
    {- |
       Module      : Text.Pandoc.Writers.ZimWiki
       Copyright   : © 2008-2020 John MacFarlane,
                       2017-2019 Alex Ivkin
       License     : GNU GPL, version 2 or above

       Maintainer  : Alex Ivkin <alex@ivkin.net>
       Stability   : beta
       Portability : portable

    Conversion of 'Pandoc' documents to ZimWiki markup.

    http://zim-wiki.org/manual/Help/Wiki_Syntax.html
    -}

    module Text.Pandoc.Writers.ZimWiki ( writeZimWiki ) where
    import Control.Monad (zipWithM)
    import Control.Monad.State.Strict (StateT, evalStateT, gets, modify)
    import Data.Default (Default (..))
    import Data.List (transpose)
    import qualified Data.Map as Map
    import Text.DocLayout (render, literal)
    import Data.Maybe (fromMaybe)
    import Data.Text (Text)
    import qualified Data.Text as T
    import Text.Pandoc.Class.PandocMonad (PandocMonad, report)
    import Text.Pandoc.Definition
    import Text.Pandoc.ImageSize
    import Text.Pandoc.Logging
    import Text.Pandoc.Options (WrapOption (..),
               WriterOptions (writerTableOfContents, writerTemplate,
                              writerWrapText))
    import Text.Pandoc.Shared (escapeURI, isURI, linesToPara, removeFormatting, trimr)
    import Text.Pandoc.Templates (renderTemplate)
    import Text.Pandoc.Writers.Shared (defField, metaToContext)

    data WriterState = WriterState {
        WriterState -> Text
    stIndent  :: Text,           -- Indent after the marker at the beginning of list items
        WriterState -> Bool
    stInTable :: Bool,           -- Inside a table
        WriterState -> Bool
    stInLink  :: Bool            -- Inside a link description
      }

    instance Default WriterState where
      def :: WriterState
    def = WriterState :: Text -> Bool -> Bool -> WriterState
    WriterState { stIndent :: Text
    stIndent = "", stInTable :: Bool
    stInTable = Bool
    False, stInLink :: Bool
    stInLink = Bool
    False }

    type ZW = StateT WriterState

    -- | Convert Pandoc to ZimWiki.
    writeZimWiki :: PandocMonad m => WriterOptions -> Pandoc -> m Text
    writeZimWiki :: WriterOptions -> Pandoc -> m Text
    writeZimWiki opts :: WriterOptions
    opts document :: Pandoc
    document = StateT WriterState m Text -> WriterState -> m Text
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT (WriterOptions -> Pandoc -> StateT WriterState m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> ZW m Text
    pandocToZimWiki WriterOptions
    opts Pandoc
    document) WriterState
    forall a. Default a => a
    def

    -- | Return ZimWiki representation of document.
    pandocToZimWiki :: PandocMonad m => WriterOptions -> Pandoc -> ZW m Text
    pandocToZimWiki :: WriterOptions -> Pandoc -> ZW m Text
    pandocToZimWiki opts :: WriterOptions
    opts (Pandoc meta :: Meta
    meta blocks :: [Block]
    blocks) = do
      Context Text
    metadata <- WriterOptions
    -> ([Block] -> StateT WriterState m (Doc Text))
    -> ([Inline] -> StateT WriterState m (Doc Text))
    -> Meta
    -> StateT WriterState 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
                  ((Text -> Doc Text) -> ZW m Text -> StateT WriterState m (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text -> Doc Text) -> (Text -> Text) -> Text -> Doc Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Text
    trimr) (ZW m Text -> StateT WriterState m (Doc Text))
    -> ([Block] -> ZW m Text)
    -> [Block]
    -> StateT WriterState m (Doc Text)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WriterOptions -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> ZW m Text
    blockListToZimWiki WriterOptions
    opts)
                  ((Text -> Doc Text) -> ZW m Text -> StateT WriterState m (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text -> Doc Text) -> (Text -> Text) -> Text -> Doc Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Text
    trimr) (ZW m Text -> StateT WriterState m (Doc Text))
    -> ([Inline] -> ZW m Text)
    -> [Inline]
    -> StateT WriterState m (Doc Text)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts)
                  Meta
    meta
      Text
    main <- WriterOptions -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> ZW m Text
    blockListToZimWiki WriterOptions
    opts [Block]
    blocks
      --let header = "Content-Type: text/x-zim-wiki\nWiki-Format: zim 0.4\n"
      let context :: Context Text
    context = Text -> Text -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField "body" Text
    main
                    (Context Text -> Context Text) -> Context Text -> Context Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Bool -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField "toc" (WriterOptions -> Bool
    writerTableOfContents WriterOptions
    opts) Context Text
    metadata
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $
        case WriterOptions -> Maybe (Template Text)
    writerTemplate WriterOptions
    opts of
           Just tpl :: Template Text
    tpl -> Maybe Int -> Doc Text -> Text
    forall a. HasChars a => Maybe Int -> Doc a -> a
    render Maybe Int
    forall a. Maybe a
    Nothing (Doc Text -> Text) -> Doc Text -> Text
    forall a b. (a -> b) -> a -> b
    $ 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
           Nothing  -> Text
    main

    -- | Escape special characters for ZimWiki.
    escapeText :: Text -> Text
    escapeText :: Text -> Text
    escapeText = Text -> Text -> Text -> Text
    T.replace "__" "''__''" (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                   Text -> Text -> Text -> Text
    T.replace "**" "''**''" (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                   Text -> Text -> Text -> Text
    T.replace "~~" "''~~''" (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
                   Text -> Text -> Text -> Text
    T.replace "//" "''//''"

    -- | Convert Pandoc block element to ZimWiki.
    blockToZimWiki :: PandocMonad m => WriterOptions -> Block -> ZW m Text

    blockToZimWiki :: WriterOptions -> Block -> ZW m Text
    blockToZimWiki _ Null = Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""

    blockToZimWiki opts :: WriterOptions
    opts (Div _attrs :: Attr
    _attrs bs :: [Block]
    bs) = do
      Text
    contents <- WriterOptions -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> ZW m Text
    blockListToZimWiki WriterOptions
    opts [Block]
    bs
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n"

    blockToZimWiki opts :: WriterOptions
    opts (Plain inlines :: [Inline]
    inlines) = WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    inlines

    -- title beginning with fig: indicates that the image is a figure
    -- ZimWiki doesn't support captions - so combine together alt and caption into alt
    blockToZimWiki opts :: WriterOptions
    opts (Para [Image attr :: Attr
    attr txt :: [Inline]
    txt (src :: Text
    src,Text -> Text -> Maybe Text
    T.stripPrefix "fig:" -> Just tit :: Text
    tit)]) = do
      Text
    capt <- if [Inline] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Inline]
    txt
                 then Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""
                 else (" " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>) (Text -> Text) -> ZW m Text -> ZW m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    txt
      let opt :: Text
    opt = if [Inline] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Inline]
    txt
                   then ""
                   else "|" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> if Text -> Bool
    T.null Text
    tit then Text
    capt else Text
    tit Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    capt
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "{{" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    src Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> WriterOptions -> Attr -> Text
    imageDims WriterOptions
    opts Attr
    attr Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    opt Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "}}\n"

    blockToZimWiki opts :: WriterOptions
    opts (Para inlines :: [Inline]
    inlines) = do
      Text
    indent <- (WriterState -> Text) -> ZW m Text
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Text
    stIndent
      -- useTags <- gets stUseTags
      Text
    contents <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    inlines
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> if Text -> Bool
    T.null Text
    indent then "\n" else ""

    blockToZimWiki opts :: WriterOptions
    opts (LineBlock lns :: [[Inline]]
    lns) =
      WriterOptions -> Block -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Block -> ZW m Text
    blockToZimWiki WriterOptions
    opts (Block -> ZW m Text) -> Block -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ [[Inline]] -> Block
    linesToPara [[Inline]]
    lns

    blockToZimWiki opts :: WriterOptions
    opts 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 "zimwiki"  = Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    str
      | Format
    f Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format "html"     = WriterOptions -> Text -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Text -> ZW m Text
    indentFromHTML WriterOptions
    opts 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
          Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""

    blockToZimWiki _ HorizontalRule = Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return "\n----\n"

    blockToZimWiki opts :: WriterOptions
    opts (Header level :: Int
    level _ inlines :: [Inline]
    inlines) = do
      Text
    contents <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts ([Inline] -> ZW m Text) -> [Inline] -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> [Inline]
    forall a. Walkable Inline a => a -> [Inline]
    removeFormatting [Inline]
    inlines   -- emphasis, links etc. not allowed in headers
      let eqs :: Text
    eqs = Int -> Text -> Text
    T.replicate ( 7 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    level ) "="
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    eqs Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    eqs Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n"

    blockToZimWiki _ (CodeBlock (_,classes :: [Text]
    classes,_) str :: Text
    str) = do
      -- Remap languages into the gtksourceview2 convention that ZimWiki source code plugin is using
      let langal :: [(Text, Text)]
    langal = [("javascript", "js"), ("bash", "sh"), ("winbatch", "dosbatch")]
      let langmap :: Map Text Text
    langmap = [(Text, Text)] -> Map Text Text
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList [(Text, Text)]
    langal
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ case [Text]
    classes of
                    []      -> "'''\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Text
    cleanupCode Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n'''\n"   -- turn no lang block into a quote block
                    (x :: Text
    x:_)   -> "{{{code: lang=\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                            Text -> Maybe Text -> Text
    forall a. a -> Maybe a -> a
    fromMaybe Text
    x (Text -> Map Text Text -> Maybe Text
    forall k a. Ord k => k -> Map k a -> Maybe a
    Map.lookup Text
    x Map Text Text
    langmap) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\" linenumbers=\"True\"\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n}}}\n"  -- for zim's code plugin, go verbatim on the lang spec

    blockToZimWiki opts :: WriterOptions
    opts (BlockQuote blocks :: [Block]
    blocks) = do
      Text
    contents <- WriterOptions -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> ZW m Text
    blockListToZimWiki WriterOptions
    opts [Block]
    blocks
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    T.unlines ([Text] -> Text) -> [Text] -> Text
    forall a b. (a -> b) -> a -> b
    $ (Text -> Text) -> [Text] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map ("> " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>) ([Text] -> [Text]) -> [Text] -> [Text]
    forall a b. (a -> b) -> a -> b
    $ Text -> [Text]
    T.lines Text
    contents

    blockToZimWiki opts :: WriterOptions
    opts (Table capt :: [Inline]
    capt aligns :: [Alignment]
    aligns _ headers :: [[Block]]
    headers rows :: [[[Block]]]
    rows) = do
      Text
    captionDoc <- if [Inline] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Inline]
    capt
                       then Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""
                       else do
                          Text
    c <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    capt
                          Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    c Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n"
      [Text]
    headers' <- if ([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
                     then (Alignment -> [Block] -> ZW m Text)
    -> [Alignment] -> [[Block]] -> StateT WriterState m [Text]
    forall (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> m c) -> [a] -> [b] -> m [c]
    zipWithM (WriterOptions -> Alignment -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Alignment -> [Block] -> ZW m Text
    tableItemToZimWiki WriterOptions
    opts) [Alignment]
    aligns ([[[Block]]] -> [[Block]]
    forall a. [a] -> a
    head [[[Block]]]
    rows)
                     else ([Block] -> ZW m Text) -> [[Block]] -> StateT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts ([Inline] -> ZW m Text)
    -> ([Block] -> [Inline]) -> [Block] -> ZW m Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Block] -> [Inline]
    forall a. Walkable Inline a => a -> [Inline]
    removeFormatting)[[Block]]
    headers  -- emphasis, links etc. are not allowed in table headers
      [[Text]]
    rows' <- ([[Block]] -> StateT WriterState m [Text])
    -> [[[Block]]] -> StateT WriterState m [[Text]]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM ((Alignment -> [Block] -> ZW m Text)
    -> [Alignment] -> [[Block]] -> StateT WriterState m [Text]
    forall (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> m c) -> [a] -> [b] -> m [c]
    zipWithM (WriterOptions -> Alignment -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Alignment -> [Block] -> ZW m Text
    tableItemToZimWiki WriterOptions
    opts) [Alignment]
    aligns) [[[Block]]]
    rows
      let widths :: [Int]
    widths = ([Text] -> Int) -> [[Text]] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map ([Int] -> Int
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum ([Int] -> Int) -> ([Text] -> [Int]) -> [Text] -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Text -> Int) -> [Text] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map Text -> Int
    T.length) ([[Text]] -> [Int]) -> [[Text]] -> [Int]
    forall a b. (a -> b) -> a -> b
    $ [[Text]] -> [[Text]]
    forall a. [[a]] -> [[a]]
    transpose ([Text]
    headers'[Text] -> [[Text]] -> [[Text]]
    forall a. a -> [a] -> [a]
    :[[Text]]
    rows')
      let padTo :: (Int, Alignment) -> Text -> Text
    padTo (width :: Int
    width, al :: Alignment
    al) s :: Text
    s =
              case Int
    width Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Text -> Int
    T.length Text
    s of
                   x :: Int
    x | Int
    x Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 0 ->
                     if Alignment
    al Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignLeft Bool -> Bool -> Bool
    || Alignment
    al Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignDefault
                        then Text
    s Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text -> Text
    T.replicate Int
    x " "
                        else if Alignment
    al Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignRight
                                then Int -> Text -> Text
    T.replicate Int
    x " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    s
                                else Int -> Text -> Text
    T.replicate (Int
    x Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `div` 2) " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                                     Text
    s Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text -> Text
    T.replicate (Int
    x Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    x Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `div` 2) " "
                     | Bool
    otherwise -> Text
    s
      let borderCell :: (Int, Alignment) -> p -> Text
    borderCell (width :: Int
    width, al :: Alignment
    al) _
            | Alignment
    al Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignLeft = ":"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text -> Text
    T.replicate (Int
    widthInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -1) "-"
            | Alignment
    al Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignDefault = Int -> Text -> Text
    T.replicate Int
    width "-"
            | Alignment
    al Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignRight = Int -> Text -> Text
    T.replicate (Int
    widthInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -1) "-" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> ":"
            | Bool
    otherwise = ":" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text -> Text
    T.replicate (Int
    widthInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -2) "-" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> ":"
      let underheader :: Text
    underheader  = "|" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> [Text] -> Text
    T.intercalate "|" (((Int, Alignment) -> Text -> Text)
    -> [(Int, Alignment)] -> [Text] -> [Text]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (Int, Alignment) -> Text -> Text
    forall p. (Int, Alignment) -> p -> Text
    borderCell ([Int] -> [Alignment] -> [(Int, Alignment)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Int]
    widths [Alignment]
    aligns) [Text]
    headers') Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "|"
      let renderRow :: [Text] -> Text
    renderRow cells :: [Text]
    cells = "|" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> [Text] -> Text
    T.intercalate "|" (((Int, Alignment) -> Text -> Text)
    -> [(Int, Alignment)] -> [Text] -> [Text]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (Int, Alignment) -> Text -> Text
    padTo ([Int] -> [Alignment] -> [(Int, Alignment)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Int]
    widths [Alignment]
    aligns) [Text]
    cells) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "|"
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    captionDoc Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
               (if [Text] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Text]
    headers' then "" else [Text] -> Text
    renderRow [Text]
    headers' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n") Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    underheader Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
               [Text] -> Text
    T.unlines (([Text] -> Text) -> [[Text]] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map [Text] -> Text
    renderRow [[Text]]
    rows')

    blockToZimWiki opts :: WriterOptions
    opts (BulletList items :: [[Block]]
    items) = do
      [Text]
    contents <- ([Block] -> ZW m Text) -> [[Block]] -> StateT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> ZW m Text
    listItemToZimWiki WriterOptions
    opts) [[Block]]
    items
      Text
    indent <- (WriterState -> Text) -> ZW m Text
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Text
    stIndent
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    vcat [Text]
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> if Text -> Bool
    T.null Text
    indent then "\n" else ""

    blockToZimWiki opts :: WriterOptions
    opts (OrderedList _ items :: [[Block]]
    items) = do
      [Text]
    contents <- (Int -> [Block] -> ZW m Text)
    -> [Int] -> [[Block]] -> StateT WriterState m [Text]
    forall (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> m c) -> [a] -> [b] -> m [c]
    zipWithM (WriterOptions -> Int -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Int -> [Block] -> ZW m Text
    orderedListItemToZimWiki WriterOptions
    opts) [1..] [[Block]]
    items
      Text
    indent <- (WriterState -> Text) -> ZW m Text
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Text
    stIndent
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    vcat [Text]
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> if Text -> Bool
    T.null Text
    indent then "\n" else ""

    blockToZimWiki opts :: WriterOptions
    opts (DefinitionList items :: [([Inline], [[Block]])]
    items) = do
      [Text]
    contents <- (([Inline], [[Block]]) -> ZW m Text)
    -> [([Inline], [[Block]])] -> StateT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> ([Inline], [[Block]]) -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> ([Inline], [[Block]]) -> ZW m Text
    definitionListItemToZimWiki WriterOptions
    opts) [([Inline], [[Block]])]
    items
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    vcat [Text]
    contents

    definitionListItemToZimWiki :: PandocMonad m
                                => WriterOptions
                                -> ([Inline],[[Block]])
                                -> ZW m Text
    definitionListItemToZimWiki :: WriterOptions -> ([Inline], [[Block]]) -> ZW m Text
    definitionListItemToZimWiki opts :: WriterOptions
    opts (label :: [Inline]
    label, items :: [[Block]]
    items) = do
      Text
    labelText <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    label
      [Text]
    contents <- ([Block] -> ZW m Text) -> [[Block]] -> StateT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> ZW m Text
    blockListToZimWiki WriterOptions
    opts) [[Block]]
    items
      Text
    indent <- (WriterState -> Text) -> ZW m Text
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Text
    stIndent
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    indent Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "* **" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    labelText Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "** " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> [Text] -> Text
    T.concat [Text]
    contents

    -- Auxiliary functions for lists:
    indentFromHTML :: PandocMonad m => WriterOptions -> Text -> ZW m Text
    indentFromHTML :: WriterOptions -> Text -> ZW m Text
    indentFromHTML _ str :: Text
    str = do
       Text
    indent <- (WriterState -> Text) -> ZW m Text
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Text
    stIndent
       if "<li>" Text -> Text -> Bool
    `T.isInfixOf` Text
    str
          then Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    indent
          else if "</li>" Text -> Text -> Bool
    `T.isInfixOf` Text
    str
            then Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return "\n"
            else if "<li value=" Text -> Text -> Bool
    `T.isInfixOf` Text
    str
              then Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""
              else if "<ol>" Text -> Text -> Bool
    `T.isInfixOf` Text
    str
                then do
                  let olcount :: Int
    olcount=Text -> Text -> Int
    countSubStrs "<ol>" Text
    str
                  (WriterState -> WriterState) -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((WriterState -> WriterState) -> StateT WriterState m ())
    -> (WriterState -> WriterState) -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ \s :: WriterState
    s -> WriterState
    s { stIndent :: Text
    stIndent = WriterState -> Text
    stIndent WriterState
    s Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                                     Int -> Text -> Text
    T.replicate Int
    olcount "\t" }
                  Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""
                else if "</ol>" Text -> Text -> Bool
    `T.isInfixOf` Text
    str
                  then do
                    let olcount :: Int
    olcount=Text -> Text -> Int
    countSubStrs "/<ol>" Text
    str
                    (WriterState -> WriterState) -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((WriterState -> WriterState) -> StateT WriterState m ())
    -> (WriterState -> WriterState) -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ \s :: WriterState
    s -> WriterState
    s{ stIndent :: Text
    stIndent = Int -> Text -> Text
    T.drop Int
    olcount (WriterState -> Text
    stIndent WriterState
    s) }
                    Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""
                  else Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""

    countSubStrs :: Text -> Text -> Int
    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)]
    T.breakOnAll Text
    sub Text
    str

    cleanupCode :: Text -> Text
    cleanupCode :: Text -> Text
    cleanupCode = Text -> Text -> Text -> Text
    T.replace "<nowiki>" "" (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Text -> Text -> Text
    T.replace "</nowiki>" ""

    vcat :: [Text] -> Text
    vcat :: [Text] -> Text
    vcat = Text -> [Text] -> Text
    T.intercalate "\n"

    -- | Convert bullet list item (list of blocks) to ZimWiki.
    listItemToZimWiki :: PandocMonad m => WriterOptions -> [Block] -> ZW m Text
    listItemToZimWiki :: WriterOptions -> [Block] -> ZW m Text
    listItemToZimWiki opts :: WriterOptions
    opts items :: [Block]
    items = do
      Text
    indent <- (WriterState -> Text) -> ZW m Text
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Text
    stIndent
      (WriterState -> WriterState) -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((WriterState -> WriterState) -> StateT WriterState m ())
    -> (WriterState -> WriterState) -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ \s :: WriterState
    s -> WriterState
    s { stIndent :: Text
    stIndent = Text
    indent Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\t" }
      Text
    contents <- WriterOptions -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> ZW m Text
    blockListToZimWiki WriterOptions
    opts [Block]
    items
      (WriterState -> WriterState) -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((WriterState -> WriterState) -> StateT WriterState m ())
    -> (WriterState -> WriterState) -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ \s :: WriterState
    s -> WriterState
    s{ stIndent :: Text
    stIndent = Text
    indent }
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    indent Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "* " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents

    -- | Convert ordered list item (list of blocks) to ZimWiki.
    orderedListItemToZimWiki :: PandocMonad m
                             => WriterOptions -> Int -> [Block] -> ZW m Text
    orderedListItemToZimWiki :: WriterOptions -> Int -> [Block] -> ZW m Text
    orderedListItemToZimWiki opts :: WriterOptions
    opts itemnum :: Int
    itemnum items :: [Block]
    items = do
      Text
    indent <- (WriterState -> Text) -> ZW m Text
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Text
    stIndent
      (WriterState -> WriterState) -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((WriterState -> WriterState) -> StateT WriterState m ())
    -> (WriterState -> WriterState) -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ \s :: WriterState
    s -> WriterState
    s { stIndent :: Text
    stIndent = Text
    indent Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\t" }
      Text
    contents <- WriterOptions -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> ZW m Text
    blockListToZimWiki WriterOptions
    opts [Block]
    items
      (WriterState -> WriterState) -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((WriterState -> WriterState) -> StateT WriterState m ())
    -> (WriterState -> WriterState) -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ \s :: WriterState
    s -> WriterState
    s{ stIndent :: Text
    stIndent = Text
    indent }
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    indent Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> String -> Text
    T.pack (Int -> String
    forall a. Show a => a -> String
    show Int
    itemnum) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> ". " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents

    -- Auxiliary functions for tables:
    tableItemToZimWiki :: PandocMonad m
                       => WriterOptions -> Alignment -> [Block] -> ZW m Text
    tableItemToZimWiki :: WriterOptions -> Alignment -> [Block] -> ZW m Text
    tableItemToZimWiki opts :: WriterOptions
    opts align' :: Alignment
    align' item :: [Block]
    item = do
      let mkcell :: a -> a
    mkcell x :: a
    x = (if Alignment
    align' Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignRight Bool -> Bool -> Bool
    || Alignment
    align' Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignCenter
                         then "  "
                         else "") a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    x a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <>
                     (if Alignment
    align' Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignLeft Bool -> Bool -> Bool
    || Alignment
    align' Alignment -> Alignment -> Bool
    forall a. Eq a => a -> a -> Bool
    == Alignment
    AlignCenter
                         then "  "
                         else "")
      (WriterState -> WriterState) -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((WriterState -> WriterState) -> StateT WriterState m ())
    -> (WriterState -> WriterState) -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ \s :: WriterState
    s -> WriterState
    s { stInTable :: Bool
    stInTable = Bool
    True }
      Text
    contents <- WriterOptions -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> ZW m Text
    blockListToZimWiki WriterOptions
    opts [Block]
    item
      (WriterState -> WriterState) -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((WriterState -> WriterState) -> StateT WriterState m ())
    -> (WriterState -> WriterState) -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ \s :: WriterState
    s -> WriterState
    s { stInTable :: Bool
    stInTable = Bool
    False }
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    forall a. (Semigroup a, IsString a) => a -> a
    mkcell Text
    contents

    -- | Convert list of Pandoc block elements to ZimWiki.
    blockListToZimWiki :: PandocMonad m
                       => WriterOptions -> [Block] -> ZW m Text
    blockListToZimWiki :: WriterOptions -> [Block] -> ZW m Text
    blockListToZimWiki opts :: WriterOptions
    opts blocks :: [Block]
    blocks = [Text] -> Text
    vcat ([Text] -> Text) -> StateT WriterState m [Text] -> ZW m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Block -> ZW m Text) -> [Block] -> StateT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> Block -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Block -> ZW m Text
    blockToZimWiki WriterOptions
    opts) [Block]
    blocks

    -- | Convert list of Pandoc inline elements to ZimWiki.
    inlineListToZimWiki :: PandocMonad m
                        => WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki :: WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki opts :: WriterOptions
    opts lst :: [Inline]
    lst = [Text] -> Text
    T.concat ([Text] -> Text) -> StateT WriterState m [Text] -> ZW m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Inline -> ZW m Text) -> [Inline] -> StateT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> Inline -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Inline -> ZW m Text
    inlineToZimWiki WriterOptions
    opts) [Inline]
    lst

    -- | Convert Pandoc inline element to ZimWiki.
    inlineToZimWiki :: PandocMonad m
                    => WriterOptions -> Inline -> ZW m Text

    inlineToZimWiki :: WriterOptions -> Inline -> ZW m Text
    inlineToZimWiki opts :: WriterOptions
    opts (Emph lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    lst
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "//" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "//"

    inlineToZimWiki opts :: WriterOptions
    opts (Strong lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    lst
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "**" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "**"

    inlineToZimWiki opts :: WriterOptions
    opts (Strikeout lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    lst
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "~~" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "~~"

    inlineToZimWiki opts :: WriterOptions
    opts (Superscript lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    lst
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "^{" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "}"

    inlineToZimWiki opts :: WriterOptions
    opts (Subscript lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    lst
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "_{" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "}"

    inlineToZimWiki opts :: WriterOptions
    opts (Quoted SingleQuote lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    lst
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "\8216" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\8217"

    inlineToZimWiki opts :: WriterOptions
    opts (Quoted DoubleQuote lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    lst
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "\8220" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\8221"

    inlineToZimWiki opts :: WriterOptions
    opts (Span _attrs :: Attr
    _attrs ils :: [Inline]
    ils) = WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    ils

    inlineToZimWiki opts :: WriterOptions
    opts (SmallCaps lst :: [Inline]
    lst) = WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    lst

    inlineToZimWiki opts :: WriterOptions
    opts (Cite _  lst :: [Inline]
    lst) = WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    lst

    inlineToZimWiki _ (Code _ str :: Text
    str) = Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "''" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "''"

    inlineToZimWiki _ (Str str :: Text
    str) = do
      Bool
    inTable <- (WriterState -> Bool) -> StateT WriterState m Bool
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Bool
    stInTable
      Bool
    inLink  <- (WriterState -> Bool) -> StateT WriterState m Bool
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Bool
    stInLink
      if Bool
    inTable
          then Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> Text -> Text
    T.replace "|" "\\|" (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Text
    escapeText (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text
    str
          else
              if Bool
    inLink
              then Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    str
              else Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    escapeText Text
    str

    inlineToZimWiki _ (Math mathType :: MathType
    mathType str :: Text
    str) = Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    delim Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    delim   -- note:  str should NOT be escaped
      where delim :: Text
    delim = case MathType
    mathType of
                         DisplayMath -> "$$"
                         InlineMath  -> "$"

    -- | f == Format "html"     = return $ "<html>" <> str <> "</html>"
    inlineToZimWiki opts :: WriterOptions
    opts 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 "zimwiki" = Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    str
      | Format
    f Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format "html"    = WriterOptions -> Text -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Text -> ZW m Text
    indentFromHTML WriterOptions
    opts 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
          Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""

    inlineToZimWiki _ LineBreak = do
      Bool
    inTable <- (WriterState -> Bool) -> StateT WriterState m Bool
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Bool
    stInTable
      if Bool
    inTable
          then Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return "\\n"
          else Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return "\n"

    inlineToZimWiki opts :: WriterOptions
    opts SoftBreak =
      case WriterOptions -> WrapOption
    writerWrapText WriterOptions
    opts of
           WrapNone     -> Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return " "
           WrapAuto     -> Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return " "
           WrapPreserve -> Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return "\n"

    inlineToZimWiki _ Space = Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return " "

    inlineToZimWiki opts :: WriterOptions
    opts (Link _ txt :: [Inline]
    txt (src :: Text
    src, _)) = do
      Bool
    inTable <- (WriterState -> Bool) -> StateT WriterState m Bool
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Bool
    stInTable
      (WriterState -> WriterState) -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((WriterState -> WriterState) -> StateT WriterState m ())
    -> (WriterState -> WriterState) -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ \s :: WriterState
    s -> WriterState
    s { stInLink :: Bool
    stInLink = Bool
    True }
      Text
    label <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts ([Inline] -> ZW m Text) -> [Inline] -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> [Inline]
    forall a. Walkable Inline a => a -> [Inline]
    removeFormatting [Inline]
    txt -- zim does not allow formatting in link text, it takes the text verbatim, no need to escape it
      (WriterState -> WriterState) -> StateT WriterState m ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((WriterState -> WriterState) -> StateT WriterState m ())
    -> (WriterState -> WriterState) -> StateT WriterState m ()
    forall a b. (a -> b) -> a -> b
    $ \s :: WriterState
    s -> WriterState
    s { stInLink :: Bool
    stInLink = Bool
    False }
      let label' :: Text
    label'= if Bool
    inTable
                then "" -- no label is allowed in a table
                else "|"Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>Text
    label
      case [Inline]
    txt of
         [Str s :: Text
    s] | "mailto:" Text -> Text -> Bool
    `T.isPrefixOf` Text
    src -> Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "<" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    s Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> ">"
                 | Text -> Text
    escapeURI Text
    s Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    src -> Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    src
         _  -> if Text -> Bool
    isURI Text
    src
                  then Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "[[" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    src  Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    label' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "]]"
                  else Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "[[" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    src' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    label' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "]]"
      where
        -- with leading / it's a link to a help page
        src' :: Text
    src' = Text -> Maybe Text -> Text
    forall a. a -> Maybe a -> a
    fromMaybe Text
    src (Maybe Text -> Text) -> Maybe Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> Maybe Text
    T.stripPrefix "/" Text
    src

    inlineToZimWiki opts :: WriterOptions
    opts (Image attr :: Attr
    attr alt :: [Inline]
    alt (source :: Text
    source, tit :: Text
    tit)) = do
      Text
    alt' <- WriterOptions -> [Inline] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> ZW m Text
    inlineListToZimWiki WriterOptions
    opts [Inline]
    alt
      Bool
    inTable <- (WriterState -> Bool) -> StateT WriterState m Bool
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Bool
    stInTable
      let txt :: Text
    txt = case (Text
    tit, [Inline]
    alt, Bool
    inTable) of
                  ("",[], _)      -> ""
                  ("", _, False ) -> "|" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    alt'
                  (_ , _, False ) -> "|" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    tit
                  (_ , _, True )  -> ""
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ "{{" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    source Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> WriterOptions -> Attr -> Text
    imageDims WriterOptions
    opts Attr
    attr Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    txt Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "}}"

    inlineToZimWiki opts :: WriterOptions
    opts (Note contents :: [Block]
    contents) = do
      -- no concept of notes in zim wiki, use a text block
      Text
    contents' <- WriterOptions -> [Block] -> ZW m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> ZW m Text
    blockListToZimWiki WriterOptions
    opts [Block]
    contents
      Text -> ZW m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> ZW m Text) -> Text -> ZW m Text
    forall a b. (a -> b) -> a -> b
    $ " **{Note:** " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Text
    trimr Text
    contents' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "**}**"

    imageDims :: WriterOptions -> Attr -> Text
    imageDims :: WriterOptions -> Attr -> Text
    imageDims opts :: WriterOptions
    opts attr :: Attr
    attr = Maybe Text -> Maybe Text -> Text
    forall a. (Semigroup a, IsString a) => Maybe a -> Maybe a -> a
    go (Maybe Dimension -> Maybe Text
    toPx (Maybe Dimension -> Maybe Text) -> Maybe Dimension -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Direction -> Attr -> Maybe Dimension
    dimension Direction
    Width Attr
    attr) (Maybe Dimension -> Maybe Text
    toPx (Maybe Dimension -> Maybe Text) -> Maybe Dimension -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Direction -> Attr -> Maybe Dimension
    dimension Direction
    Height Attr
    attr)
      where
        toPx :: Maybe Dimension -> Maybe Text
    toPx = (Dimension -> Text) -> Maybe Dimension -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (WriterOptions -> Dimension -> Text
    showInPixel WriterOptions
    opts) (Maybe Dimension -> Maybe Text)
    -> (Maybe Dimension -> Maybe Dimension)
    -> Maybe Dimension
    -> Maybe Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Maybe Dimension -> Maybe Dimension
    checkPct
        checkPct :: Maybe Dimension -> Maybe Dimension
    checkPct (Just (Percent _)) = Maybe Dimension
    forall a. Maybe a
    Nothing
        checkPct maybeDim :: Maybe Dimension
    maybeDim           = Maybe Dimension
    maybeDim
        go :: Maybe a -> Maybe a -> a
    go (Just w :: a
    w) Nothing  = "?" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    w
        go (Just w :: a
    w) (Just h :: a
    h) = "?" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    w a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> "x" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    h
        go Nothing  (Just h :: a
    h) = "?0x" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    h
        go Nothing  Nothing  = ""