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

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

Conversion of 'Pandoc' documents to ZimWiki markup.

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

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

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

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

type ZW = StateT WriterState

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

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

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

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

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

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

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

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

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

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

blockToZimWiki opts :: WriterOptions
opts b :: Block
b@(RawBlock f :: Format
f str :: Text
str)
  | Format
f Format -> Format -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Format
Format "zimwiki"  = Text -> ZW m Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
str
  | Format
f Format -> Format -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Format
Format "html"     = WriterOptions -> Text -> ZW m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Text -> ZW m Text
indentFromHTML WriterOptions
opts Text
str
  | Bool
otherwise              = do
      LogMessage -> StateT WriterState m ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (LogMessage -> StateT WriterState m ())
-> LogMessage -> StateT WriterState m ()
forall a b. (a -> b) -> a -> b
$ Block -> LogMessage
BlockNotRendered Block
b
      Text -> ZW m Text
forall (m :: * -> *) a. Monad m => a -> m a
return ""

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

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

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

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

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

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

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

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

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

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

countSubStrs :: Text -> Text -> Int
countSubStrs :: Text -> Text -> Int
countSubStrs sub :: Text
sub str :: Text
str = [(Text, Text)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([(Text, Text)] -> Int) -> [(Text, Text)] -> Int
forall a b. (a -> b) -> a -> b
$ Text -> Text -> [(Text, Text)]
T.breakOnAll Text
sub Text
str

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-- f == Format "html"     = return $ "<html>" <> str <> "</html>"
inlineToZimWiki opts :: WriterOptions
opts il :: Inline
il@(RawInline f :: Format
f str :: Text
str)
  | Format
f Format -> Format -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Format
Format "zimwiki" = Text -> ZW m Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
str
  | Format
f Format -> Format -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Format
Format "html"    = WriterOptions -> Text -> ZW m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Text -> ZW m Text
indentFromHTML WriterOptions
opts Text
str
  | Bool
otherwise             = do
      LogMessage -> StateT WriterState m ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (LogMessage -> StateT WriterState m ())
-> LogMessage -> StateT WriterState m ()
forall a b. (a -> b) -> a -> b
$ Inline -> LogMessage
InlineNotRendered Inline
il
      Text -> ZW m Text
forall (m :: * -> *) a. Monad m => a -> m a
return ""

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

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

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

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

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

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

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