Skip to content

Commit

Permalink
Docx writer: ensure that elements in settings are ordered correctly.
Browse files Browse the repository at this point in the history
The elements must occur in a specific order. This was being
messed up when integrating a custom reference.docx. Closes #9264.
  • Loading branch information
jgm committed Dec 18, 2023
1 parent 3abbf97 commit c9bf4da
Show file tree
Hide file tree
Showing 37 changed files with 99 additions and 24 deletions.
123 changes: 99 additions & 24 deletions src/Text/Pandoc/Writers/Docx.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import Codec.Archive.Zip
toEntry,
Entry(eRelativePath) )
import Control.Applicative ((<|>))
import Control.Monad (MonadPlus(mplus), unless, when)
import Control.Monad (MonadPlus(mplus), unless, when, foldM)
import Control.Monad.Except (catchError, throwError)
import Control.Monad.Reader
( asks, MonadReader(local), MonadTrans(lift), ReaderT(runReaderT) )
Expand Down Expand Up @@ -508,30 +508,105 @@ writeDocx opts doc = do
-- adds references to footnotes or endnotes we don't have...
-- we do, however, copy some settings over from reference
let settingsPath = "word/settings.xml"
settingsList = [ "zoom"
, "mirrorMargins"

settingsEntry <- copyChildren refArchive distArchive settingsPath epochtime
-- note: these must go in the following order:
[ "writeProtection"
, "view"
, "zoom"
, "removePersonalInformation"
, "removeDateAndTime"
, "doNotDisplayPageBoundaries"
, "displayBackgroundShape"
, "printPostScriptOverText"
, "printFractionalCharacterWidth"
, "printFormsData"
, "embedTrueTypeFonts"
, "embedSystemFonts"
, "saveSubsetFonts"
, "saveFormsData"
, "mirrorMargins"
, "alignBordersAndEdges"
, "bordersDoNotSurroundHeader"
, "bordersDoNotSurroundFooter"
, "gutterAtTop"
, "hideSpellingErrors"
, "hideGrammaticalErrors"
, "activeWritingStyle"
, "proofState"
, "formsDesign"
, "attachedTemplate"
, "linkStyles"
, "stylePaneFormatFilter"
, "stylePaneSortMethod"
, "documentType"
, "mailMerge"
, "revisionView"
, "trackRevisions"
, "doNotTrackMoves"
, "doNotTrackFormatting"
, "documentProtection"
, "autoFormatOverride"
, "styleLockTheme"
, "styleLockQFSet"
, "defaultTabStop"
, "autoHyphenation"
, "consecutiveHyphenLimit"
, "hyphenationZone"
, "doNotHyphenateCaps"
, "showEnvelope"
, "summaryLength"
, "clickAndTypeStyle"
, "defaultTableStyle"
, "evenAndOddHeaders"
, "bookFoldRevPrinting"
, "bookFoldPrinting"
, "bookFoldPrintingSheets"
, "drawingGridHorizontalSpacing"
, "drawingGridVerticalSpacing"
, "displayHorizontalDrawingGridEvery"
, "displayVerticalDrawingGridEvery"
, "doNotUseMarginsForDrawingGridOrigin"
, "drawingGridHorizontalOrigin"
, "drawingGridVerticalOrigin"
, "doNotShadeFormData"
, "noPunctuationKerning"
, "characterSpacingControl"
, "printTwoOnOne"
, "strictFirstAndLastChars"
, "noLineBreaksAfter"
, "noLineBreaksBefore"
, "savePreviewPicture"
, "mathPr"
, "doNotValidateAgainstSchema"
, "saveInvalidXml"
, "ignoreMixedContent"
, "alwaysShowPlaceholderText"
, "doNotDemarcateInvalidXml"
, "saveXmlDataOnly"
, "useXSLTWhenSaving"
, "saveThroughXslt"
, "showXMLTags"
, "alwaysMergeEmptyNamespace"
, "updateFields"
, "hdrShapeDefaults"
, "footnotePr"
, "endnotePr"
, "compat"
, "docVars"
, "rsids"
, "attachedSchema"
, "themeFontLang"
, "clrSchemeMapping"
, "doNotIncludeSubdocsInStats"
, "doNotAutoCompressPictures"
, "forceUpgrade"
, "captions"
, "readModeInkLockDown"
, "smartTagType"
, "shapeDefaults"
, "doNotEmbedSmartTags"
, "decimalSymbol"
, "listSeparator"
, "autoHyphenation"
, "consecutiveHyphenLimit"
, "hyphenationZone"
, "doNotHyphenateCap"
, "evenAndOddHeaders"
, "proofState"
, "compat"
]
settingsEntry <- copyChildren refArchive distArchive settingsPath epochtime settingsList
, "listSeparator" ]

let entryFromArchive arch path =
maybe (throwError $ PandocSomeError
Expand Down Expand Up @@ -639,17 +714,17 @@ copyChildren :: (PandocMonad m)
copyChildren refArchive distArchive path timestamp elNames = do
ref <- parseXml refArchive distArchive path
dist <- parseXml distArchive distArchive path
let elsToCopy =
map cleanElem $ filterChildrenName (\e -> qName e `elem` elNames) ref
let elsToKeep =
[e | Elem e <- elContent dist, not (any (hasSameNameAs e) elsToCopy)]
return $ toEntry path timestamp $ renderXml dist{
elContent = map Elem elsToKeep ++ map Elem elsToCopy
}
els <- foldM (addEl ref dist) [] (reverse elNames)
return $ toEntry path timestamp
$ renderXml dist{ elContent = map cleanElem els }
where
hasSameNameAs (Element {elName = n1}) (Element {elName = n2}) =
qName n1 == qName n2
cleanElem el@Element{elName=name} = el{elName=name{qURI=Nothing}}
addEl ref dist els name =
case filterChildName (hasName name) ref `mplus`
filterChildName (hasName name) dist of
Just el -> pure (el : els)
Nothing -> pure els
hasName name = (== name) . qName
cleanElem el@Element{elName=name} = Elem el{elName=name{qURI=Nothing}}

-- this is the lowest number used for a list numId
baseListId :: Int
Expand Down
Binary file modified test/docx/golden/block_quotes.docx
Binary file not shown.
Binary file modified test/docx/golden/codeblock.docx
Binary file not shown.
Binary file modified test/docx/golden/comments.docx
Binary file not shown.
Binary file modified test/docx/golden/custom_style_no_reference.docx
Binary file not shown.
Binary file modified test/docx/golden/custom_style_preserve.docx
Binary file not shown.
Binary file modified test/docx/golden/custom_style_reference.docx
Binary file not shown.
Binary file modified test/docx/golden/definition_list.docx
Binary file not shown.
Binary file modified test/docx/golden/document-properties-short-desc.docx
Binary file not shown.
Binary file modified test/docx/golden/document-properties.docx
Binary file not shown.
Binary file modified test/docx/golden/headers.docx
Binary file not shown.
Binary file modified test/docx/golden/image.docx
Binary file not shown.
Binary file modified test/docx/golden/inline_code.docx
Binary file not shown.
Binary file modified test/docx/golden/inline_formatting.docx
Binary file not shown.
Binary file modified test/docx/golden/inline_images.docx
Binary file not shown.
Binary file modified test/docx/golden/link_in_notes.docx
Binary file not shown.
Binary file modified test/docx/golden/links.docx
Binary file not shown.
Binary file modified test/docx/golden/lists.docx
Binary file not shown.
Binary file modified test/docx/golden/lists_continuing.docx
Binary file not shown.
Binary file modified test/docx/golden/lists_div_bullets.docx
Binary file not shown.
Binary file modified test/docx/golden/lists_multiple_initial.docx
Binary file not shown.
Binary file modified test/docx/golden/lists_restarting.docx
Binary file not shown.
Binary file modified test/docx/golden/nested_anchors_in_header.docx
Binary file not shown.
Binary file modified test/docx/golden/notes.docx
Binary file not shown.
Binary file modified test/docx/golden/raw-blocks.docx
Binary file not shown.
Binary file modified test/docx/golden/raw-bookmarks.docx
Binary file not shown.
Binary file modified test/docx/golden/table_one_row.docx
Binary file not shown.
Binary file modified test/docx/golden/table_with_list_cell.docx
Binary file not shown.
Binary file modified test/docx/golden/tables-default-widths.docx
Binary file not shown.
Binary file modified test/docx/golden/tables.docx
Binary file not shown.
Binary file modified test/docx/golden/tables_separated_with_rawblock.docx
Binary file not shown.
Binary file modified test/docx/golden/track_changes_deletion.docx
Binary file not shown.
Binary file modified test/docx/golden/track_changes_insertion.docx
Binary file not shown.
Binary file modified test/docx/golden/track_changes_move.docx
Binary file not shown.
Binary file modified test/docx/golden/track_changes_scrubbed_metadata.docx
Binary file not shown.
Binary file modified test/docx/golden/unicode.docx
Binary file not shown.
Binary file modified test/docx/golden/verbatim_subsuper.docx
Binary file not shown.

0 comments on commit c9bf4da

Please sign in to comment.