@@ -89,10 +89,12 @@ import Data.List (delete, stripPrefix, (\\), intersperse, intersect)
8989import Data.Monoid
9090import Text.TeXMath (writeTeX)
9191import qualified Text.TeXMath.Types as TM
92+import Data.Default (Default)
9293import qualified Data.ByteString.Lazy as B
9394import qualified Data.Map as M
9495import Control.Monad.Reader
9596import Control.Monad.State
97+import Control.Applicative ((<$>))
9698
9799readDocx :: ReaderOptions
98100 -> B.ByteString
@@ -104,25 +106,19 @@ readDocx opts bytes =
104106 Left _ -> error $ "couldn't parse docx file"
105107
106108data DState = DState { docxAnchorMap :: M.Map String String
107− , docxMediaBag :: MediaBag
108− , docxInHeaderBlock :: Bool}
109+ , docxMediaBag :: MediaBag }
109110
110−defaultDState :: DState
111−defaultDState = DState { docxAnchorMap = M.empty
112− , docxMediaBag = mempty
113− , docxInHeaderBlock = False}
111+instance Default DState where
112+ def = DState { docxAnchorMap = M.empty
113+ , docxMediaBag = mempty }
114114
115−data DEnv = DEnv { docxOptions :: ReaderOptions}
115+data DEnv = DEnv { docxOptions :: ReaderOptions
116+ , docxInHeaderBlock :: Bool }
116117
117−type DocxContext = ReaderT DEnv (State DState)
118+instance Default DEnv where
119+ def = DEnv def False
118120
119−withDState :: (DState -> DState) -> DocxContext a -> DocxContext a
120−withDState f dctx = do
121− ds <- get
122− modify f
123− ctx' <- dctx
124− put ds
125− return ctx'
121+type DocxContext = ReaderT DEnv (State DState)
126122
127123evalDocxContext :: DocxContext a -> DEnv -> DState -> a
128124evalDocxContext ctx env st = evalState (runReaderT ctx env) st
@@ -161,7 +157,7 @@ isEmptyPar (Paragraph _ parParts) =
161157 isEmptyElem (TextRun s) = trim s == ""
162158 isEmptyElem _ = True
163159isEmptyPar _ = False
164−
160+
165161bodyPartsToMeta' :: [BodyPart] -> DocxContext (M.Map String MetaValue)
166162bodyPartsToMeta' [] = return M.empty
167163bodyPartsToMeta' (bp : bps)
@@ -170,7 +166,7 @@ bodyPartsToMeta' (bp : bps)
170166 , (Just metaField) <- M.lookup c metaStyles = do
171167 inlines <- parPartsToInlines parParts
172168 remaining <- bodyPartsToMeta' bps
173− let
169+ let
174170 f (MetaInlines ils) (MetaInlines ils') = MetaBlocks [Para ils, Para ils']
175171 f (MetaInlines ils) (MetaBlocks blks) = MetaBlocks ((Para ils) : blks)
176172 f m (MetaList mv) = MetaList (m : mv)
@@ -350,7 +346,7 @@ parPartToInlines (BookMark _ anchor) =
350346 -- user-defined anchor links with header auto ids.
351347 do
352348 -- get whether we're in a header.
353− inHdrBool <- gets docxInHeaderBlock
349+ inHdrBool <- asks docxInHeaderBlock
354350 -- Get the anchor map.
355351 anchorMap <- gets docxAnchorMap
356352 -- We don't want to rewrite if we're in a header, since we'll take
@@ -365,7 +361,8 @@ parPartToInlines (BookMark _ anchor) =
365361 if not inHdrBool && anchor `elem` (M.elems anchorMap)
366362 then uniqueIdent [Str anchor] (M.elems anchorMap)
367363 else anchor
368− modify $ \s -> s { docxAnchorMap = M.insert anchor newAnchor anchorMap}
364+ unless inHdrBool
365+ (modify $ \s -> s { docxAnchorMap = M.insert anchor newAnchor anchorMap})
369366 return [Span (newAnchor, ["anchor"], []) []]
370367parPartToInlines (Drawing fp bs) = do
371368 mediaBag <- gets docxMediaBag
@@ -509,7 +506,7 @@ oMathRunStyleToTextType mrPr
509506 | Normal <- oMathRunTextStyle mrPr =
510507 Just $ TM.TextNormal
511508 | Styled scr sty <- oMathRunTextStyle mrPr
512− ,Just OBold <- sty
509+ ,Just OBold <- sty
513510 , Just OSansSerif <- scr =
514511 Just $ TM.TextSansSerifBold
515512 | Styled scr sty <- oMathRunTextStyle mrPr
@@ -555,7 +552,7 @@ oMathRunStyleToTextType mrPr
555552 | otherwise = Nothing
556553
557554
558−
555+
559556baseToExp :: Base -> DocxContext TM.Exp
560557baseToExp (Base mathElems) =
561558 concatMapM oMathElemToExps mathElems >>= (return . TM.EGrouped)
@@ -563,7 +560,7 @@ baseToExp (Base mathElems) =
563560-- an ungrouped version of baseToExp
564561baseToExp' :: Base -> DocxContext [TM.Exp]
565562baseToExp' (Base mathElems) =
566− concatMapM oMathElemToExps mathElems
563+ concatMapM oMathElemToExps mathElems
567564
568565
569566isAnchorSpan :: Inline -> Bool
@@ -631,8 +628,8 @@ bodyPartToBlocks (Paragraph pPr parparts)
631628 [CodeBlock ("", [], []) (concatMap parPartToString parparts)]
632629bodyPartToBlocks (Paragraph pPr parparts)
633630 | any isHeaderContainer (parStyleToContainers pPr) = do
634− ils <-withDState (\s -> s{docxInHeaderBlock = True}) $
635− parPartsToInlines parparts >>= (return . normalizeSpaces)
631+ ils <- normalizeSpaces <$> local (\s -> s{docxInHeaderBlock = True})
632+ (parPartsToInlines parparts)
636633 let (Container hdrFun) = head $ filter isHeaderContainer (parStyleToContainers pPr)
637634 Header n attr _ = hdrFun []
638635 hdr <- makeHeaderAnchor $ Header n attr ils
@@ -717,10 +714,8 @@ bodyToOutput (Body bps) = do
717714
718715docxToOutput :: ReaderOptions -> Docx -> (Meta, [Block], MediaBag)
719716docxToOutput opts (Docx (Document _ body)) =
720− let dState = defaultDState
721− dEnv = DEnv { docxOptions = opts }
722− in
723− evalDocxContext (bodyToOutput body) dEnv dState
717+ let dEnv = def { docxOptions = opts} in
718+ evalDocxContext (bodyToOutput body) dEnv def
724719
725720
726721ilToCode :: Inline -> String