@@ -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
@@ -112,18 +113,13 @@ data DEnv = DEnv { docxOptions :: ReaderOptions
112113
113114type DocxContext = ReaderT DEnv (State DState)
114115
115−updateDState :: (DState -> DState) -> DocxContext ()
116−updateDState f = do
117− st <- get
118− put $ f st
119−
120−withDState :: DState -> DocxContext a -> DocxContext a
121−withDState ds dctx = do
122− ds' <- get
123− updateDState (\_ -> ds)
124− dctx' <- dctx
125− put ds'
126− return dctx'
116+withDState :: (DState -> DState) -> DocxContext a -> DocxContext a
117+withDState f dctx = do
118+ ds <- get
119+ modify f
120+ ctx' <- dctx
121+ put ds
122+ return ctx'
127123
128124evalDocxContext :: DocxContext a -> DEnv -> DState -> a
129125evalDocxContext ctx env st = evalState (runReaderT ctx env) st
@@ -297,18 +293,24 @@ parPartToInlines (BookMark _ anchor) =
297293 -- We record these, so we can make sure not to overwrite
298294 -- user-defined anchor links with header auto ids.
299295 do
296+ -- get whether we're in a header.
297+ inHdrBool <- gets docxInHeaderBlock
300298 -- Get the anchor map.
301299 anchorMap <- gets docxAnchorMap
302− -- Check to see if the id is already in there. Rewrite if
303− -- necessary. This will have the possible effect of rewriting
304− -- user-defined anchor links. However, since these are not defined
305− -- in pandoc, it seems like a necessary evil to avoid an extra
306− -- pass.
307− let newAnchor = case anchor `elem` (M.elems anchorMap) of
308− True -> uniqueIdent [Str anchor] (M.elems anchorMap)
309− False -> anchor
310− updateDState $ \s -> s { docxAnchorMap = M.insert anchor newAnchor anchorMap}
311− 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
312+ modify $ \s -> s { docxAnchorMap = M.insert anchor newAnchor anchorMap}
313+ return [Span (newAnchor, ["anchor"], []) []]
312314parPartToInlines (Drawing fp bs) = do
313315 return $ case True of -- TODO: add self-contained images
314316 True -> [Image [] (fp, "")]
@@ -427,8 +429,8 @@ oMathElemToTexString (Matrix bases) = do
427429 s <- liftM (intercalate " \\\\\n")(mapM rowString bases)
428430 return $ printf "\\begin{matrix}\n%s\n\\end{matrix}" s
429431oMathElemToTexString (NAry style sub sup base) | Just c <- nAryChar style = do
430− ds <- gets (\s -> s{docxInTexSubscript = True})
431− subString <- withDState ds $ concatMapM oMathElemToTexString sub
432+ subString <- withDState (\s -> s{docxInTexSubscript = True}) $
433+ concatMapM oMathElemToTexString sub
432434 supString <- concatMapM oMathElemToTexString sup
433435 baseString <- baseToTexString base
434436 return $ case M.lookup c uniconvMap of
@@ -497,7 +499,7 @@ makeHeaderAnchor (Header n (_, classes, kvs) ils)
497499 do
498500 hdrIDMap <- gets docxAnchorMap
499501 let newIdent = uniqueIdent ils (M.elems hdrIDMap)
500− updateDState $ \s -> s {docxAnchorMap = M.insert ident newIdent hdrIDMap}
502+ modify $ \s -> s {docxAnchorMap = M.insert ident newIdent hdrIDMap}
501503 return $ Header n (newIdent, classes, kvs) (ils \\ (x:xs))
502504-- Otherwise we just give it a name, and register that name (associate
503505-- it with itself.)
@@ -505,7 +507,7 @@ makeHeaderAnchor (Header n (_, classes, kvs) ils) =
505507 do
506508 hdrIDMap <- gets docxAnchorMap
507509 let newIdent = uniqueIdent ils (M.elems hdrIDMap)
508− updateDState $ \s -> s {docxAnchorMap = M.insert newIdent newIdent hdrIDMap}
510+ modify $ \s -> s {docxAnchorMap = M.insert newIdent newIdent hdrIDMap}
509511 return $ Header n (newIdent, classes, kvs) ils
510512makeHeaderAnchor blk = return blk
511513
@@ -541,7 +543,8 @@ bodyPartToBlocks (Paragraph pPr parparts)
541543 [CodeBlock ("", [], []) (concatMap parPartToString parparts)]
542544bodyPartToBlocks (Paragraph pPr parparts)
543545 | any isHeaderContainer (parStyleToContainers pPr) = do
544− ils <- parPartsToInlines parparts >>= (return . normalizeSpaces)
546+ ils <-withDState (\s -> s{docxInHeaderBlock = True}) $
547+ parPartsToInlines parparts >>= (return . normalizeSpaces)
545548 let (Container hdrFun) = head $ filter isHeaderContainer (parStyleToContainers pPr)
546549 Header n attr _ = hdrFun []
547550 hdr <- makeHeaderAnchor $ Header n attr ils
@@ -624,6 +627,7 @@ bodyToBlocks (Body bps) = do
624627docxToBlocks :: ReaderOptions -> Docx -> [Block]
625628docxToBlocks opts d@(Docx (Document _ body)) =
626629 let dState = DState { docxAnchorMap = M.empty
630+ , docxInHeaderBlock = False
627631 , docxInTexSubscript = False}
628632 dEnv = DEnv { docxOptions = opts
629633 , docxDocument = d}