{-# LANGUAGE OverloadedStrings #-}
{- |
   Module      : Text.Pandoc.Writers.DokuWiki
   Copyright   : Copyright (C) 2008-2021 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 (transpose)
import Data.List.NonEmpty (nonEmpty)
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, toLegacyTable)
import Data.Maybe (fromMaybe)
import qualified Data.Map as M

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 = Text
""
                          , 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 WriterOptions
opts 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 WriterOptions
opts (Pandoc Meta
meta [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 Text
"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 Text
"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
       Maybe (Template Text)
Nothing  -> Text
body
       Just 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) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
               Text -> Text -> Text -> Text
T.replace Text
"**" Text
"%%**%%" (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
               Text -> Text -> Text -> Text
T.replace Text
"//" Text
"%%//%%"

-- | Convert Pandoc block element to DokuWiki.
blockToDokuWiki :: PandocMonad m
                => WriterOptions -- ^ Options
                -> Block         -- ^ Block element
                -> DokuWiki m Text

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

blockToDokuWiki WriterOptions
opts (Div Attr
_attrs [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
<> Text
"\n"

blockToDokuWiki WriterOptions
opts (Plain [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 WriterOptions
opts (SimpleFigure Attr
attr [Inline]
txt (Text
src, Text
tit)) = 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 Text
""
              else (Text
" " 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 Text
""
                else Text
"|" 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 -> 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
<> Text
"}}\n"

blockToDokuWiki WriterOptions
opts (Para [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 Text
"<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
<> Text
"<HTML></p></HTML>"
              else Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> if Text -> Bool
T.null Text
indent then Text
"\n" else Text
""

blockToDokuWiki WriterOptions
opts (LineBlock [[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 WriterOptions
_ b :: Block
b@(RawBlock Format
f Text
str)
  | Format
f Format -> Format -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Format
Format Text
"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 Text
"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
$ Text
"<HTML>\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
str Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n</HTML>"
  | Bool
otherwise              = Text
"" 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 WriterOptions
_ Block
HorizontalRule = Text -> DokuWiki m Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
"\n----\n"

blockToDokuWiki WriterOptions
opts (Header Int
level Attr
_ [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 ( Int
7 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
level ) Text
"="
  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 -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
eqs Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n"

blockToDokuWiki WriterOptions
_ (CodeBlock (Text
_,[Text]
classes,[(Text, Text)]
_) 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
"<code" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
           (case [Text]
classes of
               []    -> Text
""
               (Text
x:[Text]
_) -> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
x (Text -> Map Text Text -> Maybe Text
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Text
x Map Text Text
languageNames)) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
           Text
">\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
str Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
           (if Text
"\n" Text -> Text -> Bool
`T.isSuffixOf` Text
str then Text
"" else Text
"\n") Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"</code>\n"

blockToDokuWiki WriterOptions
opts (BlockQuote [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 -> 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
$ Text
"<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
<> Text
"</blockquote></HTML>"

blockToDokuWiki WriterOptions
opts (Table Attr
_ Caption
blkCapt [ColSpec]
specs TableHead
thead [TableBody]
tbody TableFoot
tfoot) = do
  let ([Inline]
capt, [Alignment]
aligns, [Double]
_, [[Block]]
headers, [[[Block]]]
rows) = Caption
-> [ColSpec]
-> TableHead
-> [TableBody]
-> TableFoot
-> ([Inline], [Alignment], [Double], [[Block]], [[[Block]]])
toLegacyTable Caption
blkCapt [ColSpec]
specs TableHead
thead [TableBody]
tbody TableFoot
tfoot
  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 Text
""
                   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 -> Text
forall a. Semigroup a => a -> a -> a
<> Text
c Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\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 -> (NonEmpty Int -> Int) -> Maybe (NonEmpty Int) -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 NonEmpty Int -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (Maybe (NonEmpty Int) -> Int)
-> ([Text] -> Maybe (NonEmpty Int)) -> [Text] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> Maybe (NonEmpty Int)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty ([Int] -> Maybe (NonEmpty Int))
-> ([Text] -> [Int]) -> [Text] -> Maybe (NonEmpty 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 (Int
width, Alignment
al) Text
s =
          case Int
width Int -> Int -> Int
forall a. Num a => a -> a -> a
- Text -> Int
T.length Text
s of
               Int
x | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
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 Text
" "
                    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 -> 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` Int
2) Text
" " 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` Int
2) Text
" "
                 | Bool
otherwise -> Text
s
  let renderRow :: Text -> [Text] -> Text
renderRow Text
sep [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 Text
"" else Text -> [Text] -> Text
renderRow Text
"^" [Text]
headers' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\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
"|") [[Text]]
rows')

blockToDokuWiki WriterOptions
opts x :: Block
x@(BulletList [[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 (\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
$ Text
"<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
<> Text
"<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 (\WriterEnvironment
s -> WriterEnvironment
s { stIndent :: Text
stIndent = WriterEnvironment -> Text
stIndent WriterEnvironment
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"  "
                                   , 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 Text
"\n" else Text
""

blockToDokuWiki WriterOptions
opts x :: Block
x@(OrderedList ListAttributes
attribs [[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 (\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
$ Text
"<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
<> Text
"></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
<> Text
"<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 (\WriterEnvironment
s -> WriterEnvironment
s { stIndent :: Text
stIndent = WriterEnvironment -> Text
stIndent WriterEnvironment
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"  "
                                   , 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 Text
"\n" else Text
""

-- 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 WriterOptions
opts x :: Block
x@(DefinitionList [([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 (\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
$ Text
"<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
<> Text
"<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 (\WriterEnvironment
s -> WriterEnvironment
s { stIndent :: Text
stIndent = WriterEnvironment -> Text
stIndent WriterEnvironment
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"  "
                                   , 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 Text
"\n" else Text
""

-- Auxiliary functions for lists:

-- | Convert ordered list attributes to HTML attribute string
listAttribsToString :: ListAttributes -> Text
listAttribsToString :: ListAttributes -> Text
listAttribsToString (Int
startnum, ListNumberStyle
numstyle, ListNumberDelim
_) =
  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
/= Int
1
          then Text
" 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
<> Text
"\""
          else Text
"") 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 Text
" 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
<> Text
";\""
          else Text
"")

-- | Convert bullet list item (list of blocks) to DokuWiki.
listItemToDokuWiki :: PandocMonad m
                   => WriterOptions -> [Block] -> DokuWiki m Text
listItemToDokuWiki :: WriterOptions -> [Block] -> DokuWiki m Text
listItemToDokuWiki WriterOptions
opts [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
$ Text
"<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
<> Text
"<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
                           [Block
_, CodeBlock Attr
_ Text
_] -> [Text] -> Text
T.concat [Text]
bs
                           [Block]
_                  -> [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 Int
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 -> 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 WriterOptions
opts [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
$ Text
"<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
<> Text
"<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 Int
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 -> 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 WriterOptions
opts ([Inline]
label, [[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
$ Text
"<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
<> Text
"<HTML></dt></HTML>\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
           Text -> [Text] -> Text
T.intercalate Text
"\n" ((Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (\Text
d -> Text
"<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
<> Text
"<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 Int
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 -> Text
forall a. Semigroup a => a -> a -> a
<> Text
labelText Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"** " 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 Block
x =
  case Block
x of
       BulletList [[Block]]
items            -> ([Block] -> Bool) -> [[Block]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all [Block] -> Bool
isSimpleListItem [[Block]]
items
       OrderedList (Int
1, ListNumberStyle
_, ListNumberDelim
_) [[Block]]
items -> ([Block] -> Bool) -> [[Block]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all [Block] -> Bool
isSimpleListItem [[Block]]
items
       DefinitionList [([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
       Block
_                           -> 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 [Block
x, CodeBlock{}] | Block -> Bool
isPlainOrPara Block
x = Bool
True
isSimpleListItem (Block
x:[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 [Block]
_ = Bool
False

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

isSimpleBlockQuote :: [Block] -> Bool
isSimpleBlockQuote :: [Block] -> Bool
isSimpleBlockQuote [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 Text
"\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 [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 Text
"\\\\ \\\\ " -- simulate paragraphs.
    escape :: String -> String
escape [Char
'\n']    = String
"" -- remove trailing newlines
    escape (Char
'\n':String
cs) = String
"\\\\ " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String -> String
escape String
cs
    escape (Char
c: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 WriterOptions
opts Alignment
align' [Block]
item = do
  let mkcell :: a -> a
mkcell 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 a
"  "
                     else a
"") 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 a
"  "
                     else a
"")
  Text
contents <- (WriterEnvironment -> WriterEnvironment)
-> DokuWiki m Text -> DokuWiki m Text
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (\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 WriterOptions
opts [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 Format
f1 Text
b1 : RawBlock Format
f2 Text
b2 : [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
<> Text
"\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
b2) Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block]
xs)
consolidateRawBlocks (Block
x:[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 WriterOptions
opts [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 WriterOptions
opts (Span Attr
_attrs [Inline]
ils) =
  WriterOptions -> [Inline] -> DokuWiki m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> DokuWiki m Text
inlineListToDokuWiki WriterOptions
opts [Inline]
ils

inlineToDokuWiki WriterOptions
opts (Emph [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 -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"//"

inlineToDokuWiki WriterOptions
opts (Underline [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 -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"__"

inlineToDokuWiki WriterOptions
opts (Strong [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 -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"**"

inlineToDokuWiki WriterOptions
opts (Strikeout [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
"<del>" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"</del>"

inlineToDokuWiki WriterOptions
opts (Superscript [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
"<sup>" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"</sup>"

inlineToDokuWiki WriterOptions
opts (Subscript [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
"<sub>" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"</sub>"

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

inlineToDokuWiki WriterOptions
opts (Quoted QuoteType
SingleQuote [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
"\8216" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\8217"

inlineToDokuWiki WriterOptions
opts (Quoted QuoteType
DoubleQuote [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
"\8220" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\8221"

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

inlineToDokuWiki WriterOptions
_ (Code Attr
_ 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 -> Text
forall a. Semigroup a => a -> a -> a
<> Text
str Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"%%''"

inlineToDokuWiki WriterOptions
_ (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 WriterOptions
_ (Math MathType
mathType 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
                     MathType
DisplayMath -> Text
"$$"
                     MathType
InlineMath  -> Text
"$"

inlineToDokuWiki WriterOptions
_ il :: Inline
il@(RawInline Format
f Text
str)
  | Format
f Format -> Format -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Format
Format Text
"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 Text
"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
$ Text
"<html>" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
str Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"</html>"
  | Bool
otherwise              = Text
"" 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 WriterOptions
_ Inline
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 Text
"\n"
           else Text
"\\\\\n"

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

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

inlineToDokuWiki WriterOptions
opts (Link Attr
_ [Inline]
txt (Text
src, Text
_)) = 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 Text
s] | Text
"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 -> Text
forall a. Semigroup a => a -> a -> a
<> Text
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
">"
             | 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
     [Inline]
_  -> 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 -> Text
forall a. Semigroup a => a -> a -> a
<> Text
src  Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"|" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
label Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"]]"
              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 -> Text
forall a. Semigroup a => a -> a -> a
<> Text
src' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"|" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
label Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"]]"
                     where src' :: Text
src' = case Text -> Maybe (Char, Text)
T.uncons Text
src of
                                     Just (Char
'/',Text
xs) -> Text
xs  -- with leading / it's a
                                     Maybe (Char, Text)
_             -> Text
src -- link to a help page
inlineToDokuWiki WriterOptions
opts (Image Attr
attr [Inline]
alt (Text
source, 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
"", [Inline]
_ ) -> Text
"|" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
alt'
              (Text
_ , [Inline]
_ ) -> Text
"|" 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 -> 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
<> Text
"}}"

inlineToDokuWiki WriterOptions
opts (Note [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 -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"))"
  -- note - may not work for notes with multiple blocks

imageDims :: WriterOptions -> Attr -> Text
imageDims :: WriterOptions -> Attr -> Text
imageDims WriterOptions
opts 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 Double
_)) = Maybe Dimension
forall a. Maybe a
Nothing
    checkPct Maybe Dimension
maybeDim           = Maybe Dimension
maybeDim
    go :: Maybe a -> Maybe a -> a
go (Just a
w) Maybe a
Nothing  = a
"?" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
w
    go (Just a
w) (Just a
h) = a
"?" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
w a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
"x" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
h
    go Maybe a
Nothing  (Just a
h) = a
"?0x" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
h
    go Maybe a
Nothing  Maybe a
Nothing  = a
""

languageNames :: M.Map Text Text
languageNames :: Map Text Text
languageNames = [(Text, Text)] -> Map Text Text
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList
  [(Text
"cs", Text
"csharp")
  ,(Text
"coffee", Text
"cofeescript")
  ,(Text
"commonlisp", Text
"lisp")
  ,(Text
"gcc", Text
"c")
  ,(Text
"html", Text
"html5")
  ,(Text
"makefile", Text
"make")
  ,(Text
"objectivec", Text
"objc")
  ,(Text
"r", Text
"rsplus")
  ,(Text
"sqlmysql", Text
"mysql")
  ,(Text
"sqlpostgresql", Text
"postgresql")
  ,(Text
"sci", Text
"scilab")
  ,(Text
"xorg", Text
"xorgconf")
  ]