Docx writer: Added nsid to abstractNum elements.

This helps when merging word documents with numbered or bulleted lists.
Closes #627.
This commit is contained in:
John MacFarlane 2012-10-02 19:43:18 -07:00
parent 02bb0f051a
commit 3f86127f5a

View file

@ -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