git.iko.soy/typeable/pandoc
on master help sign in
Docx Reader: Fix hdr auto-id when already auto-id.

If header anchors (bookmarks in a header paragraph) already have an auto-id, which will happen if they're generated by pandoc, we don't want to rename it twice, and thus end up with an unnecessary number at the end. So we add a state value to check if we're in a header. If we are, we don't rename the bookmark -- wait until we rename it in our header handling.

commit4b2d07a642c9ab570a8da64deca32a4139b2268b authorJesse Rosenthal <jrosenthal@jhu.edu> dateWed 16 Jul 2014, 03:44 (12 years ago) parenta4671af
1 file changed+19−11
src/Text/Pandoc/Readers/Docx.hs+19−11
src/Text/Pandoc/Readers/Docx.hs+19−11
@@ -105,6 +105,7 @@ readDocx opts bytes =
105105 Left _ -> error $ "couldn't parse docx file"
106106
107107data DState = DState { docxAnchorMap :: M.Map String String
108+ , docxInHeaderBlock :: Bool
108109 , docxInTexSubscript :: Bool }
109110
110111data DEnv = DEnv { docxOptions :: ReaderOptions
@@ -292,17 +293,22 @@ parPartToInlines (BookMark _ anchor) =
292293 -- We record these, so we can make sure not to overwrite
293294 -- user-defined anchor links with header auto ids.
294295 do
296+ -- get whether we're in a header.
297+ inHdrBool <- gets docxInHeaderBlock
295298 -- Get the anchor map.
296299 anchorMap <- gets docxAnchorMap
297− -- Check to see if the id is already in there. Rewrite if
298− -- necessary. This will have the possible effect of rewriting
299− -- user-defined anchor links. However, since these are not defined
300− -- in pandoc, it seems like a necessary evil to avoid an extra
301− -- pass.
302− let newAnchor = case anchor `elem` (M.elems anchorMap) of
303− True -> uniqueIdent [Str anchor] (M.elems anchorMap)
304− False -> anchor
305− return [Span (anchor, ["anchor"], []) []]
300+ -- We don't want to rewrite if we're in a header, since we'll take
301+ -- care of that later, when we make the header anchor. If the
302+ -- bookmark were already in uniqueIdent form, this would lead to a
303+ -- duplication. Otherwise, we check to see if the id is already in
304+ -- there. Rewrite if necessary. This will have the possible effect
305+ -- of rewriting user-defined anchor links. However, since these
306+ -- are not defined in pandoc, it seems like a necessary evil to
307+ -- avoid an extra pass.
308+ let newAnchor =
309+ if not inHdrBool && anchor `elem` (M.elems anchorMap)
310+ then uniqueIdent [Str anchor] (M.elems anchorMap)
311+ else anchor
306312 modify $ \s -> s { docxAnchorMap = M.insert anchor newAnchor anchorMap}
307313 return [Span (newAnchor, ["anchor"], []) []]
308314parPartToInlines (Drawing fp bs) = do
@@ -493,7 +499,7 @@ makeHeaderAnchor (Header n (_, classes, kvs) ils)
493499 do
494500 hdrIDMap <- gets docxAnchorMap
495501 let newIdent = uniqueIdent ils (M.elems hdrIDMap)
496− updateDState $ \s -> s {docxAnchorMap = M.insert ident newIdent hdrIDMap}
502+ modify $ \s -> s {docxAnchorMap = M.insert ident newIdent hdrIDMap}
497503 return $ Header n (newIdent, classes, kvs) (ils \\ (x:xs))
498504-- Otherwise we just give it a name, and register that name (associate
499505-- it with itself.)
@@ -537,7 +543,8 @@ bodyPartToBlocks (Paragraph pPr parparts)
537543 [CodeBlock ("", [], []) (concatMap parPartToString parparts)]
538544bodyPartToBlocks (Paragraph pPr parparts)
539545 | any isHeaderContainer (parStyleToContainers pPr) = do
540− ils <- parPartsToInlines parparts >>= (return . normalizeSpaces)
546+ ils <-withDState (\s -> s{docxInHeaderBlock = True}) $
547+ parPartsToInlines parparts >>= (return . normalizeSpaces)
541548 let (Container hdrFun) = head $ filter isHeaderContainer (parStyleToContainers pPr)
542549 Header n attr _ = hdrFun []
543550 hdr <- makeHeaderAnchor $ Header n attr ils
@@ -620,6 +627,7 @@ bodyToBlocks (Body bps) = do
620627docxToBlocks :: ReaderOptions -> Docx -> [Block]
621628docxToBlocks opts d@(Docx (Document _ body)) =
622629 let dState = DState { docxAnchorMap = M.empty
630+ , docxInHeaderBlock = False
623631 , docxInTexSubscript = False}
624632 dEnv = DEnv { docxOptions = opts
625633 , docxDocument = d}