    {-# LANGUAGE OverloadedStrings #-}
    {- |
       Module      : Text.Pandoc.Writers.DokuWiki
       Copyright   : Copyright (C) 2008-2020 John MacFarlane
       License     : GNU GPL, version 2 or above

       Maintainer  : Clare Macrae <clare.macrae@googlemail.com>
       Stability   : alpha
       Portability : portable

    Conversion of 'Pandoc' documents to DokuWiki markup.

    DokuWiki:  <https://www.dokuwiki.org/dokuwiki>
    -}

    {-
        [ ] Implement nested blockquotes (currently only ever does one level)
        [x] Implement alignment of text in tables
        [ ] Implement comments
        [ ] Work through the Dokuwiki spec, and check I've not missed anything out
        [ ] Remove dud/duplicate code
    -}

    module Text.Pandoc.Writers.DokuWiki ( writeDokuWiki ) where
    import Control.Monad (zipWithM)
    import Control.Monad.Reader (ReaderT, asks, local, runReaderT)
    import Control.Monad.State.Strict (StateT, evalStateT)
    import Data.Default (Default (..))
    import Data.List (intersect, transpose)
    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 (camelCaseToHyphenated, escapeURI, isURI, linesToPara,
                               removeFormatting, trimr, tshow)
    import Text.Pandoc.Templates (renderTemplate)
    import Text.DocLayout (render, literal)
    import Text.Pandoc.Writers.Shared (defField, metaToContext)

    data WriterState = WriterState {
      }

    data WriterEnvironment = WriterEnvironment {
        WriterEnvironment -> Text
    stIndent      :: Text          -- Indent after the marker at the beginning of list items
      , WriterEnvironment -> Bool
    stUseTags     :: Bool            -- True if we should use HTML tags because we're in a complex list
      , WriterEnvironment -> Bool
    stBackSlashLB :: Bool     -- True if we should produce formatted strings with newlines (as in a table cell)
      }

    instance Default WriterState where
      def :: WriterState
    def = WriterState :: WriterState
    WriterState {}

    instance Default WriterEnvironment where
      def :: WriterEnvironment
    def = WriterEnvironment :: Text -> Bool -> Bool -> WriterEnvironment
    WriterEnvironment { stIndent :: Text
    stIndent = ""
                              , stUseTags :: Bool
    stUseTags = Bool
    False
                              , stBackSlashLB :: Bool
    stBackSlashLB = Bool
    False }

    type DokuWiki m = ReaderT WriterEnvironment (StateT WriterState m)

    -- | Convert Pandoc to DokuWiki.
    writeDokuWiki :: PandocMonad m => WriterOptions -> Pandoc -> m Text
    writeDokuWiki :: WriterOptions -> Pandoc -> m Text
    writeDokuWiki opts :: WriterOptions
    opts document :: Pandoc
    document =
      DokuWiki m Text -> m Text
    forall (m :: * -> *) a. PandocMonad m => DokuWiki m a -> m a
    runDokuWiki (WriterOptions -> Pandoc -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> DokuWiki m Text
    pandocToDokuWiki WriterOptions
    opts Pandoc
    document)

    runDokuWiki :: PandocMonad m => DokuWiki m a -> m a
    runDokuWiki :: DokuWiki m a -> m a
    runDokuWiki = (StateT WriterState m a -> WriterState -> m a)
    -> WriterState -> StateT WriterState m a -> m a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip StateT WriterState m a -> WriterState -> m a
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT WriterState
    forall a. Default a => a
    def (StateT WriterState m a -> m a)
    -> (DokuWiki m a -> StateT WriterState m a) -> DokuWiki m a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (DokuWiki m a -> WriterEnvironment -> StateT WriterState m a)
    -> WriterEnvironment -> DokuWiki m a -> StateT WriterState m a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip DokuWiki m a -> WriterEnvironment -> StateT WriterState m a
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
    runReaderT WriterEnvironment
    forall a. Default a => a
    def

    -- | Return DokuWiki representation of document.
    pandocToDokuWiki :: PandocMonad m
                     => WriterOptions -> Pandoc -> DokuWiki m Text
    pandocToDokuWiki :: WriterOptions -> Pandoc -> DokuWiki m Text
    pandocToDokuWiki opts :: WriterOptions
    opts (Pandoc meta :: Meta
    meta blocks :: [Block]
    blocks) = do
      Context Text
    metadata <- WriterOptions
    -> ([Block]
        -> ReaderT WriterEnvironment (StateT WriterState m) (Doc Text))
    -> ([Inline]
        -> ReaderT WriterEnvironment (StateT WriterState m) (Doc Text))
    -> Meta
    -> ReaderT WriterEnvironment (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)
    -> DokuWiki m Text
    -> ReaderT WriterEnvironment (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) (DokuWiki m Text
     -> ReaderT WriterEnvironment (StateT WriterState m) (Doc Text))
    -> ([Block] -> DokuWiki m Text)
    -> [Block]
    -> ReaderT WriterEnvironment (StateT WriterState m) (Doc Text)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    blockListToDokuWiki WriterOptions
    opts)
                  ((Text -> Doc Text)
    -> DokuWiki m Text
    -> ReaderT WriterEnvironment (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) (DokuWiki m Text
     -> ReaderT WriterEnvironment (StateT WriterState m) (Doc Text))
    -> ([Inline] -> DokuWiki m Text)
    -> [Inline]
    -> ReaderT WriterEnvironment (StateT WriterState m) (Doc Text)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts)
                  Meta
    meta
      Text
    body <- WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    blockListToDokuWiki WriterOptions
    opts [Block]
    blocks
      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
    body
                  (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 -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $
        case WriterOptions -> Maybe (Template Text)
    writerTemplate WriterOptions
    opts of
           Nothing  -> Text
    body
           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

    -- | Escape special characters for DokuWiki.
    escapeString :: Text -> Text
    escapeString :: Text -> Text
    escapeString = 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 DokuWiki.
    blockToDokuWiki :: PandocMonad m
                    => WriterOptions -- ^ Options
                    -> Block         -- ^ Block element
                    -> DokuWiki m Text

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

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

    blockToDokuWiki opts :: WriterOptions
    opts (Plain inlines :: [Inline]
    inlines) =
      WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    inlines

    -- title beginning with fig: indicates that the image is a figure
    -- dokuwiki doesn't support captions - so combine together alt and caption into alt
    blockToDokuWiki opts :: WriterOptions
    opts (Para [Image attr :: Attr
    attr txt :: [Inline]
    txt (src :: Text
    src,tgt :: Text
    tgt)])
      | Just tit :: Text
    tit <- Text -> Text -> Maybe Text
    T.stripPrefix "fig:" Text
    tgt
      = do
          Text
    capt <- if [Inline] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Inline]
    txt
                  then Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""
                  else (" " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>) (Text -> Text) -> DokuWiki m Text -> DokuWiki m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki 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 -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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"

    blockToDokuWiki opts :: WriterOptions
    opts (Para inlines :: [Inline]
    inlines) = do
      Text
    indent <- (WriterEnvironment -> Text) -> DokuWiki m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Text
    stIndent
      Bool
    useTags <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stUseTags
      Text
    contents <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    inlines
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ if Bool
    useTags
                  then "<HTML><p></HTML>" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "<HTML></p></HTML>"
                  else Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> if Text -> Bool
    T.null Text
    indent then "\n" else ""

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

    blockToDokuWiki _ 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 "dokuwiki" = Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    str
      -- See https://www.dokuwiki.org/wiki:syntax
      -- use uppercase HTML tag for block-level content:
      | Format
    f Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format "html"     = Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<HTML>\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n</HTML>"
      | Bool
    otherwise              = "" Text
    -> ReaderT WriterEnvironment (StateT WriterState m) ()
    -> DokuWiki m Text
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$
             LogMessage -> ReaderT WriterEnvironment (StateT WriterState m) ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (Block -> LogMessage
    BlockNotRendered Block
    b)

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

    blockToDokuWiki opts :: WriterOptions
    opts (Header level :: Int
    level _ inlines :: [Inline]
    inlines) = do
      -- emphasis, links etc. not allowed in headers, apparently,
      -- so we remove formatting:
      Text
    contents <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts ([Inline] -> DokuWiki m Text) -> [Inline] -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> [Inline]
    forall a. Walkable Inline a => a -> [Inline]
    removeFormatting [Inline]
    inlines
      let eqs :: Text
    eqs = Int -> Text -> Text
    T.replicate ( 7 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    level ) "="
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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"

    blockToDokuWiki _ (CodeBlock (_,classes :: [Text]
    classes,_) str :: Text
    str) = do
      let at :: [Text]
    at  = [Text]
    classes [Text] -> [Text] -> [Text]
    forall a. Eq a => [a] -> [a] -> [a]
    `intersect` ["actionscript", "ada", "apache", "applescript", "asm", "asp",
                           "autoit", "bash", "blitzbasic", "bnf", "c", "c_mac", "caddcl", "cadlisp", "cfdg", "cfm",
                           "cpp", "cpp-qt", "csharp", "css", "d", "delphi", "diff", "div", "dos", "eiffel", "fortran",
                           "freebasic", "gml", "groovy", "html4strict", "idl", "ini", "inno", "io", "java", "java5",
                           "javascript", "latex", "lisp", "lua", "matlab", "mirc", "mpasm", "mysql", "nsis", "objc",
                           "ocaml", "ocaml-brief", "oobas", "oracle8", "pascal", "perl", "php", "php-brief", "plsql",
                           "python", "qbasic", "rails", "reg", "robots", "ruby", "sas", "scheme", "sdlbasic",
                           "smalltalk", "smarty", "sql", "tcl", "", "thinbasic", "tsql", "vb", "vbnet", "vhdl",
                           "visualfoxpro", "winbatch", "xml", "xpp", "z80"]
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<code" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                    (case [Text]
    at of
                          []    -> ">\n"
                          (x :: Text
    x:_) -> " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    x Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> ">\n") Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n</code>"

    blockToDokuWiki opts :: WriterOptions
    opts (BlockQuote blocks :: [Block]
    blocks) = do
      Text
    contents <- WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    blockListToDokuWiki WriterOptions
    opts [Block]
    blocks
      if [Block] -> Bool
    isSimpleBlockQuote [Block]
    blocks
         then Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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
         else Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<HTML><blockquote>\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "</blockquote></HTML>"

    blockToDokuWiki 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 -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""
                       else do
                          Text
    c <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    capt
                          Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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 [Text] -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
                     else (Alignment -> [Block] -> DokuWiki m Text)
    -> [Alignment]
    -> [[Block]]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> m c) -> [a] -> [b] -> m [c]
    zipWithM (WriterOptions -> Alignment -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Alignment -> [Block] -> DokuWiki m Text
    tableItemToDokuWiki WriterOptions
    opts) [Alignment]
    aligns [[Block]]
    headers
      [[Text]]
    rows' <- ([[Block]]
     -> ReaderT WriterEnvironment (StateT WriterState m) [Text])
    -> [[[Block]]]
    -> ReaderT WriterEnvironment (StateT WriterState m) [[Text]]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM ((Alignment -> [Block] -> DokuWiki m Text)
    -> [Alignment]
    -> [[Block]]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> m c) -> [a] -> [b] -> m [c]
    zipWithM (WriterOptions -> Alignment -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Alignment -> [Block] -> DokuWiki m Text
    tableItemToDokuWiki 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 renderRow :: Text -> [Text] -> Text
    renderRow sep :: Text
    sep cells :: [Text]
    cells = Text
    sep Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
              Text -> [Text] -> Text
    T.intercalate Text
    sep (((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
    sep
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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] -> 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] -> Text
    T.unlines (([Text] -> Text) -> [[Text]] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map (Text -> [Text] -> Text
    renderRow "|") [[Text]]
    rows')

    blockToDokuWiki opts :: WriterOptions
    opts x :: Block
    x@(BulletList items :: [[Block]]
    items) = do
      Bool
    oldUseTags <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stUseTags
      Text
    indent <- (WriterEnvironment -> Text) -> DokuWiki m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Text
    stIndent
      Bool
    backSlash <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stBackSlashLB
      let useTags :: Bool
    useTags = Bool
    oldUseTags Bool -> Bool -> Bool
    || Bool -> Bool
    not (Block -> Bool
    isSimpleList Block
    x)
      if Bool
    useTags
         then do
            [Text]
    contents <- (WriterEnvironment -> WriterEnvironment)
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local (\s :: WriterEnvironment
    s -> WriterEnvironment
    s { stUseTags :: Bool
    stUseTags = Bool
    True })
                          (([Block] -> DokuWiki m Text)
    -> [[Block]]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    listItemToDokuWiki WriterOptions
    opts) [[Block]]
    items)
            Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<HTML><ul></HTML>\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> [Text] -> Text
    vcat [Text]
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "<HTML></ul></HTML>\n"
         else do
            [Text]
    contents <- (WriterEnvironment -> WriterEnvironment)
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local (\s :: WriterEnvironment
    s -> WriterEnvironment
    s { stIndent :: Text
    stIndent = WriterEnvironment -> Text
    stIndent WriterEnvironment
    s Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "  "
                                       , stBackSlashLB :: Bool
    stBackSlashLB = Bool
    backSlash})
                          (([Block] -> DokuWiki m Text)
    -> [[Block]]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    listItemToDokuWiki WriterOptions
    opts) [[Block]]
    items)
            Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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 ""

    blockToDokuWiki opts :: WriterOptions
    opts x :: Block
    x@(OrderedList attribs :: ListAttributes
    attribs items :: [[Block]]
    items) = do
      Bool
    oldUseTags <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stUseTags
      Text
    indent <- (WriterEnvironment -> Text) -> DokuWiki m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Text
    stIndent
      Bool
    backSlash <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stBackSlashLB
      let useTags :: Bool
    useTags = Bool
    oldUseTags Bool -> Bool -> Bool
    || Bool -> Bool
    not (Block -> Bool
    isSimpleList Block
    x)
      if Bool
    useTags
         then do
            [Text]
    contents <- (WriterEnvironment -> WriterEnvironment)
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local (\s :: WriterEnvironment
    s -> WriterEnvironment
    s { stUseTags :: Bool
    stUseTags = Bool
    True })
                          (([Block] -> DokuWiki m Text)
    -> [[Block]]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    orderedListItemToDokuWiki WriterOptions
    opts) [[Block]]
    items)
            Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<HTML><ol" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> ListAttributes -> Text
    listAttribsToString ListAttributes
    attribs Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "></HTML>\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> [Text] -> Text
    vcat [Text]
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "<HTML></ol></HTML>\n"
         else do
            [Text]
    contents <- (WriterEnvironment -> WriterEnvironment)
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local (\s :: WriterEnvironment
    s -> WriterEnvironment
    s { stIndent :: Text
    stIndent = WriterEnvironment -> Text
    stIndent WriterEnvironment
    s Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "  "
                                       , stBackSlashLB :: Bool
    stBackSlashLB = Bool
    backSlash})
                          (([Block] -> DokuWiki m Text)
    -> [[Block]]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    orderedListItemToDokuWiki WriterOptions
    opts) [[Block]]
    items)
            Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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 ""

    -- TODO Need to decide how to make definition lists work on dokuwiki - I don't think there
    --      is a specific representation of them.
    -- TODO This creates double '; ; ' if there is a bullet or ordered list inside a definition list
    blockToDokuWiki opts :: WriterOptions
    opts x :: Block
    x@(DefinitionList items :: [([Inline], [[Block]])]
    items) = do
      Bool
    oldUseTags <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stUseTags
      Text
    indent <- (WriterEnvironment -> Text) -> DokuWiki m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Text
    stIndent
      Bool
    backSlash <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stBackSlashLB
      let useTags :: Bool
    useTags = Bool
    oldUseTags Bool -> Bool -> Bool
    || Bool -> Bool
    not (Block -> Bool
    isSimpleList Block
    x)
      if Bool
    useTags
         then do
            [Text]
    contents <- (WriterEnvironment -> WriterEnvironment)
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local (\s :: WriterEnvironment
    s -> WriterEnvironment
    s { stUseTags :: Bool
    stUseTags = Bool
    True })
                          ((([Inline], [[Block]]) -> DokuWiki m Text)
    -> [([Inline], [[Block]])]
    -> ReaderT WriterEnvironment (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]]) -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> ([Inline], [[Block]]) -> DokuWiki m Text
    definitionListItemToDokuWiki WriterOptions
    opts) [([Inline], [[Block]])]
    items)
            Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<HTML><dl></HTML>\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> [Text] -> Text
    vcat [Text]
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "<HTML></dl></HTML>\n"
         else do
            [Text]
    contents <- (WriterEnvironment -> WriterEnvironment)
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local (\s :: WriterEnvironment
    s -> WriterEnvironment
    s { stIndent :: Text
    stIndent = WriterEnvironment -> Text
    stIndent WriterEnvironment
    s Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "  "
                                       , stBackSlashLB :: Bool
    stBackSlashLB = Bool
    backSlash})
                          ((([Inline], [[Block]]) -> DokuWiki m Text)
    -> [([Inline], [[Block]])]
    -> ReaderT WriterEnvironment (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]]) -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> ([Inline], [[Block]]) -> DokuWiki m Text
    definitionListItemToDokuWiki WriterOptions
    opts) [([Inline], [[Block]])]
    items)
            Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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 ""

    -- Auxiliary functions for lists:

    -- | Convert ordered list attributes to HTML attribute string
    listAttribsToString :: ListAttributes -> Text
    listAttribsToString :: ListAttributes -> Text
    listAttribsToString (startnum :: Int
    startnum, numstyle :: ListNumberStyle
    numstyle, _) =
      let numstyle' :: Text
    numstyle' = Text -> Text
    camelCaseToHyphenated (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ ListNumberStyle -> Text
    forall a. Show a => a -> Text
    tshow ListNumberStyle
    numstyle
      in  (if Int
    startnum Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= 1
              then " start=\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    startnum Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\""
              else "") Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
          (if ListNumberStyle
    numstyle ListNumberStyle -> ListNumberStyle -> Bool
    forall a. Eq a => a -> a -> Bool
    /= ListNumberStyle
    DefaultStyle
              then " style=\"list-style-type: " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    numstyle' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> ";\""
              else "")

    -- | Convert bullet list item (list of blocks) to DokuWiki.
    listItemToDokuWiki :: PandocMonad m
                       => WriterOptions -> [Block] -> DokuWiki m Text
    listItemToDokuWiki :: WriterOptions -> [Block] -> DokuWiki m Text
    listItemToDokuWiki opts :: WriterOptions
    opts items :: [Block]
    items = do
      Bool
    useTags <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stUseTags
      if Bool
    useTags
         then do
           Text
    contents <- WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    blockListToDokuWiki WriterOptions
    opts [Block]
    items
           Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<HTML><li></HTML>" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "<HTML></li></HTML>"
         else do
           [Text]
    bs <- (Block -> DokuWiki m Text)
    -> [Block]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> Block -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Block -> DokuWiki m Text
    blockToDokuWiki WriterOptions
    opts) [Block]
    items
           let contents :: Text
    contents = case [Block]
    items of
                               [_, CodeBlock _ _] -> [Text] -> Text
    T.concat [Text]
    bs
                               _                  -> [Text] -> Text
    vcat [Text]
    bs
           Text
    indent <- (WriterEnvironment -> Text) -> DokuWiki m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Text
    stIndent
           Bool
    backSlash <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stBackSlashLB
           let indent' :: Text
    indent' = if Bool
    backSlash then Int -> Text -> Text
    T.drop 2 Text
    indent else Text
    indent
           Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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 DokuWiki.
    -- | TODO Emiminate dreadful duplication of text from listItemToDokuWiki
    orderedListItemToDokuWiki :: PandocMonad m => WriterOptions -> [Block] -> DokuWiki m Text
    orderedListItemToDokuWiki :: WriterOptions -> [Block] -> DokuWiki m Text
    orderedListItemToDokuWiki opts :: WriterOptions
    opts items :: [Block]
    items = do
      Text
    contents <- WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    blockListToDokuWiki WriterOptions
    opts [Block]
    items
      Bool
    useTags <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stUseTags
      if Bool
    useTags
         then Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<HTML><li></HTML>" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "<HTML></li></HTML>"
         else do
           Text
    indent <- (WriterEnvironment -> Text) -> DokuWiki m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Text
    stIndent
           Bool
    backSlash <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stBackSlashLB
           let indent' :: Text
    indent' = if Bool
    backSlash then Int -> Text -> Text
    T.drop 2 Text
    indent else Text
    indent
           Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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 definition list item (label, list of blocks) to DokuWiki.
    definitionListItemToDokuWiki :: PandocMonad m
                                 => WriterOptions
                                 -> ([Inline],[[Block]])
                                 -> DokuWiki m Text
    definitionListItemToDokuWiki :: WriterOptions -> ([Inline], [[Block]]) -> DokuWiki m Text
    definitionListItemToDokuWiki opts :: WriterOptions
    opts (label :: [Inline]
    label, items :: [[Block]]
    items) = do
      Text
    labelText <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    label
      [Text]
    contents <- ([Block] -> DokuWiki m Text)
    -> [[Block]]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    blockListToDokuWiki WriterOptions
    opts) [[Block]]
    items
      Bool
    useTags <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stUseTags
      if Bool
    useTags
         then Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<HTML><dt></HTML>" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    labelText Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "<HTML></dt></HTML>\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
               Text -> [Text] -> Text
    T.intercalate "\n" ((Text -> Text) -> [Text] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map (\d :: Text
    d -> "<HTML><dd></HTML>" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    d Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "<HTML></dd></HTML>") [Text]
    contents)
         else do
           Text
    indent <- (WriterEnvironment -> Text) -> DokuWiki m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Text
    stIndent
           Bool
    backSlash <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stBackSlashLB
           let indent' :: Text
    indent' = if Bool
    backSlash then Int -> Text -> Text
    T.drop 2 Text
    indent else Text
    indent
           Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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

    -- | True if the list can be handled by simple wiki markup, False if HTML tags will be needed.
    isSimpleList :: Block -> Bool
    isSimpleList :: Block -> Bool
    isSimpleList x :: Block
    x =
      case Block
    x of
           BulletList items :: [[Block]]
    items            -> ([Block] -> Bool) -> [[Block]] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all [Block] -> Bool
    isSimpleListItem [[Block]]
    items
           OrderedList (1, _, _) items :: [[Block]]
    items -> ([Block] -> Bool) -> [[Block]] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all [Block] -> Bool
    isSimpleListItem [[Block]]
    items
           DefinitionList items :: [([Inline], [[Block]])]
    items        -> (([Inline], [[Block]]) -> Bool) -> [([Inline], [[Block]])] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (([Block] -> Bool) -> [[Block]] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all [Block] -> Bool
    isSimpleListItem ([[Block]] -> Bool)
    -> (([Inline], [[Block]]) -> [[Block]])
    -> ([Inline], [[Block]])
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Inline], [[Block]]) -> [[Block]]
    forall a b. (a, b) -> b
    snd) [([Inline], [[Block]])]
    items
           _                           -> Bool
    False

    -- | True if list item can be handled with the simple wiki syntax.  False if
    --   HTML tags will be needed.
    isSimpleListItem :: [Block] -> Bool
    isSimpleListItem :: [Block] -> Bool
    isSimpleListItem []  = Bool
    True
    isSimpleListItem [x :: Block
    x, CodeBlock{}] | Block -> Bool
    isPlainOrPara Block
    x = Bool
    True
    isSimpleListItem (x :: Block
    x:ys :: [Block]
    ys) | Block -> Bool
    isPlainOrPara Block
    x = (Block -> Bool) -> [Block] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all Block -> Bool
    isSimpleList [Block]
    ys
    isSimpleListItem _ = Bool
    False

    isPlainOrPara :: Block -> Bool
    isPlainOrPara :: Block -> Bool
    isPlainOrPara (Plain _) = Bool
    True
    isPlainOrPara (Para  _) = Bool
    True
    isPlainOrPara _         = Bool
    False

    isSimpleBlockQuote :: [Block] -> Bool
    isSimpleBlockQuote :: [Block] -> Bool
    isSimpleBlockQuote bs :: [Block]
    bs  = (Block -> Bool) -> [Block] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all Block -> Bool
    isPlainOrPara [Block]
    bs

    -- | Concatenates strings with line breaks between them.
    vcat :: [Text] -> Text
    vcat :: [Text] -> Text
    vcat = Text -> [Text] -> Text
    T.intercalate "\n"

    -- | For each string in the input list, convert all newlines to
    -- dokuwiki escaped newlines. Then concat the list using double linebreaks.
    backSlashLineBreaks :: [Text] -> Text
    backSlashLineBreaks :: [Text] -> Text
    backSlashLineBreaks ls :: [Text]
    ls = [Text] -> Text
    vcatBackSlash ([Text] -> Text) -> [Text] -> Text
    forall a b. (a -> b) -> a -> b
    $ (Text -> Text) -> [Text] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> Text
    T.pack (String -> Text) -> (Text -> String) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    escape (String -> String) -> (Text -> String) -> Text -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> String
    T.unpack) [Text]
    ls
      where
        vcatBackSlash :: [Text] -> Text
    vcatBackSlash = Text -> [Text] -> Text
    T.intercalate "\\\\ \\\\ " -- simulate paragraphs.
        escape :: String -> String
    escape ['\n']    = "" -- remove trailing newlines
        escape ('\n':cs :: String
    cs) = "\\\\ " String -> String -> String
    forall a. Semigroup a => a -> a -> a
    <> String -> String
    escape String
    cs
        escape (c :: Char
    c:cs :: String
    cs)    = Char
    c Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    escape String
    cs
        escape []        = []

    -- Auxiliary functions for tables:

    tableItemToDokuWiki :: PandocMonad m
                        => WriterOptions
                        -> Alignment
                        -> [Block]
                        -> DokuWiki m Text
    tableItemToDokuWiki :: WriterOptions -> Alignment -> [Block] -> DokuWiki m Text
    tableItemToDokuWiki 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 "")
      Text
    contents <- (WriterEnvironment -> WriterEnvironment)
    -> DokuWiki m Text -> DokuWiki m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local (\s :: WriterEnvironment
    s -> WriterEnvironment
    s { stBackSlashLB :: Bool
    stBackSlashLB = Bool
    True }) (DokuWiki m Text -> DokuWiki m Text)
    -> DokuWiki m Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $
                  WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    blockListToDokuWiki WriterOptions
    opts [Block]
    item
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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 DokuWiki.
    blockListToDokuWiki :: PandocMonad m
                        => WriterOptions -- ^ Options
                        -> [Block]       -- ^ List of block elements
                        -> DokuWiki m Text
    blockListToDokuWiki :: WriterOptions -> [Block] -> DokuWiki m Text
    blockListToDokuWiki opts :: WriterOptions
    opts blocks :: [Block]
    blocks = do
      Bool
    backSlash <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stBackSlashLB
      let blocks' :: [Block]
    blocks' = [Block] -> [Block]
    consolidateRawBlocks [Block]
    blocks
      if Bool
    backSlash
        then [Text] -> Text
    backSlashLineBreaks ([Text] -> Text)
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    -> DokuWiki m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Block -> DokuWiki m Text)
    -> [Block]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> Block -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Block -> DokuWiki m Text
    blockToDokuWiki WriterOptions
    opts) [Block]
    blocks'
        else [Text] -> Text
    vcat ([Text] -> Text)
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    -> DokuWiki m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Block -> DokuWiki m Text)
    -> [Block]
    -> ReaderT WriterEnvironment (StateT WriterState m) [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (WriterOptions -> Block -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Block -> DokuWiki m Text
    blockToDokuWiki WriterOptions
    opts) [Block]
    blocks'

    consolidateRawBlocks :: [Block] -> [Block]
    consolidateRawBlocks :: [Block] -> [Block]
    consolidateRawBlocks [] = []
    consolidateRawBlocks (RawBlock f1 :: Format
    f1 b1 :: Text
    b1 : RawBlock f2 :: Format
    f2 b2 :: Text
    b2 : xs :: [Block]
    xs)
      | Format
    f1 Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Format
    f2 = [Block] -> [Block]
    consolidateRawBlocks (Format -> Text -> Block
    RawBlock Format
    f1 (Text
    b1 Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    b2) Block -> [Block] -> [Block]
    forall a. a -> [a] -> [a]
    : [Block]
    xs)
    consolidateRawBlocks (x :: Block
    x:xs :: [Block]
    xs) = Block
    x Block -> [Block] -> [Block]
    forall a. a -> [a] -> [a]
    : [Block] -> [Block]
    consolidateRawBlocks [Block]
    xs

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

    -- | Convert Pandoc inline element to DokuWiki.
    inlineToDokuWiki :: PandocMonad m
                     => WriterOptions -> Inline -> DokuWiki m Text

    inlineToDokuWiki :: WriterOptions -> Inline -> DokuWiki m Text
    inlineToDokuWiki opts :: WriterOptions
    opts (Span _attrs :: Attr
    _attrs ils :: [Inline]
    ils) =
      WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    ils

    inlineToDokuWiki opts :: WriterOptions
    opts (Emph lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    lst
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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
    <> "//"

    inlineToDokuWiki opts :: WriterOptions
    opts (Strong lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    lst
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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
    <> "**"

    inlineToDokuWiki opts :: WriterOptions
    opts (Strikeout lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    lst
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<del>" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "</del>"

    inlineToDokuWiki opts :: WriterOptions
    opts (Superscript lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    lst
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<sup>" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "</sup>"

    inlineToDokuWiki opts :: WriterOptions
    opts (Subscript lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    lst
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<sub>" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "</sub>"

    inlineToDokuWiki opts :: WriterOptions
    opts (SmallCaps lst :: [Inline]
    lst) = WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    lst

    inlineToDokuWiki opts :: WriterOptions
    opts (Quoted SingleQuote lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    lst
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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"

    inlineToDokuWiki opts :: WriterOptions
    opts (Quoted DoubleQuote lst :: [Inline]
    lst) = do
      Text
    contents <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    lst
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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"

    inlineToDokuWiki opts :: WriterOptions
    opts (Cite _  lst :: [Inline]
    lst) = WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    lst

    inlineToDokuWiki _ (Code _ str :: Text
    str) =
      -- In dokuwiki, text surrounded by '' is really just a font statement, i.e. <tt>,
      -- and so other formatting can be present inside.
      -- However, in pandoc, and markdown, inlined code doesn't contain formatting.
      -- So I have opted for using %% to disable all formatting inside inline code blocks.
      -- This gives the best results when converting from other formats to dokuwiki, even if
      -- the resultand code is a little ugly, for short strings that don't contain formatting
      -- characters.
      -- It does mean that if pandoc could ever read dokuwiki, and so round-trip the format,
      -- any formatting inside inlined code blocks would be lost, or presented incorrectly.
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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
    <> "%%''"

    inlineToDokuWiki _ (Str str :: Text
    str) = Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    escapeString Text
    str

    inlineToDokuWiki _ (Math mathType :: MathType
    mathType str :: Text
    str) = Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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  -> "$"

    inlineToDokuWiki _ 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 "dokuwiki" = Text -> DokuWiki 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"     = Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ "<html>" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "</html>"
      | Bool
    otherwise              = "" Text
    -> ReaderT WriterEnvironment (StateT WriterState m) ()
    -> DokuWiki m Text
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ LogMessage -> ReaderT WriterEnvironment (StateT WriterState m) ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (Inline -> LogMessage
    InlineNotRendered Inline
    il)

    inlineToDokuWiki _ LineBreak = do
      Bool
    backSlash <- (WriterEnvironment -> Bool)
    -> ReaderT WriterEnvironment (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterEnvironment -> Bool
    stBackSlashLB
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki m Text
    forall a b. (a -> b) -> a -> b
    $ if Bool
    backSlash
               then "\n"
               else "\\\\\n"

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

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

    inlineToDokuWiki opts :: WriterOptions
    opts (Link _ txt :: [Inline]
    txt (src :: Text
    src, _)) = do
      Text
    label <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    txt
      case [Inline]
    txt of
         [Str s :: Text
    s] | "mailto:" Text -> Text -> Bool
    `T.isPrefixOf` Text
    src -> Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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 -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    src
         _  -> if Text -> Bool
    isURI Text
    src
                  then Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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 -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    label Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "]]"
                  else Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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 -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    label Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "]]"
                         where src' :: Text
    src' = case Text -> Maybe (Char, Text)
    T.uncons Text
    src of
                                         Just ('/',xs :: Text
    xs) -> Text
    xs  -- with leading / it's a
                                         _             -> Text
    src -- link to a help page
    inlineToDokuWiki opts :: WriterOptions
    opts (Image attr :: Attr
    attr alt :: [Inline]
    alt (source :: Text
    source, tit :: Text
    tit)) = do
      Text
    alt' <- WriterOptions -> [Inline] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Inline] -> DokuWiki m Text
    inlineListToDokuWiki WriterOptions
    opts [Inline]
    alt
      let txt :: Text
    txt = case (Text
    tit, [Inline]
    alt) of
                  ("", []) -> ""
                  ("", _ ) -> "|" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    alt'
                  (_ , _ ) -> "|" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    tit
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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
    <> "}}"

    inlineToDokuWiki opts :: WriterOptions
    opts (Note contents :: [Block]
    contents) = do
      Text
    contents' <- WriterOptions -> [Block] -> DokuWiki m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> [Block] -> DokuWiki m Text
    blockListToDokuWiki WriterOptions
    opts [Block]
    contents
      Text -> DokuWiki m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> DokuWiki m Text) -> Text -> DokuWiki 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
    <> "))"
      -- note - may not work for notes with multiple blocks

    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  = ""