git.iko.soy/typeable/pandoc
on master help sign in
Docx writer: Simplified abstractNumId numbering.
05355acJohn MacFarlane
src/Text/Pandoc/Writers/Docx.hs+30−19
@@ -66,6 +66,25 @@ data ListMarker = NoMarker
66 | NumberMarker ListNumberStyle ListNumberDelim Int
66 | NumberMarker ListNumberStyle ListNumberDelim Int
67 deriving (Show, Read, Eq, Ord)
67 deriving (Show, Read, Eq, Ord)
68
68
69+listMarkerToId :: ListMarker -> String
70+listMarkerToId NoMarker = "0"
71+listMarkerToId BulletMarker = "1"
72+listMarkerToId (NumberMarker sty delim n) =
73+ styNum : delimNum : show n
74+ where styNum = case sty of
75+ DefaultStyle -> '2'
76+ Example -> '3'
77+ Decimal -> '4'
78+ LowerRoman -> '5'
79+ UpperRoman -> '6'
80+ LowerAlpha -> '7'
81+ UpperAlpha -> '8'
82+ delimNum = case delim of
83+ DefaultDelim -> '0'
84+ Period -> '1'
85+ OneParen -> '2'
86+ TwoParens -> '3'
87+
69data WriterState = WriterState{
88data WriterState = WriterState{
70 stTextProperties :: [Element]
89 stTextProperties :: [Element]
71 , stParaProperties :: [Element]
90 , stParaProperties :: [Element]
@@ -75,7 +94,6 @@ data WriterState = WriterState{
75 , stImages :: M.Map FilePath (String, String, Maybe String, Element, B.ByteString)
94 , stImages :: M.Map FilePath (String, String, Maybe String, Element, B.ByteString)
76 , stListLevel :: Int
95 , stListLevel :: Int
77 , stListNumId :: Int
96 , stListNumId :: Int
78− , stNumStyles :: M.Map ListMarker Int
79 , stLists :: [ListMarker]
97 , stLists :: [ListMarker]
80 }
98 }
81
99
@@ -89,7 +107,6 @@ defaultWriterState = WriterState{
89 , stImages = M.empty
107 , stImages = M.empty
90 , stListLevel = -1
108 , stListLevel = -1
91 , stListNumId = 1
109 , stListNumId = 1
92− , stNumStyles = M.fromList [(NoMarker, 0)]
93 , stLists = [NoMarker]
110 , stLists = [NoMarker]
94 }
111 }
95
112
@@ -273,7 +290,7 @@ writeDocx opts doc@(Pandoc meta _) = do
273 -- construct word/numbering.xml
290 -- construct word/numbering.xml
274 let numpath = "word/numbering.xml"
291 let numpath = "word/numbering.xml"
275 numEntry <- (toEntry numpath epochtime . renderXml)
292 numEntry <- (toEntry numpath epochtime . renderXml)
276− `fmap` mkNumbering (stNumStyles st) (stLists st)
293+ `fmap` mkNumbering (stLists st)
277 let docPropsPath = "docProps/core.xml"
294 let docPropsPath = "docProps/core.xml"
278 let docProps = mknode "cp:coreProperties"
295 let docProps = mknode "cp:coreProperties"
279 [("xmlns:cp","http://schemas.openxmlformats.org/package/2006/metadata/core-properties")
296 [("xmlns:cp","http://schemas.openxmlformats.org/package/2006/metadata/core-properties")
@@ -371,29 +388,28 @@ styleToOpenXml style = parStyle : map toStyle alltoktypes
371 $ backgroundColor style )
388 $ backgroundColor style )
372 ]
389 ]
373
390
374−mkNumbering :: M.Map ListMarker Int -> [ListMarker] -> IO Element
391+mkNumbering :: [ListMarker] -> IO Element
375−mkNumbering markers lists = do
392+mkNumbering lists = do
376− elts <- mapM mkAbstractNum (M.toList markers)
393+ elts <- mapM mkAbstractNum (ordNub lists)
377 return $ mknode "w:numbering"
394 return $ mknode "w:numbering"
378 [("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")]
395 [("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")]
379− $ elts ++ zipWith (mkNum markers) lists [1..(length lists)]
396+ $ elts ++ zipWith mkNum lists [1..(length lists)]
380
397
381−mkNum :: M.Map ListMarker Int -> ListMarker -> Int -> Element
398+mkNum :: ListMarker -> Int -> Element
382−mkNum markers marker numid =
399+mkNum marker numid =
383 mknode "w:num" [("w:numId",show numid)]
400 mknode "w:num" [("w:numId",show numid)]
384− $ mknode "w:abstractNumId" [("w:val",show absnumid)] ()
401+ $ mknode "w:abstractNumId" [("w:val",listMarkerToId marker)] ()
385 : case marker of
402 : case marker of
386 NoMarker -> []
403 NoMarker -> []
387 BulletMarker -> []
404 BulletMarker -> []
388 NumberMarker _ _ start ->
405 NumberMarker _ _ start ->
389 map (\lvl -> mknode "w:lvlOverride" [("w:ilvl",show (lvl :: Int))]
406 map (\lvl -> mknode "w:lvlOverride" [("w:ilvl",show (lvl :: Int))]
390 $ mknode "w:startOverride" [("w:val",show start)] ()) [0..6]
407 $ mknode "w:startOverride" [("w:val",show start)] ()) [0..6]
391− where absnumid = fromMaybe 0 $ M.lookup marker markers
392
408
393−mkAbstractNum :: (ListMarker,Int) -> IO Element
409+mkAbstractNum :: ListMarker -> IO Element
394−mkAbstractNum (marker,numid) = do
410+mkAbstractNum marker = do
395 nsid <- randomRIO (0x10000000 :: Integer, 0xFFFFFFFF :: Integer)
411 nsid <- randomRIO (0x10000000 :: Integer, 0xFFFFFFFF :: Integer)
396− return $ mknode "w:abstractNum" [("w:abstractNumId",show numid)]
412+ return $ mknode "w:abstractNum" [("w:abstractNumId",listMarkerToId marker)]
397 $ mknode "w:nsid" [("w:val", printf "%8x" nsid)] ()
413 $ mknode "w:nsid" [("w:val", printf "%8x" nsid)] ()
398 : mknode "w:multiLevelType" [("w:val","multilevel")] ()
414 : mknode "w:multiLevelType" [("w:val","multilevel")] ()
399 : map (mkLvl marker) [0..6]
415 : map (mkLvl marker) [0..6]
@@ -594,11 +610,6 @@ addList :: ListMarker -> WS ()
594addList marker = do
610addList marker = do
595 lists <- gets stLists
611 lists <- gets stLists
596 modify $ \st -> st{ stLists = lists ++ [marker] }
612 modify $ \st -> st{ stLists = lists ++ [marker] }
597− numStyles <- gets stNumStyles
598− case M.lookup marker numStyles of
599− Just _ -> return ()
600− Nothing -> modify $ \st ->
601− st{ stNumStyles = M.insert marker (M.size numStyles + 1) numStyles }
602
613
603listItemToOpenXML :: WriterOptions -> Int -> [Block] -> WS [Element]
614listItemToOpenXML :: WriterOptions -> Int -> [Block] -> WS [Element]
604listItemToOpenXML _ _ [] = return []
615listItemToOpenXML _ _ [] = return []