@@ -39,6 +39,7 @@ import Text.Pandoc.Templates (renderTemplate')
3939import Text.Pandoc.XML ( escapeStringForXML )
4040import Data.List ( intersect, intercalate, intersperse )
4141import Network.URI ( isURI )
42+import Control.Monad.Reader
4243import Control.Monad.State
4344
4445data WriterState = WriterState {
@@ -47,20 +48,23 @@ data WriterState = WriterState {
4748 , stUseTags :: Bool -- True if we should use HTML tags because we're in a complex list
4849 }
4950
51+type MediaWikiWriter = ReaderT WriterOptions (State WriterState)
52+
5053-- | Convert Pandoc to MediaWiki.
5154writeMediaWiki :: WriterOptions -> Pandoc -> String
5255writeMediaWiki opts document =
53− evalState (pandocToMediaWiki opts document)
56+ evalState (runReaderT (pandocToMediaWiki document) opts)
5457 WriterState { stNotes = False, stListLevel = [], stUseTags = False }
5558
5659-- | Return MediaWiki representation of document.
57−pandocToMediaWiki :: WriterOptions -> Pandoc -> State WriterState String
58−pandocToMediaWiki opts (Pandoc meta blocks) = do
60+pandocToMediaWiki :: Pandoc -> MediaWikiWriter String
61+pandocToMediaWiki (Pandoc meta blocks) = do
62+ opts <- ask
5963 metadata <- metaToJSON opts
60− (fmap trimr . blockListToMediaWiki opts)
61− (inlineListToMediaWiki opts)
64+ (fmap trimr . blockListToMediaWiki)
65+ inlineListToMediaWiki
6266 meta
63− body <- blockListToMediaWiki opts blocks
67+ body <- blockListToMediaWiki blocks
6468 notesExist <- get >>= return . stNotes
6569 let notes = if notesExist
6670 then "\n<references />"
@@ -78,51 +82,50 @@ escapeString :: String -> String
7882escapeString = escapeStringForXML
7983
8084-- | Convert Pandoc block element to MediaWiki.
81−blockToMediaWiki :: WriterOptions -- ^ Options
82− -> Block -- ^ Block element
83− -> State WriterState String
85+blockToMediaWiki :: Block -- ^ Block element
86+ -> MediaWikiWriter String
8487
85−blockToMediaWiki _ Null = return ""
88+blockToMediaWiki Null = return ""
8689
87−blockToMediaWiki opts (Div attrs bs) = do
88− contents <- blockListToMediaWiki opts bs
90+blockToMediaWiki (Div attrs bs) = do
91+ contents <- blockListToMediaWiki bs
8992 return $ render Nothing (tagWithAttrs "div" attrs) ++ "\n\n" ++
9093 contents ++ "\n\n" ++ "</div>"
9194
92−blockToMediaWiki opts (Plain inlines) =
93− inlineListToMediaWiki opts inlines
95+blockToMediaWiki (Plain inlines) =
96+ inlineListToMediaWiki inlines
9497
9598-- title beginning with fig: indicates that the image is a figure
96−blockToMediaWiki opts (Para [Image txt (src,'f':'i':'g':':':tit)]) = do
99+blockToMediaWiki (Para [Image txt (src,'f':'i':'g':':':tit)]) = do
97100 capt <- if null txt
98101 then return ""
99− else ("|caption " ++) `fmap` inlineListToMediaWiki opts txt
102+ else ("|caption " ++) `fmap` inlineListToMediaWiki txt
100103 let opt = if null txt
101104 then ""
102105 else "|alt=" ++ if null tit then capt else tit ++ capt
103106 return $ "[[Image:" ++ src ++ "|frame|none" ++ opt ++ "]]\n"
104107
105−blockToMediaWiki opts (Para inlines) = do
108+blockToMediaWiki (Para inlines) = do
106109 useTags <- get >>= return . stUseTags
107110 listLevel <- get >>= return . stListLevel
108− contents <- inlineListToMediaWiki opts inlines
111+ contents <- inlineListToMediaWiki inlines
109112 return $ if useTags
110113 then "<p>" ++ contents ++ "</p>"
111114 else contents ++ if null listLevel then "\n" else ""
112115
113−blockToMediaWiki _ (RawBlock f str)
116+blockToMediaWiki (RawBlock f str)
114117 | f == Format "mediawiki" = return str
115118 | f == Format "html" = return str
116119 | otherwise = return ""
117120
118−blockToMediaWiki _ HorizontalRule = return "\n-----\n"
121+blockToMediaWiki HorizontalRule = return "\n-----\n"
119122
120−blockToMediaWiki opts (Header level _ inlines) = do
121− contents <- inlineListToMediaWiki opts inlines
123+blockToMediaWiki (Header level _ inlines) = do
124+ contents <- inlineListToMediaWiki inlines
122125 let eqs = replicate level '='
123126 return $ eqs ++ " " ++ contents ++ " " ++ eqs ++ "\n"
124127
125−blockToMediaWiki _ (CodeBlock (_,classes,_) str) = do
128+blockToMediaWiki (CodeBlock (_,classes,_) str) = do
126129 let at = classes `intersect` ["actionscript", "ada", "apache", "applescript", "asm", "asp",
127130 "autoit", "bash", "blitzbasic", "bnf", "c", "c_mac", "caddcl", "cadlisp", "cfdg", "cfm",
128131 "cpp", "cpp-qt", "csharp", "css", "d", "delphi", "diff", "div", "dos", "eiffel", "fortran",
@@ -137,68 +140,68 @@ blockToMediaWiki _ (CodeBlock (_,classes,_) str) = do
137140 else ("<source lang=\"" ++ head at ++ "\">", "</source>")
138141 return $ beg ++ escapeString str ++ end
139142
140−blockToMediaWiki opts (BlockQuote blocks) = do
141− contents <- blockListToMediaWiki opts blocks
143+blockToMediaWiki (BlockQuote blocks) = do
144+ contents <- blockListToMediaWiki blocks
142145 return $ "<blockquote>" ++ contents ++ "</blockquote>"
143146
144−blockToMediaWiki opts (Table capt aligns widths headers rows') = do
147+blockToMediaWiki (Table capt aligns widths headers rows') = do
145148 caption <- if null capt
146149 then return ""
147150 else do
148− c <- inlineListToMediaWiki opts capt
151+ c <- inlineListToMediaWiki capt
149152 return $ "|+ " ++ trimr c ++ "\n"
150153 let headless = all null headers
151154 let allrows = if headless then rows' else headers:rows'
152155 tableBody <- (concat . intersperse "|-\n") `fmap`
153− mapM (tableRowToMediaWiki opts headless aligns widths)
156+ mapM (tableRowToMediaWiki headless aligns widths)
154157 (zip [1..] allrows)
155158 return $ "{|\n" ++ caption ++ tableBody ++ "|}\n"
156159
157−blockToMediaWiki opts x@(BulletList items) = do
160+blockToMediaWiki x@(BulletList items) = do
158161 oldUseTags <- get >>= return . stUseTags
159162 listLevel <- get >>= return . stListLevel
160163 let useTags = oldUseTags || not (isSimpleList x)
161164 if useTags
162165 then do
163166 modify $ \s -> s { stUseTags = True }
164− contents <- mapM (listItemToMediaWiki opts) items
167+ contents <- mapM listItemToMediaWiki items
165168 modify $ \s -> s { stUseTags = oldUseTags }
166169 return $ "<ul>\n" ++ vcat contents ++ "</ul>\n"
167170 else do
168171 modify $ \s -> s { stListLevel = stListLevel s ++ "*" }
169− contents <- mapM (listItemToMediaWiki opts) items
172+ contents <- mapM listItemToMediaWiki items
170173 modify $ \s -> s { stListLevel = init (stListLevel s) }
171174 return $ vcat contents ++ if null listLevel then "\n" else ""
172175
173−blockToMediaWiki opts x@(OrderedList attribs items) = do
176+blockToMediaWiki x@(OrderedList attribs items) = do
174177 oldUseTags <- get >>= return . stUseTags
175178 listLevel <- get >>= return . stListLevel
176179 let useTags = oldUseTags || not (isSimpleList x)
177180 if useTags
178181 then do
179182 modify $ \s -> s { stUseTags = True }
180− contents <- mapM (listItemToMediaWiki opts) items
183+ contents <- mapM listItemToMediaWiki items
181184 modify $ \s -> s { stUseTags = oldUseTags }
182185 return $ "<ol" ++ listAttribsToString attribs ++ ">\n" ++ vcat contents ++ "</ol>\n"
183186 else do
184187 modify $ \s -> s { stListLevel = stListLevel s ++ "#" }
185− contents <- mapM (listItemToMediaWiki opts) items
188+ contents <- mapM listItemToMediaWiki items
186189 modify $ \s -> s { stListLevel = init (stListLevel s) }
187190 return $ vcat contents ++ if null listLevel then "\n" else ""
188191
189−blockToMediaWiki opts x@(DefinitionList items) = do
192+blockToMediaWiki x@(DefinitionList items) = do
190193 oldUseTags <- get >>= return . stUseTags
191194 listLevel <- get >>= return . stListLevel
192195 let useTags = oldUseTags || not (isSimpleList x)
193196 if useTags
194197 then do
195198 modify $ \s -> s { stUseTags = True }
196− contents <- mapM (definitionListItemToMediaWiki opts) items
199+ contents <- mapM definitionListItemToMediaWiki items
197200 modify $ \s -> s { stUseTags = oldUseTags }
198201 return $ "<dl>\n" ++ vcat contents ++ "</dl>\n"
199202 else do
200203 modify $ \s -> s { stListLevel = stListLevel s ++ ";" }
201− contents <- mapM (definitionListItemToMediaWiki opts) items
204+ contents <- mapM definitionListItemToMediaWiki items
202205 modify $ \s -> s { stListLevel = init (stListLevel s) }
203206 return $ vcat contents ++ if null listLevel then "\n" else ""
204207
@@ -216,9 +219,9 @@ listAttribsToString (startnum, numstyle, _) =
216219 else "")
217220
218221-- | Convert bullet or ordered list item (list of blocks) to MediaWiki.
219−listItemToMediaWiki :: WriterOptions -> [Block] -> State WriterState String
220−listItemToMediaWiki opts items = do
221− contents <- blockListToMediaWiki opts items
222+listItemToMediaWiki :: [Block] -> MediaWikiWriter String
223+listItemToMediaWiki items = do
224+ contents <- blockListToMediaWiki items
222225 useTags <- get >>= return . stUseTags
223226 if useTags
224227 then return $ "<li>" ++ contents ++ "</li>"
@@ -227,12 +230,11 @@ listItemToMediaWiki opts items = do
227230 return $ marker ++ " " ++ contents
228231
229232-- | Convert definition list item (label, list of blocks) to MediaWiki.
230−definitionListItemToMediaWiki :: WriterOptions
231− -> ([Inline],[[Block]])
232− -> State WriterState String
233−definitionListItemToMediaWiki opts (label, items) = do
234− labelText <- inlineListToMediaWiki opts label
235− contents <- mapM (blockListToMediaWiki opts) items
233+definitionListItemToMediaWiki :: ([Inline],[[Block]])
234+ -> MediaWikiWriter String
235+definitionListItemToMediaWiki (label, items) = do
236+ labelText <- inlineListToMediaWiki label
237+ contents <- mapM blockListToMediaWiki items
236238 useTags <- get >>= return . stUseTags
237239 if useTags
238240 then return $ "<dt>" ++ labelText ++ "</dt>\n" ++
@@ -283,25 +285,23 @@ vcat = intercalate "\n"
283285
284286-- Auxiliary functions for tables:
285287
286−tableRowToMediaWiki :: WriterOptions
287− -> Bool
288+tableRowToMediaWiki :: Bool
288289 -> [Alignment]
289290 -> [Double]
290291 -> (Int, [[Block]])
291− -> State WriterState String
292−tableRowToMediaWiki opts headless alignments widths (rownum, cells) = do
292+ -> MediaWikiWriter String
293+tableRowToMediaWiki headless alignments widths (rownum, cells) = do
293294 cells' <- mapM (\cellData ->
294− tableCellToMediaWiki opts headless rownum cellData)
295+ tableCellToMediaWiki headless rownum cellData)
295296 $ zip3 alignments widths cells
296297 return $ unlines cells'
297298
298−tableCellToMediaWiki :: WriterOptions
299− -> Bool
299+tableCellToMediaWiki :: Bool
300300 -> Int
301301 -> (Alignment, Double, [Block])
302− -> State WriterState String
303−tableCellToMediaWiki opts headless rownum (alignment, width, bs) = do
304− contents <- blockListToMediaWiki opts bs
302+ -> MediaWikiWriter String
303+tableCellToMediaWiki headless rownum (alignment, width, bs) = do
304+ contents <- blockListToMediaWiki bs
305305 let marker = if rownum == 1 && not headless then "!" else "|"
306306 let percent w = show (truncate (100*w) :: Integer) ++ "%"
307307 let attrs = ["align=" ++ show (alignmentToString alignment) |
@@ -321,75 +321,74 @@ alignmentToString alignment = case alignment of
321321 AlignDefault -> "left"
322322
323323-- | Convert list of Pandoc block elements to MediaWiki.
324−blockListToMediaWiki :: WriterOptions -- ^ Options
325− -> [Block] -- ^ List of block elements
326− -> State WriterState String
327−blockListToMediaWiki opts blocks =
328− mapM (blockToMediaWiki opts) blocks >>= return . vcat
324+blockListToMediaWiki :: [Block] -- ^ List of block elements
325+ -> MediaWikiWriter String
326+blockListToMediaWiki blocks =
327+ mapM blockToMediaWiki blocks >>= return . vcat
329328
330329-- | Convert list of Pandoc inline elements to MediaWiki.
331−inlineListToMediaWiki :: WriterOptions -> [Inline] -> State WriterState String
332−inlineListToMediaWiki opts lst =
333− mapM (inlineToMediaWiki opts) lst >>= return . concat
330+inlineListToMediaWiki :: [Inline] -> MediaWikiWriter String
331+inlineListToMediaWiki lst =
332+ mapM inlineToMediaWiki lst >>= return . concat
334333
335334-- | Convert Pandoc inline element to MediaWiki.
336−inlineToMediaWiki :: WriterOptions -> Inline -> State WriterState String
335+inlineToMediaWiki :: Inline -> MediaWikiWriter String
337336
338−inlineToMediaWiki opts (Span attrs ils) = do
339− contents <- inlineListToMediaWiki opts ils
337+inlineToMediaWiki (Span attrs ils) = do
338+ contents <- inlineListToMediaWiki ils
340339 return $ render Nothing (tagWithAttrs "span" attrs) ++ contents ++ "</span>"
341340
342−inlineToMediaWiki opts (Emph lst) = do
343− contents <- inlineListToMediaWiki opts lst
341+inlineToMediaWiki (Emph lst) = do
342+ contents <- inlineListToMediaWiki lst
344343 return $ "''" ++ contents ++ "''"
345344
346−inlineToMediaWiki opts (Strong lst) = do
347− contents <- inlineListToMediaWiki opts lst
345+inlineToMediaWiki (Strong lst) = do
346+ contents <- inlineListToMediaWiki lst
348347 return $ "'''" ++ contents ++ "'''"
349348
350−inlineToMediaWiki opts (Strikeout lst) = do
351− contents <- inlineListToMediaWiki opts lst
349+inlineToMediaWiki (Strikeout lst) = do
350+ contents <- inlineListToMediaWiki lst
352351 return $ "<s>" ++ contents ++ "</s>"
353352
354−inlineToMediaWiki opts (Superscript lst) = do
355− contents <- inlineListToMediaWiki opts lst
353+inlineToMediaWiki (Superscript lst) = do
354+ contents <- inlineListToMediaWiki lst
356355 return $ "<sup>" ++ contents ++ "</sup>"
357356
358−inlineToMediaWiki opts (Subscript lst) = do
359− contents <- inlineListToMediaWiki opts lst
357+inlineToMediaWiki (Subscript lst) = do
358+ contents <- inlineListToMediaWiki lst
360359 return $ "<sub>" ++ contents ++ "</sub>"
361360
362−inlineToMediaWiki opts (SmallCaps lst) = inlineListToMediaWiki opts lst
361+inlineToMediaWiki (SmallCaps lst) = inlineListToMediaWiki lst
363362
364−inlineToMediaWiki opts (Quoted SingleQuote lst) = do
365− contents <- inlineListToMediaWiki opts lst
363+inlineToMediaWiki (Quoted SingleQuote lst) = do
364+ contents <- inlineListToMediaWiki lst
366365 return $ "\8216" ++ contents ++ "\8217"
367366
368−inlineToMediaWiki opts (Quoted DoubleQuote lst) = do
369− contents <- inlineListToMediaWiki opts lst
367+inlineToMediaWiki (Quoted DoubleQuote lst) = do
368+ contents <- inlineListToMediaWiki lst
370369 return $ "\8220" ++ contents ++ "\8221"
371370
372−inlineToMediaWiki opts (Cite _ lst) = inlineListToMediaWiki opts lst
371+inlineToMediaWiki (Cite _ lst) = inlineListToMediaWiki lst
373372
374−inlineToMediaWiki _ (Code _ str) =
373+inlineToMediaWiki (Code _ str) =
375374 return $ "<code>" ++ (escapeString str) ++ "</code>"
376375
377−inlineToMediaWiki _ (Str str) = return $ escapeString str
376+inlineToMediaWiki (Str str) = return $ escapeString str
378377
379−inlineToMediaWiki _ (Math _ str) = return $ "<math>" ++ str ++ "</math>"
380− -- note: str should NOT be escaped
378+inlineToMediaWiki (Math _ str) = return $ "<math>" ++ str ++ "</math>"
379+ -- note: str should NOT be escaped
381380
382−inlineToMediaWiki _ (RawInline f str)
381+inlineToMediaWiki (RawInline f str)
383382 | f == Format "mediawiki" = return str
384383 | f == Format "html" = return str
385384 | otherwise = return ""
386385
387−inlineToMediaWiki _ (LineBreak) = return "<br />"
386+inlineToMediaWiki (LineBreak) = return "<br />"
388387
389−inlineToMediaWiki _ Space = return " "
388+inlineToMediaWiki Space = return " "
390389
391−inlineToMediaWiki opts (Link txt (src, _)) = do
392− label <- inlineListToMediaWiki opts txt
390+inlineToMediaWiki (Link txt (src, _)) = do
391+ label <- inlineListToMediaWiki txt
393392 case txt of
394393 [Str s] | escapeURI s == src -> return src
395394 _ -> if isURI src
@@ -398,8 +397,8 @@ inlineToMediaWiki opts (Link txt (src, _)) = do
398397 where src' = case src of
399398 '/':xs -> xs -- with leading / it's a
400399 _ -> src -- link to a help page
401−inlineToMediaWiki opts (Image alt (source, tit)) = do
402− alt' <- inlineListToMediaWiki opts alt
400+inlineToMediaWiki (Image alt (source, tit)) = do
401+ alt' <- inlineListToMediaWiki alt
403402 let txt = if (null tit)
404403 then if null alt
405404 then ""
@@ -407,8 +406,8 @@ inlineToMediaWiki opts (Image alt (source, tit)) = do
407406 else "|" ++ tit
408407 return $ "[[Image:" ++ source ++ txt ++ "]]"
409408
410−inlineToMediaWiki opts (Note contents) = do
411− contents' <- blockListToMediaWiki opts contents
409+inlineToMediaWiki (Note contents) = do
410+ contents' <- blockListToMediaWiki contents
412411 modify (\s -> s { stNotes = True })
413412 return $ "<ref>" ++ contents' ++ "</ref>"
414413 -- note - may not work for notes with multiple blocks