Docx writer: ensure that documents don't start with a section separator

Any leading section separator is removed from the result.

Closes: #10578
This commit is contained in:
Albert Krewinkel
2025-08-11 18:08:53 -07:00
committed by John MacFarlane
parent 0bbbdbcdb6
commit 529b6d1667
2 changed files with 26 additions and 11 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
{-# LANGUAGE OverloadedStrings #-}
{- |
Module : Text.Pandoc.Writers.Docx
Copyright : Copyright (C) 2012-2024 John MacFarlane
Copyright : Copyright (C) 2012-2025 John MacFarlane
License : GNU GPL, version 2 or above
Maintainer : John MacFarlane <jgm@berkeley.edu>
+25 -10
View File
@@ -9,7 +9,7 @@
{-# LANGUAGE TypeApplications #-}
{- |
Module : Text.Pandoc.Writers.Docx
Copyright : Copyright (C) 2012-2024 John MacFarlane
Copyright : Copyright (C) 2012-2025 John MacFarlane
License : GNU GPL, version 2 or above
Maintainer : John MacFarlane <jgm@berkeley.edu>
@@ -20,7 +20,7 @@ Conversion of 'Pandoc' documents to docx.
-}
module Text.Pandoc.Writers.Docx.OpenXML ( writeOpenXML, maxListLevel ) where
import Control.Monad (when, unless)
import Control.Monad ((>=>), when, unless)
import Control.Applicative ((<|>))
import Control.Monad.Except (catchError)
import Crypto.Hash (hashWith, SHA1(SHA1))
@@ -220,6 +220,15 @@ makeLOT opts = do
]) -- w:sdtContent
]] -- w:sdt
-- | Separator element between sections
sectionSeparator :: PandocMonad m => WS m (Maybe Content)
sectionSeparator = do
asks envSectPr >>= \case
Just sectPrElem -> pure $
Just $ Elem (mknode "w:p" [] (mknode "w:pPr" [] [sectPrElem]))
Nothing -> pure
Nothing
-- | Convert Pandoc document to rendered document contents plus two lists of
-- OpenXML elements (footnotes and comments).
writeOpenXML :: PandocMonad m
@@ -317,7 +326,17 @@ writeOpenXML opts (Pandoc meta blocks) = do
-- | Convert a list of Pandoc blocks to OpenXML.
blocksToOpenXML :: (PandocMonad m) => WriterOptions -> [Block] -> WS m [Content]
blocksToOpenXML opts = fmap concat . mapM (blockToOpenXML opts) . separateTables . filter (not . isForeignRawBlock)
blocksToOpenXML opts =
fmap concat . mapM (blockToOpenXML opts)
. separateTables . filter (not . isForeignRawBlock)
>=>
\case
a@(x:xs) -> do
sep <- sectionSeparator
if Just x == sep
then pure xs
else pure a
[] -> pure []
isForeignRawBlock :: Block -> Bool
isForeignRawBlock (RawBlock format _) = format /= "openxml"
@@ -395,13 +414,9 @@ blockToOpenXML' opts (Header lev (ident,_,kvs) lst) = do
Nothing -> return []
else return []
contents <- (number ++) <$> inlinesToOpenXML opts lst
sectpr <- asks envSectPr
let addSectionBreak
| isSection
, Just sectPrElem <- sectpr
= (Elem (mknode "w:p" []
(mknode "w:pPr" [] [sectPrElem])) :)
| otherwise = id
addSectionBreak <- sectionSeparator >>= \case
Just sep | isSection -> pure (sep:)
_ -> pure id
addSectionBreak <$>
if T.null ident
then return [Elem $ mknode "w:p" [] (map Elem paraProps ++ contents)]