summaryrefslogtreecommitdiff
path: root/src/Text/Pandoc/Writers/DokuWiki.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Text/Pandoc/Writers/DokuWiki.hs')
-rw-r--r--src/Text/Pandoc/Writers/DokuWiki.hs169
1 files changed, 91 insertions, 78 deletions
diff --git a/src/Text/Pandoc/Writers/DokuWiki.hs b/src/Text/Pandoc/Writers/DokuWiki.hs
index 7459f1b42..dda21d23d 100644
--- a/src/Text/Pandoc/Writers/DokuWiki.hs
+++ b/src/Text/Pandoc/Writers/DokuWiki.hs
@@ -1,5 +1,5 @@
{-
-Copyright (C) 2008-2015 John MacFarlane <jgm@berkeley.edu>
+Copyright (C) 2008-2018 John MacFarlane <jgm@berkeley.edu>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
{- |
Module : Text.Pandoc.Writers.DokuWiki
- Copyright : Copyright (C) 2008-2015 John MacFarlane
+ Copyright : Copyright (C) 2008-2018 John MacFarlane
License : GNU GPL, version 2 or above
Maintainer : Clare Macrae <clare.macrae@googlemail.com>
@@ -39,71 +39,64 @@ DokuWiki: <https://www.dokuwiki.org/dokuwiki>
-}
module Text.Pandoc.Writers.DokuWiki ( writeDokuWiki ) where
+import Control.Monad (zipWithM)
+import Control.Monad.Reader (ReaderT, ask, local, runReaderT)
+import Control.Monad.State.Strict (StateT, evalStateT)
+import Data.Default (Default (..))
+import Data.List (intercalate, intersect, isPrefixOf, transpose)
+import Data.Text (Text, pack)
+import Text.Pandoc.Class (PandocMonad, report)
import Text.Pandoc.Definition
-import Text.Pandoc.Options ( WriterOptions(
- writerTableOfContents
- , writerTemplate
- , writerWrapText), WrapOption(..) )
-import Text.Pandoc.Shared ( escapeURI, linesToPara, removeFormatting
- , camelCaseToHyphenated, trimr, normalize, substitute )
-import Text.Pandoc.Writers.Shared ( defField, metaToJSON )
import Text.Pandoc.ImageSize
-import Text.Pandoc.Templates ( renderTemplate' )
-import Data.List ( intersect, intercalate, isPrefixOf, transpose )
-import Data.Default (Default(..))
-import Network.URI ( isURI )
-import Control.Monad ( zipWithM )
-import Control.Monad.State ( modify, State, get, evalState )
-import Control.Monad.Reader ( ReaderT, runReaderT, ask, local )
+import Text.Pandoc.Logging
+import Text.Pandoc.Options (WrapOption (..), WriterOptions (writerTableOfContents, writerTemplate, writerWrapText))
+import Text.Pandoc.Shared (camelCaseToHyphenated, escapeURI, isURI, linesToPara,
+ removeFormatting, substitute, trimr)
+import Text.Pandoc.Templates (renderTemplate')
+import Text.Pandoc.Writers.Shared (defField, metaToJSON)
data WriterState = WriterState {
- stNotes :: Bool -- True if there are notes
}
data WriterEnvironment = WriterEnvironment {
- stIndent :: String -- Indent after the marker at the beginning of list items
- , stUseTags :: Bool -- True if we should use HTML tags because we're in a complex list
+ stIndent :: String -- Indent after the marker at the beginning of list items
+ , stUseTags :: Bool -- True if we should use HTML tags because we're in a complex list
, stBackSlashLB :: Bool -- True if we should produce formatted strings with newlines (as in a table cell)
}
instance Default WriterState where
- def = WriterState { stNotes = False }
+ def = WriterState {}
instance Default WriterEnvironment where
def = WriterEnvironment { stIndent = ""
, stUseTags = False
, stBackSlashLB = False }
-type DokuWiki = ReaderT WriterEnvironment (State WriterState)
+type DokuWiki m = ReaderT WriterEnvironment (StateT WriterState m)
-- | Convert Pandoc to DokuWiki.
-writeDokuWiki :: WriterOptions -> Pandoc -> String
+writeDokuWiki :: PandocMonad m => WriterOptions -> Pandoc -> m Text
writeDokuWiki opts document =
- runDokuWiki (pandocToDokuWiki opts $ normalize document)
+ runDokuWiki (pandocToDokuWiki opts document)
-runDokuWiki :: DokuWiki a -> a
-runDokuWiki = flip evalState def . flip runReaderT def
+runDokuWiki :: PandocMonad m => DokuWiki m a -> m a
+runDokuWiki = flip evalStateT def . flip runReaderT def
-- | Return DokuWiki representation of document.
-pandocToDokuWiki :: WriterOptions -> Pandoc -> DokuWiki String
+pandocToDokuWiki :: PandocMonad m
+ => WriterOptions -> Pandoc -> DokuWiki m Text
pandocToDokuWiki opts (Pandoc meta blocks) = do
metadata <- metaToJSON opts
(fmap trimr . blockListToDokuWiki opts)
(inlineListToDokuWiki opts)
meta
body <- blockListToDokuWiki opts blocks
- notesExist <- stNotes <$> get
- let notes = if notesExist
- then "" -- TODO Was "\n<references />" Check whether I can really remove this:
- -- if it is definitely to do with footnotes, can remove this whole bit
- else ""
- let main = body ++ notes
+ let main = pack body
let context = defField "body" main
- $ defField "toc" (writerTableOfContents opts)
- $ metadata
+ $ defField "toc" (writerTableOfContents opts) metadata
case writerTemplate opts of
Nothing -> return main
- Just tpl -> return $ renderTemplate' tpl context
+ Just tpl -> renderTemplate' tpl context
-- | Escape special characters for DokuWiki.
escapeString :: String -> String
@@ -112,9 +105,10 @@ escapeString = substitute "__" "%%__%%" .
substitute "//" "%%//%%"
-- | Convert Pandoc block element to DokuWiki.
-blockToDokuWiki :: WriterOptions -- ^ Options
+blockToDokuWiki :: PandocMonad m
+ => WriterOptions -- ^ Options
-> Block -- ^ Block element
- -> DokuWiki String
+ -> DokuWiki m String
blockToDokuWiki _ Null = return ""
@@ -149,12 +143,13 @@ blockToDokuWiki opts (Para inlines) = do
blockToDokuWiki opts (LineBlock lns) =
blockToDokuWiki opts $ linesToPara lns
-blockToDokuWiki _ (RawBlock f str)
+blockToDokuWiki _ b@(RawBlock f str)
| f == Format "dokuwiki" = return str
-- See https://www.dokuwiki.org/wiki:syntax
-- use uppercase HTML tag for block-level content:
| f == Format "html" = return $ "<HTML>\n" ++ str ++ "\n</HTML>"
- | otherwise = return ""
+ | otherwise = "" <$
+ report (BlockNotRendered b)
blockToDokuWiki _ HorizontalRule = return "\n----\n"
@@ -177,7 +172,7 @@ blockToDokuWiki _ (CodeBlock (_,classes,_) str) = do
"visualfoxpro", "winbatch", "xml", "xpp", "z80"]
return $ "<code" ++
(case at of
- [] -> ">\n"
+ [] -> ">\n"
(x:_) -> " " ++ x ++ ">\n") ++ str ++ "\n</code>"
blockToDokuWiki opts (BlockQuote blocks) = do
@@ -198,7 +193,7 @@ blockToDokuWiki opts (Table capt aligns _ headers rows) = do
rows' <- mapM (zipWithM (tableItemToDokuWiki opts) aligns) rows
let widths = map (maximum . map length) $ transpose (headers':rows')
let padTo (width, al) s =
- case (width - length s) of
+ case width - length s of
x | x > 0 ->
if al == AlignLeft || al == AlignDefault
then s ++ replicate x ' '
@@ -278,21 +273,27 @@ listAttribsToString (startnum, numstyle, _) =
else "")
-- | Convert bullet list item (list of blocks) to DokuWiki.
-listItemToDokuWiki :: WriterOptions -> [Block] -> DokuWiki String
+listItemToDokuWiki :: PandocMonad m
+ => WriterOptions -> [Block] -> DokuWiki m String
listItemToDokuWiki opts items = do
- contents <- blockListToDokuWiki opts items
useTags <- stUseTags <$> ask
if useTags
- then return $ "<HTML><li></HTML>" ++ contents ++ "<HTML></li></HTML>"
+ then do
+ contents <- blockListToDokuWiki opts items
+ return $ "<HTML><li></HTML>" ++ contents ++ "<HTML></li></HTML>"
else do
+ bs <- mapM (blockToDokuWiki opts) items
+ let contents = case items of
+ [_, CodeBlock _ _] -> concat bs
+ _ -> vcat bs
indent <- stIndent <$> ask
backSlash <- stBackSlashLB <$> ask
- let indent' = if backSlash then (drop 2 indent) else indent
+ let indent' = if backSlash then drop 2 indent else indent
return $ indent' ++ "* " ++ contents
-- | Convert ordered list item (list of blocks) to DokuWiki.
-- | TODO Emiminate dreadful duplication of text from listItemToDokuWiki
-orderedListItemToDokuWiki :: WriterOptions -> [Block] -> DokuWiki String
+orderedListItemToDokuWiki :: PandocMonad m => WriterOptions -> [Block] -> DokuWiki m String
orderedListItemToDokuWiki opts items = do
contents <- blockListToDokuWiki opts items
useTags <- stUseTags <$> ask
@@ -301,24 +302,25 @@ orderedListItemToDokuWiki opts items = do
else do
indent <- stIndent <$> ask
backSlash <- stBackSlashLB <$> ask
- let indent' = if backSlash then (drop 2 indent) else indent
+ let indent' = if backSlash then drop 2 indent else indent
return $ indent' ++ "- " ++ contents
-- | Convert definition list item (label, list of blocks) to DokuWiki.
-definitionListItemToDokuWiki :: WriterOptions
+definitionListItemToDokuWiki :: PandocMonad m
+ => WriterOptions
-> ([Inline],[[Block]])
- -> DokuWiki String
+ -> DokuWiki m String
definitionListItemToDokuWiki opts (label, items) = do
labelText <- inlineListToDokuWiki opts label
contents <- mapM (blockListToDokuWiki opts) items
useTags <- stUseTags <$> ask
if useTags
then return $ "<HTML><dt></HTML>" ++ labelText ++ "<HTML></dt></HTML>\n" ++
- (intercalate "\n" $ map (\d -> "<HTML><dd></HTML>" ++ d ++ "<HTML></dd></HTML>") contents)
+ intercalate "\n" (map (\d -> "<HTML><dd></HTML>" ++ d ++ "<HTML></dd></HTML>") contents)
else do
indent <- stIndent <$> ask
backSlash <- stBackSlashLB <$> ask
- let indent' = if backSlash then (drop 2 indent) else indent
+ let indent' = if backSlash then drop 2 indent else indent
return $ indent' ++ "* **" ++ labelText ++ "** " ++ concat contents
-- | True if the list can be handled by simple wiki markup, False if HTML tags will be needed.
@@ -337,18 +339,19 @@ isSimpleListItem :: [Block] -> Bool
isSimpleListItem [] = True
isSimpleListItem [x] =
case x of
- Plain _ -> True
- Para _ -> True
- BulletList _ -> isSimpleList x
- OrderedList _ _ -> isSimpleList x
- DefinitionList _ -> isSimpleList x
- _ -> False
+ Plain _ -> True
+ Para _ -> True
+ BulletList _ -> isSimpleList x
+ OrderedList _ _ -> isSimpleList x
+ DefinitionList _ -> isSimpleList x
+ _ -> False
isSimpleListItem [x, y] | isPlainOrPara x =
case y of
- BulletList _ -> isSimpleList y
- OrderedList _ _ -> isSimpleList y
- DefinitionList _ -> isSimpleList y
- _ -> False
+ BulletList _ -> isSimpleList y
+ OrderedList _ _ -> isSimpleList y
+ DefinitionList _ -> isSimpleList y
+ CodeBlock _ _ -> True
+ _ -> False
isSimpleListItem _ = False
isPlainOrPara :: Block -> Bool
@@ -368,14 +371,15 @@ backSlashLineBreaks cs = reverse $ g $ reverse $ concatMap f cs
where f '\n' = "\\\\ "
f c = [c]
g (' ' : '\\':'\\': xs) = xs
- g s = s
+ g s = s
-- Auxiliary functions for tables:
-tableItemToDokuWiki :: WriterOptions
- -> Alignment
- -> [Block]
- -> DokuWiki String
+tableItemToDokuWiki :: PandocMonad m
+ => WriterOptions
+ -> Alignment
+ -> [Block]
+ -> DokuWiki m String
tableItemToDokuWiki opts align' item = do
let mkcell x = (if align' == AlignRight || align' == AlignCenter
then " "
@@ -388,22 +392,32 @@ tableItemToDokuWiki opts align' item = do
return $ mkcell contents
-- | Convert list of Pandoc block elements to DokuWiki.
-blockListToDokuWiki :: WriterOptions -- ^ Options
+blockListToDokuWiki :: PandocMonad m
+ => WriterOptions -- ^ Options
-> [Block] -- ^ List of block elements
- -> DokuWiki String
+ -> DokuWiki m String
blockListToDokuWiki opts blocks = do
backSlash <- stBackSlashLB <$> ask
+ let blocks' = consolidateRawBlocks blocks
if backSlash
- then (backSlashLineBreaks . vcat) <$> mapM (blockToDokuWiki opts) blocks
- else vcat <$> mapM (blockToDokuWiki opts) blocks
+ then (backSlashLineBreaks . vcat) <$> mapM (blockToDokuWiki opts) blocks'
+ else vcat <$> mapM (blockToDokuWiki opts) blocks'
+
+consolidateRawBlocks :: [Block] -> [Block]
+consolidateRawBlocks [] = []
+consolidateRawBlocks (RawBlock f1 b1 : RawBlock f2 b2 : xs)
+ | f1 == f2 = consolidateRawBlocks (RawBlock f1 (b1 ++ "\n" ++ b2) : xs)
+consolidateRawBlocks (x:xs) = x : consolidateRawBlocks xs
-- | Convert list of Pandoc inline elements to DokuWiki.
-inlineListToDokuWiki :: WriterOptions -> [Inline] -> DokuWiki String
+inlineListToDokuWiki :: PandocMonad m
+ => WriterOptions -> [Inline] -> DokuWiki m String
inlineListToDokuWiki opts lst =
- concat <$> (mapM (inlineToDokuWiki opts) lst)
+ concat <$> mapM (inlineToDokuWiki opts) lst
-- | Convert Pandoc inline element to DokuWiki.
-inlineToDokuWiki :: WriterOptions -> Inline -> DokuWiki String
+inlineToDokuWiki :: PandocMonad m
+ => WriterOptions -> Inline -> DokuWiki m String
inlineToDokuWiki opts (Span _attrs ils) =
inlineListToDokuWiki opts ils
@@ -460,12 +474,12 @@ inlineToDokuWiki _ (Math mathType str) = return $ delim ++ str ++ delim
DisplayMath -> "$$"
InlineMath -> "$"
-inlineToDokuWiki _ (RawInline f str)
+inlineToDokuWiki _ il@(RawInline f str)
| f == Format "dokuwiki" = return str
| f == Format "html" = return $ "<html>" ++ str ++ "</html>"
- | otherwise = return ""
+ | otherwise = "" <$ report (InlineNotRendered il)
-inlineToDokuWiki _ (LineBreak) = return "\\\\\n"
+inlineToDokuWiki _ LineBreak = return "\\\\\n"
inlineToDokuWiki opts SoftBreak =
case writerWrapText opts of
@@ -498,7 +512,6 @@ inlineToDokuWiki opts (Image attr alt (source, tit)) = do
inlineToDokuWiki opts (Note contents) = do
contents' <- blockListToDokuWiki opts contents
- modify (\s -> s { stNotes = True })
return $ "((" ++ contents' ++ "))"
-- note - may not work for notes with multiple blocks
@@ -507,7 +520,7 @@ imageDims opts attr = go (toPx $ dimension Width attr) (toPx $ dimension Height
where
toPx = fmap (showInPixel opts) . checkPct
checkPct (Just (Percent _)) = Nothing
- checkPct maybeDim = maybeDim
+ checkPct maybeDim = maybeDim
go (Just w) Nothing = "?" ++ w
go (Just w) (Just h) = "?" ++ w ++ "x" ++ h
go Nothing (Just h) = "?0x" ++ h