{-# LANGUAGE OverloadedStrings #-}
{- |
   Module      : Text.Pandoc.Writers.DokuWiki
   Copyright   : Copyright (C) 2008-2022 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 {}

instance Default WriterEnvironment where
  def :: WriterEnvironment
def = 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 :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> m Text
writeDokuWiki WriterOptions
opts Pandoc
document =
  forall (m :: * -> *) a. PandocMonad m => DokuWiki m a -> m a
runDokuWiki (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> DokuWiki m Text
pandocToDokuWiki WriterOptions
opts Pandoc
document)

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

-- | Return DokuWiki representation of document.
pandocToDokuWiki :: PandocMonad m
                 => WriterOptions -> Pandoc -> DokuWiki m Text
pandocToDokuWiki :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> DokuWiki m Text
pandocToDokuWiki WriterOptions
opts (Pandoc Meta
meta [Block]
blocks) = do
  Context Text
metadata <- forall (m :: * -> *) a.
(Monad m, TemplateTarget a) =>
WriterOptions
-> ([Block] -> m (Doc a))
-> ([Inline] -> m (Doc a))
-> Meta
-> m (Context a)
metaToContext WriterOptions
opts
              (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. HasChars a => a -> Doc a
literal forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
trimr) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
blockListToDokuWiki WriterOptions
opts)
              (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. HasChars a => a -> Doc a
literal forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
trimr) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> DokuWiki m Text
inlineListToDokuWiki WriterOptions
opts)
              Meta
meta
  Text
body <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
blockListToDokuWiki WriterOptions
opts [Block]
blocks
  let context :: Context Text
context = forall a b. ToContext a b => Text -> b -> Context a -> Context a
defField Text
"body" Text
body
              forall a b. (a -> b) -> a -> b
$ forall a b. ToContext a b => Text -> b -> Context a -> Context a
defField Text
"toc" (WriterOptions -> Bool
writerTableOfContents WriterOptions
opts) Context Text
metadata
  forall (m :: * -> *) a. Monad m => a -> m a
return 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 -> forall a. HasChars a => Maybe Int -> Doc a -> a
render forall a. Maybe a
Nothing forall a b. (a -> b) -> a -> b
$ 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
"%%__%%" forall b c a. (b -> c) -> (a -> b) -> a -> c
.
               Text -> Text -> Text -> Text
T.replace 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 :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> DokuWiki m Text
blockToDokuWiki WriterOptions
_ Block
Null = forall (m :: * -> *) a. Monad m => a -> m a
return Text
""

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

blockToDokuWiki WriterOptions
opts (Plain [Inline]
inlines) =
  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 forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Inline]
txt
              then forall (m :: * -> *) a. Monad m => a -> m a
return Text
""
              else (Text
" " forall a. Semigroup a => a -> a -> a
<>) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> DokuWiki m Text
inlineListToDokuWiki WriterOptions
opts [Inline]
txt
      let opt :: Text
opt = if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Inline]
txt
                then Text
""
                else Text
"|" forall a. Semigroup a => a -> a -> a
<> if Text -> Bool
T.null Text
tit then Text
capt else Text
tit forall a. Semigroup a => a -> a -> a
<> Text
capt
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"{{" forall a. Semigroup a => a -> a -> a
<> Text
src forall a. Semigroup a => a -> a -> a
<> WriterOptions -> Attr -> Text
imageDims WriterOptions
opts Attr
attr forall a. Semigroup a => a -> a -> a
<> Text
opt forall a. Semigroup a => a -> a -> a
<> Text
"}}\n"

blockToDokuWiki WriterOptions
opts (Para [Inline]
inlines) = do
  Text
indent <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Text
stIndent
  Bool
useTags <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Bool
stUseTags
  Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> DokuWiki m Text
inlineListToDokuWiki WriterOptions
opts [Inline]
inlines
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if Bool
useTags
              then Text
"<HTML><p></HTML>" forall a. Semigroup a => a -> a -> a
<> Text
contents forall a. Semigroup a => a -> a -> a
<> Text
"<HTML></p></HTML>"
              else Text
contents 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) =
  forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> DokuWiki m Text
blockToDokuWiki WriterOptions
opts forall a b. (a -> b) -> a -> b
$ [[Inline]] -> Block
linesToPara [[Inline]]
lns

blockToDokuWiki WriterOptions
_ b :: Block
b@(RawBlock Format
f Text
str)
  | Format
f forall a. Eq a => a -> a -> Bool
== Text -> Format
Format Text
"dokuwiki" = 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 forall a. Eq a => a -> a -> Bool
== Text -> Format
Format Text
"html"     = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"<HTML>\n" forall a. Semigroup a => a -> a -> a
<> Text
str forall a. Semigroup a => a -> a -> a
<> Text
"\n</HTML>"
  | Bool
otherwise              = Text
"" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$
         forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (Block -> LogMessage
BlockNotRendered Block
b)

blockToDokuWiki WriterOptions
_ Block
HorizontalRule = 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 <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> DokuWiki m Text
inlineListToDokuWiki WriterOptions
opts forall a b. (a -> b) -> a -> b
$ forall a. Walkable Inline a => a -> [Inline]
removeFormatting [Inline]
inlines
  let eqs :: Text
eqs = Int -> Text -> Text
T.replicate ( Int
7 forall a. Num a => a -> a -> a
- Int
level ) Text
"="
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
eqs forall a. Semigroup a => a -> a -> a
<> Text
" " forall a. Semigroup a => a -> a -> a
<> Text
contents forall a. Semigroup a => a -> a -> a
<> Text
" " forall a. Semigroup a => a -> a -> a
<> Text
eqs forall a. Semigroup a => a -> a -> a
<> Text
"\n"

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

blockToDokuWiki WriterOptions
opts (BlockQuote [Block]
blocks) = do
  Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
blockListToDokuWiki WriterOptions
opts [Block]
blocks
  if [Block] -> Bool
isSimpleBlockQuote [Block]
blocks
     then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.unlines forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (Text
"> " forall a. Semigroup a => a -> a -> a
<>) forall a b. (a -> b) -> a -> b
$ Text -> [Text]
T.lines Text
contents
     else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"<HTML><blockquote>\n" forall a. Semigroup a => a -> a -> a
<> Text
contents 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 forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Inline]
capt
                   then forall (m :: * -> *) a. Monad m => a -> m a
return Text
""
                   else do
                      Text
c <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> DokuWiki m Text
inlineListToDokuWiki WriterOptions
opts [Inline]
capt
                      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"" forall a. Semigroup a => a -> a -> a
<> Text
c forall a. Semigroup a => a -> a -> a
<> Text
"\n"
  [Text]
headers' <- if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Block]]
headers
                 then forall (m :: * -> *) a. Monad m => a -> m a
return []
                 else forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Alignment -> [Block] -> DokuWiki m Text
tableItemToDokuWiki WriterOptions
opts) [Alignment]
aligns [[Block]]
headers
  [[Text]]
rows' <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Alignment -> [Block] -> DokuWiki m Text
tableItemToDokuWiki WriterOptions
opts) [Alignment]
aligns) [[[Block]]]
rows
  let widths :: [Int]
widths = forall a b. (a -> b) -> [a] -> [b]
map (forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> Maybe (NonEmpty a)
nonEmpty forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Text -> Int
T.length)
                   forall a b. (a -> b) -> a -> b
$ forall a. [[a]] -> [[a]]
transpose ([Text]
headers'forall a. a -> [a] -> [a]
:[[Text]]
rows')
  let padTo :: (Int, Alignment) -> Text -> Text
padTo (Int
width, Alignment
al) Text
s =
          case Int
width forall a. Num a => a -> a -> a
- Text -> Int
T.length Text
s of
               Int
x | Int
x forall a. Ord a => a -> a -> Bool
> Int
0 ->
                 if Alignment
al forall a. Eq a => a -> a -> Bool
== Alignment
AlignLeft Bool -> Bool -> Bool
|| Alignment
al forall a. Eq a => a -> a -> Bool
== Alignment
AlignDefault
                    then Text
s forall a. Semigroup a => a -> a -> a
<> Int -> Text -> Text
T.replicate Int
x Text
" "
                    else if Alignment
al forall a. Eq a => a -> a -> Bool
== Alignment
AlignRight
                            then Int -> Text -> Text
T.replicate Int
x Text
" " forall a. Semigroup a => a -> a -> a
<> Text
s
                            else Int -> Text -> Text
T.replicate (Int
x forall a. Integral a => a -> a -> a
`div` Int
2) Text
" " forall a. Semigroup a => a -> a -> a
<>
                                 Text
s forall a. Semigroup a => a -> a -> a
<> Int -> Text -> Text
T.replicate (Int
x forall a. Num a => a -> a -> a
- Int
x 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 forall a. Semigroup a => a -> a -> a
<>
          Text -> [Text] -> Text
T.intercalate Text
sep (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Int, Alignment) -> Text -> Text
padTo (forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
widths [Alignment]
aligns) [Text]
cells) forall a. Semigroup a => a -> a -> a
<> Text
sep
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
captionDoc forall a. Semigroup a => a -> a -> a
<>
           (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
headers' then Text
"" else Text -> [Text] -> Text
renderRow Text
"^" [Text]
headers' forall a. Semigroup a => a -> a -> a
<> Text
"\n") forall a. Semigroup a => a -> a -> a
<>
           [Text] -> Text
T.unlines (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 <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Bool
stUseTags
  Text
indent <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Text
stIndent
  Bool
backSlash <- 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 <- forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (\WriterEnvironment
s -> WriterEnvironment
s { stUseTags :: Bool
stUseTags = Bool
True })
                      (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
listItemToDokuWiki WriterOptions
opts) [[Block]]
items)
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"<HTML><ul></HTML>\n" forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
vcat [Text]
contents forall a. Semigroup a => a -> a -> a
<> Text
"<HTML></ul></HTML>\n"
     else do
        [Text]
contents <- 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 forall a. Semigroup a => a -> a -> a
<> Text
"  "
                                   , stBackSlashLB :: Bool
stBackSlashLB = Bool
backSlash})
                      (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
listItemToDokuWiki WriterOptions
opts) [[Block]]
items)
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Text] -> Text
vcat [Text]
contents 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 <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Bool
stUseTags
  Text
indent <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Text
stIndent
  Bool
backSlash <- 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 <- forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (\WriterEnvironment
s -> WriterEnvironment
s { stUseTags :: Bool
stUseTags = Bool
True })
                      (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
orderedListItemToDokuWiki WriterOptions
opts) [[Block]]
items)
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"<HTML><ol" forall a. Semigroup a => a -> a -> a
<> ListAttributes -> Text
listAttribsToString ListAttributes
attribs forall a. Semigroup a => a -> a -> a
<> Text
"></HTML>\n" forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
vcat [Text]
contents forall a. Semigroup a => a -> a -> a
<> Text
"<HTML></ol></HTML>\n"
     else do
        [Text]
contents <- 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 forall a. Semigroup a => a -> a -> a
<> Text
"  "
                                   , stBackSlashLB :: Bool
stBackSlashLB = Bool
backSlash})
                      (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
orderedListItemToDokuWiki WriterOptions
opts) [[Block]]
items)
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Text] -> Text
vcat [Text]
contents 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 <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Bool
stUseTags
  Text
indent <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Text
stIndent
  Bool
backSlash <- 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 <- forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (\WriterEnvironment
s -> WriterEnvironment
s { stUseTags :: Bool
stUseTags = Bool
True })
                      (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> ([Inline], [[Block]]) -> DokuWiki m Text
definitionListItemToDokuWiki WriterOptions
opts) [([Inline], [[Block]])]
items)
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"<HTML><dl></HTML>\n" forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
vcat [Text]
contents forall a. Semigroup a => a -> a -> a
<> Text
"<HTML></dl></HTML>\n"
     else do
        [Text]
contents <- 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 forall a. Semigroup a => a -> a -> a
<> Text
"  "
                                   , stBackSlashLB :: Bool
stBackSlashLB = Bool
backSlash})
                      (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> ([Inline], [[Block]]) -> DokuWiki m Text
definitionListItemToDokuWiki WriterOptions
opts) [([Inline], [[Block]])]
items)
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Text] -> Text
vcat [Text]
contents 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 forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> Text
tshow ListNumberStyle
numstyle
  in  (if Int
startnum forall a. Eq a => a -> a -> Bool
/= Int
1
          then Text
" start=\"" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
tshow Int
startnum forall a. Semigroup a => a -> a -> a
<> Text
"\""
          else Text
"") forall a. Semigroup a => a -> a -> a
<>
      (if ListNumberStyle
numstyle forall a. Eq a => a -> a -> Bool
/= ListNumberStyle
DefaultStyle
          then Text
" style=\"list-style-type: " forall a. Semigroup a => a -> a -> a
<> Text
numstyle' 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 :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
listItemToDokuWiki WriterOptions
opts [Block]
items = do
  Bool
useTags <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Bool
stUseTags
  if Bool
useTags
     then do
       Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
blockListToDokuWiki WriterOptions
opts [Block]
items
       forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"<HTML><li></HTML>" forall a. Semigroup a => a -> a -> a
<> Text
contents forall a. Semigroup a => a -> a -> a
<> Text
"<HTML></li></HTML>"
     else do
       [Text]
bs <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (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 <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Text
stIndent
       Bool
backSlash <- 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
       forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
indent' forall a. Semigroup a => a -> a -> a
<> 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 :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
orderedListItemToDokuWiki WriterOptions
opts [Block]
items = do
  Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
blockListToDokuWiki WriterOptions
opts [Block]
items
  Bool
useTags <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Bool
stUseTags
  if Bool
useTags
     then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"<HTML><li></HTML>" forall a. Semigroup a => a -> a -> a
<> Text
contents forall a. Semigroup a => a -> a -> a
<> Text
"<HTML></li></HTML>"
     else do
       Text
indent <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Text
stIndent
       Bool
backSlash <- 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
       forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
indent' forall a. Semigroup a => a -> a -> a
<> 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 :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> ([Inline], [[Block]]) -> DokuWiki m Text
definitionListItemToDokuWiki WriterOptions
opts ([Inline]
label, [[Block]]
items) = do
  Text
labelText <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> DokuWiki m Text
inlineListToDokuWiki WriterOptions
opts [Inline]
label
  [Text]
contents <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
blockListToDokuWiki WriterOptions
opts) [[Block]]
items
  Bool
useTags <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Bool
stUseTags
  if Bool
useTags
     then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"<HTML><dt></HTML>" forall a. Semigroup a => a -> a -> a
<> Text
labelText forall a. Semigroup a => a -> a -> a
<> Text
"<HTML></dt></HTML>\n" forall a. Semigroup a => a -> a -> a
<>
           Text -> [Text] -> Text
T.intercalate Text
"\n" (forall a b. (a -> b) -> [a] -> [b]
map (\Text
d -> Text
"<HTML><dd></HTML>" forall a. Semigroup a => a -> a -> a
<> Text
d forall a. Semigroup a => a -> a -> a
<> Text
"<HTML></dd></HTML>") [Text]
contents)
     else do
       Text
indent <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Text
stIndent
       Bool
backSlash <- 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
       forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
indent' forall a. Semigroup a => a -> a -> a
<> Text
"* **" forall a. Semigroup a => a -> a -> a
<> Text
labelText forall a. Semigroup a => a -> a -> a
<> 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            -> forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all [Block] -> Bool
isSimpleListItem [[Block]]
items
       OrderedList (Int
1, ListNumberStyle
_, ListNumberDelim
_) [[Block]]
items -> forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all [Block] -> Bool
isSimpleListItem [[Block]]
items
       DefinitionList [([Inline], [[Block]])]
items        -> forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all [Block] -> Bool
isSimpleListItem forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = 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  = 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 forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
escape 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
"\\\\ " forall a. Semigroup a => a -> a -> a
<> String -> String
escape String
cs
    escape (Char
c:String
cs)    = Char
c 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 :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Alignment -> [Block] -> DokuWiki m Text
tableItemToDokuWiki WriterOptions
opts Alignment
align' [Block]
item = do
  let mkcell :: a -> a
mkcell a
x = (if Alignment
align' forall a. Eq a => a -> a -> Bool
== Alignment
AlignRight Bool -> Bool -> Bool
|| Alignment
align' forall a. Eq a => a -> a -> Bool
== Alignment
AlignCenter
                     then a
"  "
                     else a
"") forall a. Semigroup a => a -> a -> a
<> a
x forall a. Semigroup a => a -> a -> a
<>
                 (if Alignment
align' forall a. Eq a => a -> a -> Bool
== Alignment
AlignLeft Bool -> Bool -> Bool
|| Alignment
align' forall a. Eq a => a -> a -> Bool
== Alignment
AlignCenter
                     then a
"  "
                     else a
"")
  Text
contents <- forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (\WriterEnvironment
s -> WriterEnvironment
s { stBackSlashLB :: Bool
stBackSlashLB = Bool
True }) forall a b. (a -> b) -> a -> b
$
              forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
blockListToDokuWiki WriterOptions
opts [Block]
item
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ 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 :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
blockListToDokuWiki WriterOptions
opts [Block]
blocks = do
  Bool
backSlash <- 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 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> DokuWiki m Text
blockToDokuWiki WriterOptions
opts) [Block]
blocks'
    else [Text] -> Text
vcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (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 forall a. Eq a => a -> a -> Bool
== Format
f2 = [Block] -> [Block]
consolidateRawBlocks (Format -> Text -> Block
RawBlock Format
f1 (Text
b1 forall a. Semigroup a => a -> a -> a
<> Text
"\n" forall a. Semigroup a => a -> a -> a
<> Text
b2) forall a. a -> [a] -> [a]
: [Block]
xs)
consolidateRawBlocks (Block
x:[Block]
xs) = Block
x 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 :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> DokuWiki m Text
inlineListToDokuWiki WriterOptions
opts [Inline]
lst =
  [Text] -> Text
T.concat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (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 :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Inline -> DokuWiki m Text
inlineToDokuWiki WriterOptions
opts (Span Attr
_attrs [Inline]
ils) =
  forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> DokuWiki m Text
inlineListToDokuWiki WriterOptions
opts [Inline]
ils

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

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

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

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

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

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

inlineToDokuWiki WriterOptions
opts (SmallCaps [Inline]
lst) = 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 <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> DokuWiki m Text
inlineListToDokuWiki WriterOptions
opts [Inline]
lst
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"\8216" forall a. Semigroup a => a -> a -> a
<> Text
contents forall a. Semigroup a => a -> a -> a
<> Text
"\8217"

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

inlineToDokuWiki WriterOptions
opts (Cite [Citation]
_  [Inline]
lst) = 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.
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"''%%" forall a. Semigroup a => a -> a -> a
<> Text
str forall a. Semigroup a => a -> a -> a
<> Text
"%%''"

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

inlineToDokuWiki WriterOptions
_ (Math MathType
mathType Text
str) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
delim forall a. Semigroup a => a -> a -> a
<> Text
str 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 forall a. Eq a => a -> a -> Bool
== Text -> Format
Format Text
"dokuwiki" = forall (m :: * -> *) a. Monad m => a -> m a
return Text
str
  | Format
f forall a. Eq a => a -> a -> Bool
== Text -> Format
Format Text
"html"     = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"<html>" forall a. Semigroup a => a -> a -> a
<> Text
str forall a. Semigroup a => a -> a -> a
<> Text
"</html>"
  | Bool
otherwise              = Text
"" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (Inline -> LogMessage
InlineNotRendered Inline
il)

inlineToDokuWiki WriterOptions
_ Inline
LineBreak = do
  Bool
backSlash <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WriterEnvironment -> Bool
stBackSlashLB
  forall (m :: * -> *) a. Monad m => a -> m a
return 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     -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
" "
       WrapOption
WrapAuto     -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
" "
       WrapOption
WrapPreserve -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
"\n"

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

inlineToDokuWiki WriterOptions
opts (Link Attr
_ [Inline]
txt (Text
src, Text
_)) = do
  Text
label <- 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 -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"<" forall a. Semigroup a => a -> a -> a
<> Text
s forall a. Semigroup a => a -> a -> a
<> Text
">"
             | Text -> Text
escapeURI Text
s forall a. Eq a => a -> a -> Bool
== Text
src -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
src
     [Inline]
_  -> if Text -> Bool
isURI Text
src
              then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"[[" forall a. Semigroup a => a -> a -> a
<> Text
src  forall a. Semigroup a => a -> a -> a
<> Text
"|" forall a. Semigroup a => a -> a -> a
<> Text
label forall a. Semigroup a => a -> a -> a
<> Text
"]]"
              else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"[[" forall a. Semigroup a => a -> a -> a
<> Text
src' forall a. Semigroup a => a -> a -> a
<> Text
"|" forall a. Semigroup a => a -> a -> a
<> Text
label 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' <- 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
"|" forall a. Semigroup a => a -> a -> a
<> Text
alt'
              (Text
_ , [Inline]
_ ) -> Text
"|" forall a. Semigroup a => a -> a -> a
<> Text
tit
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"{{" forall a. Semigroup a => a -> a -> a
<> Text
source forall a. Semigroup a => a -> a -> a
<> WriterOptions -> Attr -> Text
imageDims WriterOptions
opts Attr
attr forall a. Semigroup a => a -> a -> a
<> Text
txt forall a. Semigroup a => a -> a -> a
<> Text
"}}"

inlineToDokuWiki WriterOptions
opts (Note [Block]
contents) = do
  Text
contents' <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> DokuWiki m Text
blockListToDokuWiki WriterOptions
opts [Block]
contents
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text
"((" forall a. Semigroup a => a -> a -> a
<> Text
contents' 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 = forall {a}. (Semigroup a, IsString a) => Maybe a -> Maybe a -> a
go (Maybe Dimension -> Maybe Text
toPx forall a b. (a -> b) -> a -> b
$ Direction -> Attr -> Maybe Dimension
dimension Direction
Width Attr
attr) (Maybe Dimension -> Maybe Text
toPx forall a b. (a -> b) -> a -> b
$ Direction -> Attr -> Maybe Dimension
dimension Direction
Height Attr
attr)
  where
    toPx :: Maybe Dimension -> Maybe Text
toPx = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (WriterOptions -> Dimension -> Text
showInPixel WriterOptions
opts) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Dimension -> Maybe Dimension
checkPct
    checkPct :: Maybe Dimension -> Maybe Dimension
checkPct (Just (Percent Double
_)) = 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
"?" forall a. Semigroup a => a -> a -> a
<> a
w
    go (Just a
w) (Just a
h) = a
"?" forall a. Semigroup a => a -> a -> a
<> a
w forall a. Semigroup a => a -> a -> a
<> a
"x" forall a. Semigroup a => a -> a -> a
<> a
h
    go Maybe a
Nothing  (Just a
h) = a
"?0x" 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 = 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")
  ]