From d596b0db8321cdb9c018ac8037d301291d0cc63c Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Mon, 18 Mar 2013 19:31:48 -0700 Subject: Docx writer: Fixed rendering of display math in lists. In 1.11 and 1.11.1, display math in lists rendered as a new list item. Now it always appears centered, just as outside of lists, and in proper display math style, no matter how far indented the containing list item is. Closes #784. --- src/Text/Pandoc/Writers/Docx.hs | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) (limited to 'src/Text') diff --git a/src/Text/Pandoc/Writers/Docx.hs b/src/Text/Pandoc/Writers/Docx.hs index 7a782efb6..0549772af 100644 --- a/src/Text/Pandoc/Writers/Docx.hs +++ b/src/Text/Pandoc/Writers/Docx.hs @@ -105,12 +105,13 @@ writeDocx :: WriterOptions -- ^ Writer options -> IO BL.ByteString writeDocx opts doc@(Pandoc (Meta tit auths date) _) = do let datadir = writerUserDataDir opts + let doc' = bottomUp (concatMap fixDisplayMath) doc refArchive <- liftM (toArchive . toLazy) $ case writerReferenceDocx opts of Just f -> B.readFile f Nothing -> readDataFile datadir "reference.docx" - ((contents, footnotes), st) <- runStateT (writeOpenXML opts{writerWrapText = False} doc) + ((contents, footnotes), st) <- runStateT (writeOpenXML opts{writerWrapText = False} doc') defaultWriterState epochtime <- floor `fmap` getPOSIXTime let imgs = M.elems $ stImages st @@ -420,19 +421,17 @@ blockToOpenXML opts (Header lev (ident,_,_) lst) = do blockToOpenXML opts (Plain lst) = blockToOpenXML opts (Para lst) -- title beginning with fig: indicates that the image is a figure blockToOpenXML opts (Para [Image alt (src,'f':'i':'g':':':tit)]) = do - paraProps <- getParaProps + paraProps <- getParaProps False contents <- inlinesToOpenXML opts [Image alt (src,tit)] captionNode <- withParaProp (pStyle "ImageCaption") $ blockToOpenXML opts (Para alt) return $ mknode "w:p" [] (paraProps ++ contents) : captionNode -blockToOpenXML opts (Para lst) - | any isDisplayMath lst && not (all isDisplayMath lst) = do - -- chop into several paragraphs so each displaymath is its own - let lsts = groupBy (\x y -> (isDisplayMath x && isDisplayMath y) || - not (isDisplayMath x || isDisplayMath y)) lst - blocksToOpenXML opts (map Para lsts) - | otherwise = do - paraProps <- getParaProps +-- fixDisplayMath sometimes produces a Para [] as artifact +blockToOpenXML _ (Para []) = return [] +blockToOpenXML opts (Para lst) = do + paraProps <- getParaProps $ case lst of + [Math DisplayMath _] -> True + _ -> False contents <- inlinesToOpenXML opts lst return [mknode "w:p" [] (paraProps ++ contents)] blockToOpenXML _ (RawBlock format str) @@ -571,12 +570,12 @@ withTextProp d p = do popTextProp return res -getParaProps :: WS [Element] -getParaProps = do +getParaProps :: Bool -> WS [Element] +getParaProps displayMathPara = do props <- gets stParaProperties listLevel <- gets stListLevel numid <- gets stListNumId - let listPr = if listLevel >= 0 + let listPr = if listLevel >= 0 && not displayMathPara then [ mknode "w:numPr" [] [ mknode "w:numId" [("w:val",show numid)] () , mknode "w:ilvl" [("w:val",show listLevel)] () ] @@ -775,3 +774,18 @@ parseXml refArchive relpath = isDisplayMath :: Inline -> Bool isDisplayMath (Math DisplayMath _) = True isDisplayMath _ = False + +stripLeadingTrailingSpace :: [Inline] -> [Inline] +stripLeadingTrailingSpace = go . reverse . go . reverse + where go (Space:xs) = xs + go xs = xs + +fixDisplayMath :: Block -> [Block] +fixDisplayMath (Plain lst) = fixDisplayMath (Para lst) +fixDisplayMath (Para lst) + | any isDisplayMath lst && not (all isDisplayMath lst) = + -- chop into several paragraphs so each displaymath is its own + map (Para . stripLeadingTrailingSpace) $ + groupBy (\x y -> (isDisplayMath x && isDisplayMath y) || + not (isDisplayMath x || isDisplayMath y)) lst +fixDisplayMath x = [x] -- cgit v1.2.3