@@ -441,7 +441,7 @@ writeDocx opts doc = do
441441 Nothing -> mknode "w:sectPr" [] ()
442442
443443 -- let sectpr = fromMaybe (mknode "w:sectPr" [] ()) mbsectpr'
444− let contents' = contents ++ [sectpr]
444+ let contents' = contents ++ [Elem sectpr]
445445 let docContents = mknode "w:document" stdAttributes
446446 $ mknode "w:body" [] contents'
447447
@@ -538,7 +538,8 @@ writeDocx opts doc = do
538538
539539 -- docProps/custom.xml
540540 let customProperties :: [(String, String)]
541− customProperties = [(T.unpack k, T.unpack $ lookupMetaString k meta) | k <- M.keys (unMeta meta)
541+ customProperties = [ (T.unpack k, T.unpack $ lookupMetaString k meta)
542+ | k <- M.keys (unMeta meta)
542543 , k `notElem` (["title", "author", "keywords"]
543544 ++ extraCoreProps)]
544545 let mkCustomProp (k, v) pid = mknode "property"
@@ -788,7 +789,7 @@ makeTOC opts = do
788789 mknode "w:docPartUnique" [] ()]
789790 -- w:docPartObj
790791 ), -- w:sdtPr
791− mknode "w:sdtContent" [] (title++[
792+ mknode "w:sdtContent" [] (title ++ [ Elem $
792793 mknode "w:p" [] (
793794 mknode "w:r" [] [
794795 mknode "w:fldChar" [("w:fldCharType","begin"),("w:dirty","true")] (),
@@ -802,7 +803,9 @@ makeTOC opts = do
802803
803804-- | Convert Pandoc document to two lists of
804805-- OpenXML elements (the main document and footnotes).
805−writeOpenXML :: (PandocMonad m) => WriterOptions -> Pandoc -> WS m ([Element], [Element],[Element])
806+writeOpenXML :: (PandocMonad m)
807+ => WriterOptions -> Pandoc
808+ -> WS m ([Content], [Element], [Element])
806809writeOpenXML opts (Pandoc meta blocks) = do
807810 let tit = docTitle meta
808811 let auths = docAuthors meta
@@ -830,6 +833,7 @@ writeOpenXML opts (Pandoc meta blocks) = do
830833 return $
831834 mknode "w:comment" [('w':':':T.unpack k,T.unpack v) | (k,v) <- kvs]
832835 [ mknode "w:p" [] $
836+ map Elem
833837 [ mknode "w:pPr" []
834838 [ mknode "w:pStyle" [("w:val", "CommentText")] () ]
835839 , mknode "w:r" []
@@ -844,11 +848,11 @@ writeOpenXML opts (Pandoc meta blocks) = do
844848 toc <- if includeTOC
845849 then makeTOC opts
846850 else return []
847− let meta' = title ++ subtitle ++ authors ++ date ++ abstract ++ toc
851+ let meta' = title ++ subtitle ++ authors ++ date ++ abstract ++ map Elem toc
848852 return (meta' ++ doc', notes', comments')
849853
850854-- | Convert a list of Pandoc blocks to OpenXML.
851−blocksToOpenXML :: (PandocMonad m) => WriterOptions -> [Block] -> WS m [Element]
855+blocksToOpenXML :: (PandocMonad m) => WriterOptions -> [Block] -> WS m [Content]
852856blocksToOpenXML opts = fmap concat . mapM (blockToOpenXML opts) . separateTables
853857
854858-- Word combines adjacent tables unless you put an empty paragraph between
@@ -884,10 +888,10 @@ dynamicStyleKey :: T.Text
884888dynamicStyleKey = "custom-style"
885889
886890-- | Convert a Pandoc block element to OpenXML.
887−blockToOpenXML :: (PandocMonad m) => WriterOptions -> Block -> WS m [Element]
891+blockToOpenXML :: (PandocMonad m) => WriterOptions -> Block -> WS m [Content]
888892blockToOpenXML opts blk = withDirection $ blockToOpenXML' opts blk
889893
890−blockToOpenXML' :: (PandocMonad m) => WriterOptions -> Block -> WS m [Element]
894+blockToOpenXML' :: (PandocMonad m) => WriterOptions -> Block -> WS m [Content]
891895blockToOpenXML' _ Null = return []
892896blockToOpenXML' opts (Div (ident,_classes,kvs) bs) = do
893897 stylemod <- case lookup dynamicStyleKey kvs of
@@ -921,18 +925,18 @@ blockToOpenXML' opts (Header lev (ident,_,kvs) lst) = do
921925 Just n -> do
922926 num <- withTextPropM (rStyleM "SectionNumber")
923927 (inlineToOpenXML opts (Str n))
924− return $ num ++ [mknode "w:r" [] [mknode "w:tab" [] ()]]
928+ return $ num ++ [Elem $ mknode "w:r" [] [mknode "w:tab" [] ()]]
925929 Nothing -> return []
926930 else return []
927931 contents <- (number ++) <$> inlinesToOpenXML opts lst
928932 if T.null ident
929− then return [mknode "w:p" [] (paraProps ++ contents)]
933+ then return [Elem $ mknode "w:p" [] (map Elem paraProps ++ contents)]
930934 else do
931935 let bookmarkName = ident
932936 modify $ \s -> s{ stSectionIds = Set.insert bookmarkName
933937 $ stSectionIds s }
934938 bookmarkedContents <- wrapBookmark bookmarkName contents
935− return [mknode "w:p" [] (paraProps ++ bookmarkedContents)]
939+ return [Elem $ mknode "w:p" [] (map Elem paraProps ++ bookmarkedContents)]
936940blockToOpenXML' opts (Plain lst) = do
937941 isInTable <- gets stInTable
938942 isInList <- gets stInList
@@ -952,7 +956,9 @@ blockToOpenXML' opts (Para [Image attr alt (src,T.stripPrefix "fig:" -> Just tit
952956 contents <- inlinesToOpenXML opts [Image attr alt (src,tit)]
953957 captionNode <- withParaPropM (pStyleM "Image Caption")
954958 $ blockToOpenXML opts (Para alt)
955− return $ mknode "w:p" [] (paraProps ++ contents) : captionNode
959+ return $
960+ Elem (mknode "w:p" [] (map Elem paraProps ++ contents))
961+ : captionNode
956962blockToOpenXML' opts (Para lst)
957963 | null lst && not (isEnabled Ext_empty_paragraphs opts) = return []
958964 | otherwise = do
@@ -969,10 +975,10 @@ blockToOpenXML' opts (Para lst)
969975 ps -> ps
970976 modify $ \s -> s { stFirstPara = False }
971977 contents <- inlinesToOpenXML opts lst
972− return [mknode "w:p" [] (paraProps' ++ contents)]
978+ return [Elem $ mknode "w:p" [] (map Elem paraProps' ++ contents)]
973979blockToOpenXML' opts (LineBlock lns) = blockToOpenXML opts $ linesToPara lns
974980blockToOpenXML' _ b@(RawBlock format str)
975− | format == Format "openxml" = return [ x | Elem x <- parseXML str ]
981+ | format == Format "openxml" = return (parseXML str)
976982 | otherwise = do
977983 report $ BlockNotRendered b
978984 return []
@@ -987,7 +993,7 @@ blockToOpenXML' opts (CodeBlock attrs@(ident, _, _) str) = do
987993 wrapBookmark ident p
988994blockToOpenXML' _ HorizontalRule = do
989995 setFirstPara
990− return [
996+ return [ Elem $
991997 mknode "w:p" [] $ mknode "w:r" [] $ mknode "w:pict" []
992998 $ mknode "v:rect" [("style","width:0;height:1.5pt"),
993999 ("o:hralign","center"),
@@ -1006,26 +1012,28 @@ blockToOpenXML' opts (Table _ blkCapt specs thead tbody tfoot) = do
10061012 -- Not in the spec but in Word 2007, 2010. See #4953.
10071013 let cellToOpenXML (al, cell) = do
10081014 es <- withParaProp (alignmentFor al) $ blocksToOpenXML opts cell
1009− return $ if any (\e -> qName (elName e) == "p") es
1015+ return $ if any (\e -> qName (elName e) == "p") (onlyElems es)
10101016 then es
1011− else es ++ [mknode "w:p" [] ()]
1017+ else es ++ [Elem $ mknode "w:p" [] ()]
10121018 headers' <- mapM cellToOpenXML $ zip aligns headers
10131019 rows' <- mapM (mapM cellToOpenXML . zip aligns) rows
1014− let borderProps = mknode "w:tcPr" []
1020+ let borderProps = Elem $ mknode "w:tcPr" []
10151021 [ mknode "w:tcBorders" []
10161022 $ mknode "w:bottom" [("w:val","single")] ()
10171023 , mknode "w:vAlign" [("w:val","bottom")] () ]
10181024 compactStyle <- pStyleM "Compact"
1019− let emptyCell' = [mknode "w:p" [] [mknode "w:pPr" [] [compactStyle]]]
1025+ let emptyCell' = [Elem $ mknode "w:p" [] [mknode "w:pPr" [] [compactStyle]]]
10201026 let mkcell border contents = mknode "w:tc" []
10211027 $ [ borderProps | border ] ++
10221028 if null contents
10231029 then emptyCell'
10241030 else contents
1025− let mkrow border cells = mknode "w:tr" [] $
1026− [mknode "w:trPr" [] [
1027− mknode "w:cnfStyle" [("w:firstRow","1")] ()] | border]
1028− ++ map (mkcell border) cells
1031+ let mkrow border cells =
1032+ mknode "w:tr" [] $
1033+ [ mknode "w:trPr" []
1034+ [ mknode "w:cnfStyle" [("w:firstRow","1")] ()]
1035+ | border]
1036+ ++ map (mkcell border) cells
10291037 let textwidth = 7920 -- 5.5 in in twips, 1/20 pt
10301038 let fullrow = 5000 -- 100% specified in pct
10311039 let rowwidth = fullrow * sum widths
@@ -1035,7 +1043,8 @@ blockToOpenXML' opts (Table _ blkCapt specs thead tbody tfoot) = do
10351043 modify $ \s -> s { stInTable = False }
10361044 return $
10371045 caption' ++
1038− [mknode "w:tbl" []
1046+ [Elem $
1047+ mknode "w:tbl" []
10391048 ( mknode "w:tblPr" []
10401049 ( mknode "w:tblStyle" [("w:val","Table")] () :
10411050 mknode "w:tblW" [("w:type", "pct"), ("w:w", show rowwidth)] () :
@@ -1070,7 +1079,9 @@ blockToOpenXML' opts (DefinitionList items) = do
10701079 setFirstPara
10711080 return l
10721081
1073−definitionListItemToOpenXML :: (PandocMonad m) => WriterOptions -> ([Inline],[[Block]]) -> WS m [Element]
1082+definitionListItemToOpenXML :: (PandocMonad m)
1083+ => WriterOptions -> ([Inline],[[Block]])
1084+ -> WS m [Content]
10741085definitionListItemToOpenXML opts (term,defs) = do
10751086 term' <- withParaPropM (pStyleM "Definition Term")
10761087 $ blockToOpenXML opts (Para term)
@@ -1083,8 +1094,11 @@ addList marker = do
10831094 lists <- gets stLists
10841095 modify $ \st -> st{ stLists = lists ++ [marker] }
10851096
1086−listItemToOpenXML :: (PandocMonad m) => WriterOptions -> Int -> [Block] -> WS m [Element]
1087−listItemToOpenXML _ _ [] = return []
1097+listItemToOpenXML :: (PandocMonad m)
1098+ => WriterOptions
1099+ -> Int -> [Block]
1100+ -> WS m [Content]
1101+listItemToOpenXML _ _ [] = return []
10881102listItemToOpenXML opts numid (first:rest) = do
10891103 oldInList <- gets stInList
10901104 modify $ \st -> st{ stInList = True }
@@ -1111,7 +1125,7 @@ alignmentToString alignment = case alignment of
11111125 AlignDefault -> "left"
11121126
11131127-- | Convert a list of inline elements to OpenXML.
1114−inlinesToOpenXML :: (PandocMonad m) => WriterOptions -> [Inline] -> WS m [Element]
1128+inlinesToOpenXML :: PandocMonad m => WriterOptions -> [Inline] -> WS m [Content]
11151129inlinesToOpenXML opts lst = concat `fmap` mapM (inlineToOpenXML opts) lst
11161130
11171131withNumId :: (PandocMonad m) => Int -> WS m a -> WS m a
@@ -1186,12 +1200,12 @@ setFirstPara :: PandocMonad m => WS m ()
11861200setFirstPara = modify $ \s -> s { stFirstPara = True }
11871201
11881202-- | Convert an inline element to OpenXML.
1189−inlineToOpenXML :: PandocMonad m => WriterOptions -> Inline -> WS m [Element]
1203+inlineToOpenXML :: PandocMonad m => WriterOptions -> Inline -> WS m [Content]
11901204inlineToOpenXML opts il = withDirection $ inlineToOpenXML' opts il
11911205
1192−inlineToOpenXML' :: PandocMonad m => WriterOptions -> Inline -> WS m [Element]
1206+inlineToOpenXML' :: PandocMonad m => WriterOptions -> Inline -> WS m [Content]
11931207inlineToOpenXML' _ (Str str) =
1194− formattedString str
1208+ map Elem <$> formattedString str
11951209inlineToOpenXML' opts Space = inlineToOpenXML opts (Str " ")
11961210inlineToOpenXML' opts SoftBreak = inlineToOpenXML opts (Str " ")
11971211inlineToOpenXML' opts (Span ("",["csl-block"],[]) ils) =
@@ -1199,10 +1213,11 @@ inlineToOpenXML' opts (Span ("",["csl-block"],[]) ils) =
11991213inlineToOpenXML' opts (Span ("",["csl-left-margin"],[]) ils) =
12001214 inlinesToOpenXML opts ils
12011215inlineToOpenXML' opts (Span ("",["csl-right-inline"],[]) ils) =
1202− ([mknode "w:r" []
1203− (mknode "w:t"
1204− [("xml:space","preserve")]
1205− ("\t" :: String))] ++)
1216+ ([Elem $
1217+ mknode "w:r" []
1218+ (mknode "w:t"
1219+ [("xml:space","preserve")]
1220+ ("\t" :: String))] ++)
12061221 <$> inlinesToOpenXML opts ils
12071222inlineToOpenXML' opts (Span ("",["csl-indent"],[]) ils) =
12081223 inlinesToOpenXML opts ils
@@ -1212,18 +1227,18 @@ inlineToOpenXML' _ (Span (ident,["comment-start"],kvs) ils) = do
12121227 let ident' = fromMaybe ident (lookup "id" kvs)
12131228 kvs' = filter (("id" /=) . fst) kvs
12141229 modify $ \st -> st{ stComments = (("id",ident'):kvs', ils) : stComments st }
1215− return [ mknode "w:commentRangeStart" [("w:id", T.unpack ident')] () ]
1230+ return [ Elem $ mknode "w:commentRangeStart" [("w:id", T.unpack ident')] () ]
12161231inlineToOpenXML' _ (Span (ident,["comment-end"],kvs) _) =
12171232 -- prefer the "id" in kvs, since that is the one produced by the docx
12181233 -- reader.
12191234 let ident' = fromMaybe ident (lookup "id" kvs)
1220− in
1221− return [ mknode "w:commentRangeEnd" [("w:id", T.unpack ident')] ()
1222− , mknode "w:r" []
1223− [ mknode "w:rPr" []
1224− [ mknode "w:rStyle" [("w:val", "CommentReference")] () ]
1225− , mknode "w:commentReference" [("w:id", T.unpack ident')] () ]
1226− ]
1235+ in return . map Elem $
1236+ [ mknode "w:commentRangeEnd" [("w:id", T.unpack ident')] ()
1237+ , mknode "w:r" []
1238+ [ mknode "w:rPr" []
1239+ [ mknode "w:rStyle" [("w:val", "CommentReference")] () ]
1240+ , mknode "w:commentReference" [("w:id", T.unpack ident')] () ]
1241+ ]
12271242inlineToOpenXML' opts (Span (ident,classes,kvs) ils) = do
12281243 stylemod <- case lookup dynamicStyleKey kvs of
12291244 Just (fromString . T.unpack -> sty) -> do
@@ -1255,8 +1270,9 @@ inlineToOpenXML' opts (Span (ident,classes,kvs) ils) = do
12551270 modify $ \s -> s{stInsId = insId + 1}
12561271 return $ \f -> do
12571272 x <- f
1258− return [ mknode "w:ins"
1259− (("w:id", show insId) : changeAuthorDate) x]
1273+ return [Elem $
1274+ mknode "w:ins"
1275+ (("w:id", show insId) : changeAuthorDate) x]
12601276 else return id
12611277 delmod <- if "deletion" `elem` classes
12621278 then do
@@ -1265,8 +1281,8 @@ inlineToOpenXML' opts (Span (ident,classes,kvs) ils) = do
12651281 modify $ \s -> s{stDelId = delId + 1}
12661282 return $ \f -> local (\env->env{envInDel=True}) $ do
12671283 x <- f
1268− return [mknode "w:del"
1269− (("w:id", show delId) : changeAuthorDate) x]
1284+ return [Elem $ mknode "w:del"
1285+ (("w:id", show delId) : changeAuthorDate) x]
12701286 else return id
12711287 contents <- insmod $ delmod $ dirmod $ stylemod $ pmod
12721288 $ inlinesToOpenXML opts ils
@@ -1294,9 +1310,9 @@ inlineToOpenXML' opts (SmallCaps lst) =
12941310inlineToOpenXML' opts (Strikeout lst) =
12951311 withTextProp (mknode "w:strike" [] ())
12961312 $ inlinesToOpenXML opts lst
1297−inlineToOpenXML' _ LineBreak = return [br]
1313+inlineToOpenXML' _ LineBreak = return [Elem br]
12981314inlineToOpenXML' _ il@(RawInline f str)
1299− | f == Format "openxml" = return [ x | Elem x <- parseXML str ]
1315+ | f == Format "openxml" = return (parseXML str)
13001316 | otherwise = do
13011317 report $ InlineNotRendered il
13021318 return []
@@ -1309,13 +1325,13 @@ inlineToOpenXML' opts (Math mathType str) = do
13091325 when (mathType == DisplayMath) setFirstPara
13101326 res <- (lift . lift) (convertMath writeOMML mathType str)
13111327 case res of
1312− Right r -> return [r]
1328+ Right r -> return [Elem r]
13131329 Left il -> inlineToOpenXML' opts il
13141330inlineToOpenXML' opts (Cite _ lst) = inlinesToOpenXML opts lst
13151331inlineToOpenXML' opts (Code attrs str) = do
13161332 let alltoktypes = [KeywordTok ..]
13171333 tokTypesMap <- mapM (\tt -> (,) tt <$> rStyleM (fromString $ show tt)) alltoktypes
1318− let unhighlighted = intercalate [br] `fmap`
1334+ let unhighlighted = (map Elem . intercalate [br]) `fmap`
13191335 mapM formattedString (T.lines str)
13201336 formatOpenXML _fmtOpts = intercalate [br] . map (map toHlTok)
13211337 toHlTok (toktype,tok) =
@@ -1328,7 +1344,7 @@ inlineToOpenXML' opts (Code attrs str) = do
13281344 then unhighlighted
13291345 else case highlight (writerSyntaxMap opts)
13301346 formatOpenXML attrs str of
1331− Right h -> return h
1347+ Right h -> return (map Elem h)
13321348 Left msg -> do
13331349 unless (T.null msg) $ report $ CouldNotHighlight msg
13341350 unhighlighted
@@ -1351,14 +1367,14 @@ inlineToOpenXML' opts (Note bs) = do
13511367 $ insertNoteRef bs)
13521368 let newnote = mknode "w:footnote" [("w:id", notenum)] contents
13531369 modify $ \s -> s{ stFootnotes = newnote : notes }
1354− return [ mknode "w:r" []
1370+ return [ Elem $ mknode "w:r" []
13551371 [ mknode "w:rPr" [] footnoteStyle
13561372 , mknode "w:footnoteReference" [("w:id", notenum)] () ] ]
13571373-- internal link:
13581374inlineToOpenXML' opts (Link _ txt (T.uncons -> Just ('#', xs),_)) = do
13591375 contents <- withTextPropM (rStyleM "Hyperlink") $ inlinesToOpenXML opts txt
13601376 return
1361− [ mknode "w:hyperlink" [("w:anchor", T.unpack $ toBookmarkName xs)] contents ]
1377+ [ Elem $ mknode "w:hyperlink" [("w:anchor", T.unpack $ toBookmarkName xs)] contents ]
13621378-- external link:
13631379inlineToOpenXML' opts (Link _ txt (src,_)) = do
13641380 contents <- withTextPropM (rStyleM "Hyperlink") $ inlinesToOpenXML opts txt
@@ -1370,7 +1386,7 @@ inlineToOpenXML' opts (Link _ txt (src,_)) = do
13701386 modify $ \st -> st{ stExternalLinks =
13711387 M.insert (T.unpack src) i extlinks }
13721388 return i
1373− return [ mknode "w:hyperlink" [("r:id",id')] contents ]
1389+ return [ Elem $ mknode "w:hyperlink" [("r:id",id')] contents ]
13741390inlineToOpenXML' opts (Image attr@(imgident, _, _) alt (src, title)) = do
13751391 pageWidth <- asks envPrintWidth
13761392 imgs <- gets stImages
@@ -1434,7 +1450,7 @@ inlineToOpenXML' opts (Image attr@(imgident, _, _) alt (src, title)) = do
14341450 imgElt
14351451
14361452 wrapBookmark imgident =<< case stImage of
1437− Just imgData -> return [generateImgElt imgData]
1453+ Just imgData -> return [Elem $ generateImgElt imgData]
14381454 Nothing -> ( do --try
14391455 (img, mt) <- P.fetchItem src
14401456 ident <- ("rId"++) `fmap` getUniqueId
@@ -1462,7 +1478,7 @@ inlineToOpenXML' opts (Image attr@(imgident, _, _) alt (src, title)) = do
14621478 else do
14631479 -- insert mime type to use in constructing [Content_Types].xml
14641480 modify $ \st -> st { stImages = M.insert (T.unpack src) imgData $ stImages st }
1465− return [generateImgElt imgData]
1481+ return [Elem $ generateImgElt imgData]
14661482 )
14671483 `catchError` ( \e -> do
14681484 report $ CouldNotFetchResource src $ T.pack (show e)
@@ -1512,7 +1528,7 @@ withDirection x = do
15121528 , envTextProperties = EnvProps textStyle textProps'
15131529 }
15141530
1515−wrapBookmark :: (PandocMonad m) => T.Text -> [Element] -> WS m [Element]
1531+wrapBookmark :: (PandocMonad m) => T.Text -> [Content] -> WS m [Content]
15161532wrapBookmark "" contents = return contents
15171533wrapBookmark ident contents = do
15181534 id' <- getUniqueId
@@ -1520,7 +1536,7 @@ wrapBookmark ident contents = do
15201536 [("w:id", id')
15211537 ,("w:name", T.unpack $ toBookmarkName ident)] ()
15221538 bookmarkEnd = mknode "w:bookmarkEnd" [("w:id", id')] ()
1523− return $ bookmarkStart : contents ++ [bookmarkEnd]
1539+ return $ Elem bookmarkStart : contents ++ [Elem bookmarkEnd]
15241540
15251541-- Word imposes a 40 character limit on bookmark names and requires
15261542-- that they begin with a letter. So we just use a hash of the