From 3f86127f5a146d63261a378a826532183ab3a63b Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Tue, 2 Oct 2012 19:43:18 -0700 Subject: Docx writer: Added nsid to abstractNum elements. This helps when merging word documents with numbered or bulleted lists. Closes #627. --- src/Text/Pandoc/Writers/Docx.hs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/Text/Pandoc/Writers/Docx.hs b/src/Text/Pandoc/Writers/Docx.hs index e44f77497..b0f31ac45 100644 --- a/src/Text/Pandoc/Writers/Docx.hs +++ b/src/Text/Pandoc/Writers/Docx.hs @@ -51,6 +51,8 @@ import Text.TeXMath import Control.Monad.State import Text.Highlighting.Kate import Data.Unique (hashUnique, newUnique) +import System.Random (randomRIO) +import Text.Printf (printf) data WriterState = WriterState{ stTextProperties :: [Element] @@ -152,8 +154,8 @@ writeDocx opts doc@(Pandoc (Meta tit auths date) _) = do let styleEntry = toEntry stylepath epochtime $ UTF8.fromStringLazy $ showTopElement' styledoc' -- construct word/numbering.xml let numpath = "word/numbering.xml" - let numEntry = toEntry numpath epochtime $ UTF8.fromStringLazy $ showTopElement' - $ mkNumbering (stNumStyles st) (stLists st) + numEntry <- (toEntry numpath epochtime . UTF8.fromStringLazy . showTopElement') + `fmap` mkNumbering (stNumStyles st) (stLists st) let docPropsPath = "docProps/core.xml" let docProps = mknode "cp:coreProperties" [("xmlns:cp","http://schemas.openxmlformats.org/package/2006/metadata/core-properties") @@ -215,11 +217,12 @@ styleToOpenXml style = parStyle : map toStyle alltoktypes $ backgroundColor style ) ] -mkNumbering :: M.Map ListMarker Int -> [ListMarker] -> Element -mkNumbering markers lists = - mknode "w:numbering" [("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")] - $ map mkAbstractNum (M.toList markers) - ++ zipWith (mkNum markers) lists [1..(length lists)] +mkNumbering :: M.Map ListMarker Int -> [ListMarker] -> IO Element +mkNumbering markers lists = do + elts <- mapM mkAbstractNum (M.toList markers) + return $ mknode "w:numbering" + [("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")] + $ elts ++ zipWith (mkNum markers) lists [1..(length lists)] mkNum :: M.Map ListMarker Int -> ListMarker -> Int -> Element mkNum markers marker numid = @@ -233,10 +236,12 @@ mkNum markers marker numid = $ mknode "w:startOverride" [("w:val",show start)] ()) [0..6] where absnumid = maybe 0 id $ M.lookup marker markers -mkAbstractNum :: (ListMarker,Int) -> Element -mkAbstractNum (marker,numid) = - mknode "w:abstractNum" [("w:abstractNumId",show numid)] - $ mknode "w:multiLevelType" [("w:val","multilevel")] () +mkAbstractNum :: (ListMarker,Int) -> IO Element +mkAbstractNum (marker,numid) = do + nsid <- randomRIO (0x10000000 :: Integer, 0xFFFFFFFF :: Integer) + return $ mknode "w:abstractNum" [("w:abstractNumId",show numid)] + $ mknode "w:nsid" [("w:val", printf "%8x" nsid)] () + : mknode "w:multiLevelType" [("w:val","multilevel")] () : map (mkLvl marker) [0..6] mkLvl :: ListMarker -> Int -> Element -- cgit v1.2.3