    {-# LANGUAGE OverloadedStrings #-}
    {-
    Copyright (C) 2008-2017 John MacFarlane <jgm@berkeley.edu>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    -}

    {- |
       Module      : Text.Pandoc.Writers.XWiki
       Copyright   : Copyright (C) 2008-2017 John MacFarlane
       License     : GNU GPL, version 2 or above

       Maintainer  : Derek Chen-Becker <dchenbecker@gmail.com>
       Stability   : alpha
       Portability : portable

    Conversion of 'Pandoc' documents to XWiki markup.

    XWiki:  <http://www.xwiki.org/>
    XWiki Syntax:  <http://www.xwiki.org/xwiki/bin/view/Documentation/UserGuide/Features/XWikiSyntax/>
    -}

    module Text.Pandoc.Writers.XWiki ( writeXWiki ) where
    import Control.Monad.Reader (ReaderT, asks, local, runReaderT)
    import qualified Data.Set as Set
    import qualified Data.Text as Text
    import Data.Text (Text, intercalate, replace, split)
    import Text.Pandoc.Class.PandocMonad (PandocMonad, report)
    import Text.Pandoc.Definition
    import Text.Pandoc.Logging
    import Text.Pandoc.Options
    import Text.Pandoc.Shared
    import Text.Pandoc.Writers.MediaWiki (highlightingLangs)

    data WriterState = WriterState {
      WriterState -> Text
    listLevel :: Text -- String at the beginning of items
    }

    type XWikiReader m = ReaderT WriterState m

    -- | Convert Pandoc to XWiki.
    writeXWiki :: PandocMonad m => WriterOptions -> Pandoc -> m Text
    writeXWiki :: WriterOptions -> Pandoc -> m Text
    writeXWiki _ (Pandoc _ blocks :: [Block]
    blocks) =
      let env :: WriterState
    env = WriterState :: Text -> WriterState
    WriterState { listLevel :: Text
    listLevel = "" }
      in ReaderT WriterState m Text -> WriterState -> m Text
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
    runReaderT ([Block] -> ReaderT WriterState m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> XWikiReader m Text
    blockListToXWiki [Block]
    blocks) WriterState
    env

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

    -- If an id is provided, we can generate an anchor using the id macro
    -- https://extensions.xwiki.org/xwiki/bin/view/Extension/Id%20Macro
    genAnchor :: Text -> Text
    genAnchor :: Text -> Text
    genAnchor id' :: Text
    id' = if Text -> Bool
    Text.null Text
    id'
      then ""
      else "{{id name=\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    id' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\" /}}"

    blockListToXWiki :: PandocMonad m => [Block] -> XWikiReader m Text
    blockListToXWiki :: [Block] -> XWikiReader m Text
    blockListToXWiki blocks :: [Block]
    blocks =
      [Text] -> Text
    vcat ([Text] -> Text)
    -> ReaderT WriterState m [Text] -> XWikiReader m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Block -> XWikiReader m Text)
    -> [Block] -> ReaderT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM Block -> XWikiReader m Text
    forall (m :: * -> *). PandocMonad m => Block -> XWikiReader m Text
    blockToXWiki [Block]
    blocks

    blockToXWiki :: PandocMonad m => Block -> XWikiReader m Text

    blockToXWiki :: Block -> XWikiReader m Text
    blockToXWiki Null = Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return ""

    blockToXWiki (Div (id' :: Text
    id', _, _) blocks :: [Block]
    blocks) = do
      Text
    content <- [Block] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> XWikiReader m Text
    blockListToXWiki [Block]
    blocks
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    genAnchor Text
    id' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    content

    blockToXWiki (Plain inlines :: [Inline]
    inlines) =
      [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    inlines

    blockToXWiki (Para inlines :: [Inline]
    inlines) = do
      Text
    contents <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    inlines
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n"

    blockToXWiki (LineBlock lns :: [[Inline]]
    lns) =
      Block -> XWikiReader m Text
    forall (m :: * -> *). PandocMonad m => Block -> XWikiReader m Text
    blockToXWiki (Block -> XWikiReader m Text) -> Block -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ [[Inline]] -> Block
    linesToPara [[Inline]]
    lns

    blockToXWiki 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 "xwiki" = Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    str
      | Bool
    otherwise           = "" Text -> ReaderT WriterState m () -> XWikiReader m Text
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ LogMessage -> ReaderT WriterState m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (Block -> LogMessage
    BlockNotRendered Block
    b)

    blockToXWiki HorizontalRule = Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return "\n----\n"

    blockToXWiki (Header level :: Int
    level (id' :: Text
    id', _, _) inlines :: [Inline]
    inlines) = do
      Text
    contents <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    inlines
      let eqs :: Text
    eqs = Int -> Text -> Text
    Text.replicate Int
    level "="
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader 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 -> Text
    genAnchor Text
    id' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    eqs Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n"

    -- XWiki doesn't appear to differentiate between inline and block-form code, so we delegate
    -- We do amend the text to ensure that the code markers are on their own lines, since this is a block
    blockToXWiki (CodeBlock attrs :: Attr
    attrs str :: Text
    str) = do
      Text
    contents <- Inline -> XWikiReader m Text
    forall (m :: * -> *). PandocMonad m => Inline -> XWikiReader m Text
    inlineToXWiki (Attr -> Text -> Inline
    Code Attr
    attrs ("\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n"))
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ "\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\n"

    blockToXWiki (BlockQuote blocks :: [Block]
    blocks) = do
      Text
    blockText <- [Block] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> XWikiReader m Text
    blockListToXWiki [Block]
    blocks
      let quoteLines :: [Text]
    quoteLines = (Char -> Bool) -> Text -> [Text]
    split (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == '\n') Text
    blockText
      let prefixed :: [Text]
    prefixed = (Text -> Text) -> [Text] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map (">" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>) [Text]
    quoteLines
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    vcat [Text]
    prefixed

    blockToXWiki (BulletList contents :: [[Block]]
    contents) = Text -> [[Block]] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Text -> [[Block]] -> XWikiReader m Text
    blockToXWikiList "*" [[Block]]
    contents

    blockToXWiki (OrderedList _ contents :: [[Block]]
    contents) = Text -> [[Block]] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Text -> [[Block]] -> XWikiReader m Text
    blockToXWikiList "1" [[Block]]
    contents

    blockToXWiki (DefinitionList items :: [([Inline], [[Block]])]
    items) = do
      Text
    lev <- (WriterState -> Text) -> XWikiReader m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterState -> Text
    listLevel
      [Text]
    contents <- (WriterState -> WriterState)
    -> ReaderT WriterState m [Text] -> ReaderT WriterState m [Text]
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local (\s :: WriterState
    s -> WriterState
    s { listLevel :: Text
    listLevel = WriterState -> Text
    listLevel WriterState
    s Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> ";" }) (ReaderT WriterState m [Text] -> ReaderT WriterState m [Text])
    -> ReaderT WriterState m [Text] -> ReaderT WriterState m [Text]
    forall a b. (a -> b) -> a -> b
    $ (([Inline], [[Block]]) -> XWikiReader m Text)
    -> [([Inline], [[Block]])] -> ReaderT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM ([Inline], [[Block]]) -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    ([Inline], [[Block]]) -> XWikiReader m Text
    definitionListItemToMediaWiki [([Inline], [[Block]])]
    items
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader 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
    Text.null Text
    lev then "\n" else ""

    -- TODO: support more features
    blockToXWiki (Table _ _ _ headers :: [[Block]]
    headers rows' :: [[[Block]]]
    rows') = do
      [Text]
    headers' <- ([Block] -> XWikiReader m Text)
    -> [[Block]] -> ReaderT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (Bool -> [Block] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Bool -> [Block] -> XWikiReader m Text
    tableCellXWiki Bool
    True) [[Block]]
    headers
      [Text]
    otherRows <- ([[Block]] -> XWikiReader m Text)
    -> [[[Block]]] -> ReaderT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM [[Block]] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [[Block]] -> XWikiReader m Text
    formRow [[[Block]]]
    rows'
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    Text.unlines ([Text] -> Text
    Text.unwords [Text]
    headers'Text -> [Text] -> [Text]
    forall a. a -> [a] -> [a]
    :[Text]
    otherRows)

    formRow :: PandocMonad m => [[Block]] -> XWikiReader m Text
    formRow :: [[Block]] -> XWikiReader m Text
    formRow row :: [[Block]]
    row = do
      [Text]
    cellStrings <- ([Block] -> XWikiReader m Text)
    -> [[Block]] -> ReaderT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (Bool -> [Block] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Bool -> [Block] -> XWikiReader m Text
    tableCellXWiki Bool
    False) [[Block]]
    row
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    Text.unwords [Text]
    cellStrings

    tableCellXWiki :: PandocMonad m => Bool -> [Block] -> XWikiReader m Text
    tableCellXWiki :: Bool -> [Block] -> XWikiReader m Text
    tableCellXWiki isHeader :: Bool
    isHeader cell :: [Block]
    cell = do
      Text
    contents <- [Block] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> XWikiReader m Text
    blockListToXWiki [Block]
    cell
      let isMultiline :: Bool
    isMultiline = ([Text] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length ([Text] -> Int) -> (Text -> [Text]) -> Text -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char -> Bool) -> Text -> [Text]
    split (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == '\n')) Text
    contents Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 1
      let contents' :: Text
    contents' = Text -> [Text] -> Text
    intercalate Text
    contents ([Text] -> Text) -> [Text] -> Text
    forall a b. (a -> b) -> a -> b
    $ if Bool
    isMultiline then ["(((", ")))"] else [Text
    forall a. Monoid a => a
    mempty, Text
    forall a. Monoid a => a
    mempty]
      let cellBorder :: Text
    cellBorder = if Bool
    isHeader then "|=" else "|"
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    cellBorder Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents'

    inlineListToXWiki :: PandocMonad m => [Inline] -> XWikiReader m Text
    inlineListToXWiki :: [Inline] -> XWikiReader m Text
    inlineListToXWiki lst :: [Inline]
    lst =
      [Text] -> Text
    forall a. Monoid a => [a] -> a
    mconcat ([Text] -> Text)
    -> ReaderT WriterState m [Text] -> XWikiReader m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Inline -> XWikiReader m Text)
    -> [Inline] -> ReaderT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM Inline -> XWikiReader m Text
    forall (m :: * -> *). PandocMonad m => Inline -> XWikiReader m Text
    inlineToXWiki [Inline]
    lst

    inlineToXWiki :: PandocMonad m => Inline -> XWikiReader m Text

    inlineToXWiki :: Inline -> XWikiReader m Text
    inlineToXWiki (Str str :: Text
    str) = Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    escapeXWikiString Text
    str

    inlineToXWiki Space = Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return " "

    -- Special syntax for XWiki 2.0. This won't break table cells
    inlineToXWiki LineBreak = Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return "\\\\"

    inlineToXWiki SoftBreak = Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return " "

    inlineToXWiki (Emph lst :: [Inline]
    lst) = do
      Text
    contents <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    lst
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader 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
    <> "//"

    inlineToXWiki (Strong lst :: [Inline]
    lst) = do
      Text
    contents <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    lst
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader 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
    <> "**"

    inlineToXWiki (Strikeout lst :: [Inline]
    lst) = do
      Text
    contents <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    lst
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader 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
    <> "--"

    inlineToXWiki (Superscript lst :: [Inline]
    lst) = do
      Text
    contents <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    lst
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader 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
    <> "^^"

    inlineToXWiki (Subscript lst :: [Inline]
    lst) = do
      Text
    contents <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    lst
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader 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
    <> ",,"

    -- TODO: Not supported. Maybe escape to HTML?
    inlineToXWiki (SmallCaps lst :: [Inline]
    lst) =
      [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    lst

    inlineToXWiki (Quoted SingleQuote lst :: [Inline]
    lst) = do
      Text
    contents <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    lst
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader 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
    <> "’"

    inlineToXWiki (Quoted DoubleQuote lst :: [Inline]
    lst) = do
      Text
    contents <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    lst
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader 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
    <> "”"

    inlineToXWiki (Code (_,classes :: [Text]
    classes,_) contents :: Text
    contents) = do
      let at :: Set Text
    at  = [Text] -> Set Text
    forall a. Ord a => [a] -> Set a
    Set.fromList [Text]
    classes Set Text -> Set Text -> Set Text
    forall a. Ord a => Set a -> Set a -> Set a
    `Set.intersection` Set Text
    highlightingLangs
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $
        case Set Text -> [Text]
    forall a. Set a -> [a]
    Set.toList Set Text
    at of
          [] -> "{{code}}" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "{{/code}}"
          (l :: Text
    l:_) -> "{{code language=\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    l 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
    <> "{{/code}}"

    inlineToXWiki (Cite _ lst :: [Inline]
    lst) = [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    lst

    -- FIXME: optionally support this (plugin?)
    inlineToXWiki (Math _ str :: Text
    str) = Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ "{{formula}}" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "{{/formula}}"

    inlineToXWiki il :: Inline
    il@(RawInline frmt :: Format
    frmt str :: Text
    str)
      | Format
    frmt Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format "xwiki" = Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    str
      | Bool
    otherwise              = "" Text -> ReaderT WriterState m () -> XWikiReader m Text
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ LogMessage -> ReaderT WriterState m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (Inline -> LogMessage
    InlineNotRendered Inline
    il)

    -- TODO: Handle anchors
    inlineToXWiki (Link (id' :: Text
    id', _, _) txt :: [Inline]
    txt (src :: Text
    src, _)) = do
      Text
    label <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    txt
      case [Inline]
    txt of
         [Str s :: Text
    s] | Text -> Bool
    isURI Text
    src Bool -> Bool -> Bool
    && Text -> Text
    escapeURI Text
    s Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    src -> Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    src Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Text
    genAnchor Text
    id'
         _  -> Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ "[[" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    label Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> ">>" 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 -> Text
    genAnchor Text
    id'

    inlineToXWiki (Image _ alt :: [Inline]
    alt (source :: Text
    source, tit :: Text
    tit)) = do
      Text
    alt' <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    alt
      let
        params :: Text
    params = [Text] -> Text
    Text.unwords ([Text] -> Text) -> [Text] -> Text
    forall a b. (a -> b) -> a -> b
    $ (Text -> Bool) -> [Text] -> [Text]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Bool
    Text.null) [
            if Text -> Bool
    Text.null Text
    alt' then "" else "alt=\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    alt' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\"",
              if Text -> Bool
    Text.null Text
    tit then "" else "title=\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    tit Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "\""
            ]
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ "[[image:" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    source Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> (if Text -> Bool
    Text.null Text
    params then "" else "||" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    params) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "]]"

    inlineToXWiki (Note contents :: [Block]
    contents) = do
      Text
    contents' <- [Block] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> XWikiReader m Text
    blockListToXWiki [Block]
    contents
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ "{{footnote}}" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Text
    Text.strip Text
    contents' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> "{{/footnote}}"

    -- TODO: support attrs other than id (anchor)
    inlineToXWiki (Span (id' :: Text
    id', _, _) contents :: [Inline]
    contents) = do
      Text
    contents' <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    contents
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    genAnchor Text
    id' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    contents'

    -- Utility method since (for now) all lists are handled the same way
    blockToXWikiList :: PandocMonad m => Text -> [[Block]] -> XWikiReader m Text
    blockToXWikiList :: Text -> [[Block]] -> XWikiReader m Text
    blockToXWikiList marker :: Text
    marker contents :: [[Block]]
    contents = do
      Text
    lev <- (WriterState -> Text) -> XWikiReader m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterState -> Text
    listLevel
      [Text]
    contents' <- (WriterState -> WriterState)
    -> ReaderT WriterState m [Text] -> ReaderT WriterState m [Text]
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local (\s :: WriterState
    s -> WriterState
    s { listLevel :: Text
    listLevel = WriterState -> Text
    listLevel WriterState
    s Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    marker } ) (ReaderT WriterState m [Text] -> ReaderT WriterState m [Text])
    -> ReaderT WriterState m [Text] -> ReaderT WriterState m [Text]
    forall a b. (a -> b) -> a -> b
    $ ([Block] -> XWikiReader m Text)
    -> [[Block]] -> ReaderT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM [Block] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> XWikiReader m Text
    listItemToXWiki [[Block]]
    contents
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader 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
    Text.null Text
    lev then "\n" else ""

    listItemToXWiki :: PandocMonad m => [Block] -> XWikiReader m Text
    listItemToXWiki :: [Block] -> XWikiReader m Text
    listItemToXWiki contents :: [Block]
    contents = do
      Text
    marker <- (WriterState -> Text) -> XWikiReader m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterState -> Text
    listLevel
      Text
    contents' <- [Block] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> XWikiReader m Text
    blockListToXWiki [Block]
    contents
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    marker Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> ". " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Text
    Text.strip Text
    contents'

    -- | Convert definition list item (label, list of blocks) to MediaWiki.
    definitionListItemToMediaWiki :: PandocMonad m
                                  => ([Inline],[[Block]])
                                  -> XWikiReader m Text
    definitionListItemToMediaWiki :: ([Inline], [[Block]]) -> XWikiReader m Text
    definitionListItemToMediaWiki (label :: [Inline]
    label, items :: [[Block]]
    items) = do
      Text
    labelText <- [Inline] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> XWikiReader m Text
    inlineListToXWiki [Inline]
    label
      [Text]
    contents <- ([Block] -> XWikiReader m Text)
    -> [[Block]] -> ReaderT WriterState m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM [Block] -> XWikiReader m Text
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> XWikiReader m Text
    blockListToXWiki [[Block]]
    items
      Text
    marker <- (WriterState -> Text) -> XWikiReader m Text
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterState -> Text
    listLevel
      Text -> XWikiReader m Text
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> XWikiReader m Text) -> Text -> XWikiReader m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    marker 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
    <> "\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
        Text -> [Text] -> Text
    intercalate "\n" ((Text -> Text) -> [Text] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map (\d :: Text
    d -> Text -> Text
    Text.init Text
    marker Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> ": " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    d) [Text]
    contents)

    -- Escape the escape character, as well as formatting pairs
    escapeXWikiString :: Text -> Text
    escapeXWikiString :: Text -> Text
    escapeXWikiString s :: Text
    s = ((Text, Text) -> Text -> Text) -> Text -> [(Text, Text)] -> Text
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr ((Text -> Text -> Text -> Text) -> (Text, Text) -> Text -> Text
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry Text -> Text -> Text -> Text
    replace) Text
    s ([(Text, Text)] -> Text) -> [(Text, Text)] -> Text
    forall a b. (a -> b) -> a -> b
    $ [Text] -> [Text] -> [(Text, Text)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip ["--", "**", "//", "^^", ",,", "~"] ["~-~-", "~*~*", "~/~/", "~^~^", "~,~,", "~~"]