aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <[email protected]>2025-04-05 13:35:55 -0700
committerJohn MacFarlane <[email protected]>2025-04-05 13:48:46 -0700
commitaf57648e58d2babe17dbc30935a1b1f8c888f083 (patch)
treeaf3c1514683a4ca3c1578111ca61731c7b92871c
parentf8f7c29fb81468a7b559e9590089152cee5d0b04 (diff)
Docx writer: preserve Relationships for images from reference docx.
This should allow one to include an image in a reference.docx and reference it in an openxml template. Closes #10759.
-rw-r--r--src/Text/Pandoc/Writers/Docx.hs60
-rw-r--r--test/docx/golden/block_quotes.docxbin10691 -> 10689 bytes
-rw-r--r--test/docx/golden/codeblock.docxbin10508 -> 10507 bytes
-rw-r--r--test/docx/golden/comments.docxbin10839 -> 10838 bytes
-rw-r--r--test/docx/golden/custom_style_no_reference.docxbin10610 -> 10609 bytes
-rw-r--r--test/docx/golden/custom_style_preserve.docxbin11235 -> 11235 bytes
-rw-r--r--test/docx/golden/custom_style_reference.docxbin12543 -> 12542 bytes
-rw-r--r--test/docx/golden/definition_list.docxbin10498 -> 10498 bytes
-rw-r--r--test/docx/golden/document-properties-short-desc.docxbin10512 -> 10512 bytes
-rw-r--r--test/docx/golden/document-properties.docxbin10998 -> 10997 bytes
-rw-r--r--test/docx/golden/headers.docxbin10652 -> 10652 bytes
-rw-r--r--test/docx/golden/image.docxbin27388 -> 27380 bytes
-rw-r--r--test/docx/golden/inline_code.docxbin10449 -> 10448 bytes
-rw-r--r--test/docx/golden/inline_formatting.docxbin10625 -> 10624 bytes
-rw-r--r--test/docx/golden/inline_images.docxbin27384 -> 27380 bytes
-rw-r--r--test/docx/golden/link_in_notes.docxbin10666 -> 10661 bytes
-rw-r--r--test/docx/golden/links.docxbin10840 -> 10839 bytes
-rw-r--r--test/docx/golden/lists.docxbin11034 -> 11031 bytes
-rw-r--r--test/docx/golden/lists_9994.docxbin10786 -> 10785 bytes
-rw-r--r--test/docx/golden/lists_continuing.docxbin10700 -> 10699 bytes
-rw-r--r--test/docx/golden/lists_div_bullets.docxbin10684 -> 10682 bytes
-rw-r--r--test/docx/golden/lists_multiple_initial.docxbin10916 -> 10915 bytes
-rw-r--r--test/docx/golden/lists_restarting.docxbin10697 -> 10696 bytes
-rw-r--r--test/docx/golden/nested_anchors_in_header.docxbin10841 -> 10842 bytes
-rw-r--r--test/docx/golden/notes.docxbin10611 -> 10612 bytes
-rw-r--r--test/docx/golden/raw-blocks.docxbin10542 -> 10541 bytes
-rw-r--r--test/docx/golden/raw-bookmarks.docxbin10681 -> 10680 bytes
-rw-r--r--test/docx/golden/table_one_row.docxbin10520 -> 10519 bytes
-rw-r--r--test/docx/golden/table_with_list_cell.docxbin10970 -> 10969 bytes
-rw-r--r--test/docx/golden/tables-default-widths.docxbin10883 -> 10879 bytes
-rw-r--r--test/docx/golden/tables.docxbin10896 -> 10893 bytes
-rw-r--r--test/docx/golden/tables_separated_with_rawblock.docxbin10517 -> 10516 bytes
-rw-r--r--test/docx/golden/task_list.docxbin10781 -> 10780 bytes
-rw-r--r--test/docx/golden/track_changes_deletion.docxbin10490 -> 10489 bytes
-rw-r--r--test/docx/golden/track_changes_insertion.docxbin10474 -> 10473 bytes
-rw-r--r--test/docx/golden/track_changes_move.docxbin10504 -> 10503 bytes
-rw-r--r--test/docx/golden/track_changes_scrubbed_metadata.docxbin10615 -> 10614 bytes
-rw-r--r--test/docx/golden/unicode.docxbin10466 -> 10465 bytes
-rw-r--r--test/docx/golden/verbatim_subsuper.docxbin10477 -> 10476 bytes
39 files changed, 31 insertions, 29 deletions
diff --git a/src/Text/Pandoc/Writers/Docx.hs b/src/Text/Pandoc/Writers/Docx.hs
index 7fb539289..596bb6944 100644
--- a/src/Text/Pandoc/Writers/Docx.hs
+++ b/src/Text/Pandoc/Writers/Docx.hs
@@ -3,9 +3,7 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TypeApplications #-}
{- |
Module : Text.Pandoc.Writers.Docx
Copyright : Copyright (C) 2012-2024 John MacFarlane
@@ -176,12 +174,6 @@ writeDocx opts doc = do
[] -> stTocTitle defaultWriterState
ls -> ls
- let initialSt = defaultWriterState {
- stStyleMaps = styleMaps
- , stTocTitle = tocTitle
- , stCurId = 20
- }
-
let isRTLmeta = case lookupMeta "dir" meta of
Just (MetaString "rtl") -> True
Just (MetaInlines [Str "rtl"]) -> True
@@ -194,44 +186,58 @@ writeDocx opts doc = do
, envPrintWidth = maybe 420 (`quot` 20) pgContentWidth
}
- parsedRels <- parseXml refArchive distArchive "word/_rels/document.xml.rels"
+ let isImageNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
let isHeaderNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header"
let isFooterNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer"
- let headers = filterElements isHeaderNode parsedRels
- let footers = filterElements isFooterNode parsedRels
+ parsedRels <- filterElements
+ (\e -> isImageNode e || isHeaderNode e || isFooterNode e)
+ <$> parseXml refArchive distArchive "word/_rels/document.xml.rels"
+ let getRelId e =
+ case findAttr (QName "Id" Nothing Nothing) e of
+ Just ident -> T.stripPrefix "rId" ident >>= safeRead
+ Nothing -> Nothing
+ let relIds = mapMaybe getRelId parsedRels
+ let maxRelId = if null relIds then 0 else maximum relIds
+
+ let headers = filter isHeaderNode parsedRels
+ let footers = filter isFooterNode parsedRels
-- word/_rels/document.xml.rels
- let toBaseRel (url', id', target') = mknode "Relationship"
- [("Type",url')
- ,("Id",id')
- ,("Target",target')] ()
- let baserels' = map toBaseRel
+ let addBaseRel (url', target') (maxId, rels) =
+ case [e | e <- rels
+ , findAttr (QName "Target" Nothing Nothing) e ==
+ Just target'] of
+ [] -> (maxId + 1, mknode "Relationship"
+ [("Type",url')
+ ,("Id","rId" <> tshow (maxId + 1))
+ ,("Target",target')] () : rels)
+ _ -> (maxId, rels)
+
+ let (newMaxRelId, baserels) = foldr addBaseRel (maxRelId, parsedRels)
[("http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
- "rId1",
"numbering.xml")
,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
- "rId2",
"styles.xml")
,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",
- "rId3",
"settings.xml")
,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings",
- "rId4",
"webSettings.xml")
,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",
- "rId5",
"fontTable.xml")
,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
- "rId6",
"theme/theme1.xml")
,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
- "rId7",
"footnotes.xml")
,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
- "rId8",
"comments.xml")
]
- let idMap = renumIdMap (length baserels' + 1) (headers ++ footers)
+ let initialSt = defaultWriterState {
+ stStyleMaps = styleMaps
+ , stTocTitle = tocTitle
+ , stCurId = newMaxRelId + 1
+ }
+
+ let idMap = renumIdMap (length baserels + 1) (headers ++ footers)
-- adjust contents to add sectPr from reference.docx
let sectpr = case mbsectpr of
@@ -331,10 +337,6 @@ writeDocx opts doc = do
let contentTypesEntry = toEntry "[Content_Types].xml" epochtime
$ renderXml contentTypesDoc
-
- let renumHeaders = renumIds (\q -> qName q == "Id") idMap headers
- let renumFooters = renumIds (\q -> qName q == "Id") idMap footers
- let baserels = baserels' ++ renumHeaders ++ renumFooters
let toImgRel (ident,path,_,_) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"),("Id",T.pack ident),("Target",T.pack path)] ()
let imgrels = map toImgRel imgs
let toLinkRel (src,ident) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"),("Id",ident),("Target",src),("TargetMode","External") ] ()
diff --git a/test/docx/golden/block_quotes.docx b/test/docx/golden/block_quotes.docx
index 214a57a5b..ba308cb04 100644
--- a/test/docx/golden/block_quotes.docx
+++ b/test/docx/golden/block_quotes.docx
Binary files differ
diff --git a/test/docx/golden/codeblock.docx b/test/docx/golden/codeblock.docx
index 9aa1dd858..160f02c87 100644
--- a/test/docx/golden/codeblock.docx
+++ b/test/docx/golden/codeblock.docx
Binary files differ
diff --git a/test/docx/golden/comments.docx b/test/docx/golden/comments.docx
index 41eb630ea..a3d09e933 100644
--- a/test/docx/golden/comments.docx
+++ b/test/docx/golden/comments.docx
Binary files differ
diff --git a/test/docx/golden/custom_style_no_reference.docx b/test/docx/golden/custom_style_no_reference.docx
index ff7b8c477..740a3f33b 100644
--- a/test/docx/golden/custom_style_no_reference.docx
+++ b/test/docx/golden/custom_style_no_reference.docx
Binary files differ
diff --git a/test/docx/golden/custom_style_preserve.docx b/test/docx/golden/custom_style_preserve.docx
index 8afe51ecd..d23633d94 100644
--- a/test/docx/golden/custom_style_preserve.docx
+++ b/test/docx/golden/custom_style_preserve.docx
Binary files differ
diff --git a/test/docx/golden/custom_style_reference.docx b/test/docx/golden/custom_style_reference.docx
index e4dd93f47..5c6270704 100644
--- a/test/docx/golden/custom_style_reference.docx
+++ b/test/docx/golden/custom_style_reference.docx
Binary files differ
diff --git a/test/docx/golden/definition_list.docx b/test/docx/golden/definition_list.docx
index cf152c5f2..fcf451174 100644
--- a/test/docx/golden/definition_list.docx
+++ b/test/docx/golden/definition_list.docx
Binary files differ
diff --git a/test/docx/golden/document-properties-short-desc.docx b/test/docx/golden/document-properties-short-desc.docx
index 8af10827a..85790580d 100644
--- a/test/docx/golden/document-properties-short-desc.docx
+++ b/test/docx/golden/document-properties-short-desc.docx
Binary files differ
diff --git a/test/docx/golden/document-properties.docx b/test/docx/golden/document-properties.docx
index 6d151023f..a72127699 100644
--- a/test/docx/golden/document-properties.docx
+++ b/test/docx/golden/document-properties.docx
Binary files differ
diff --git a/test/docx/golden/headers.docx b/test/docx/golden/headers.docx
index c6bec6ca4..1d3595da8 100644
--- a/test/docx/golden/headers.docx
+++ b/test/docx/golden/headers.docx
Binary files differ
diff --git a/test/docx/golden/image.docx b/test/docx/golden/image.docx
index ab841908c..4f2c7fa05 100644
--- a/test/docx/golden/image.docx
+++ b/test/docx/golden/image.docx
Binary files differ
diff --git a/test/docx/golden/inline_code.docx b/test/docx/golden/inline_code.docx
index f8dd88987..44b0345d9 100644
--- a/test/docx/golden/inline_code.docx
+++ b/test/docx/golden/inline_code.docx
Binary files differ
diff --git a/test/docx/golden/inline_formatting.docx b/test/docx/golden/inline_formatting.docx
index 9e83fa0e3..4675ae918 100644
--- a/test/docx/golden/inline_formatting.docx
+++ b/test/docx/golden/inline_formatting.docx
Binary files differ
diff --git a/test/docx/golden/inline_images.docx b/test/docx/golden/inline_images.docx
index b76cf6417..b091b3b38 100644
--- a/test/docx/golden/inline_images.docx
+++ b/test/docx/golden/inline_images.docx
Binary files differ
diff --git a/test/docx/golden/link_in_notes.docx b/test/docx/golden/link_in_notes.docx
index fc8326472..88b8e500e 100644
--- a/test/docx/golden/link_in_notes.docx
+++ b/test/docx/golden/link_in_notes.docx
Binary files differ
diff --git a/test/docx/golden/links.docx b/test/docx/golden/links.docx
index 5b1fce508..b1c755329 100644
--- a/test/docx/golden/links.docx
+++ b/test/docx/golden/links.docx
Binary files differ
diff --git a/test/docx/golden/lists.docx b/test/docx/golden/lists.docx
index 99ccd88a7..d5ae963fe 100644
--- a/test/docx/golden/lists.docx
+++ b/test/docx/golden/lists.docx
Binary files differ
diff --git a/test/docx/golden/lists_9994.docx b/test/docx/golden/lists_9994.docx
index a43d1869b..bf1d640ef 100644
--- a/test/docx/golden/lists_9994.docx
+++ b/test/docx/golden/lists_9994.docx
Binary files differ
diff --git a/test/docx/golden/lists_continuing.docx b/test/docx/golden/lists_continuing.docx
index f9409df00..2049af474 100644
--- a/test/docx/golden/lists_continuing.docx
+++ b/test/docx/golden/lists_continuing.docx
Binary files differ
diff --git a/test/docx/golden/lists_div_bullets.docx b/test/docx/golden/lists_div_bullets.docx
index ee504f3c1..66d6c7c95 100644
--- a/test/docx/golden/lists_div_bullets.docx
+++ b/test/docx/golden/lists_div_bullets.docx
Binary files differ
diff --git a/test/docx/golden/lists_multiple_initial.docx b/test/docx/golden/lists_multiple_initial.docx
index 593fe03b5..7cc22667a 100644
--- a/test/docx/golden/lists_multiple_initial.docx
+++ b/test/docx/golden/lists_multiple_initial.docx
Binary files differ
diff --git a/test/docx/golden/lists_restarting.docx b/test/docx/golden/lists_restarting.docx
index 5cbe7b24e..bf4bd4b1b 100644
--- a/test/docx/golden/lists_restarting.docx
+++ b/test/docx/golden/lists_restarting.docx
Binary files differ
diff --git a/test/docx/golden/nested_anchors_in_header.docx b/test/docx/golden/nested_anchors_in_header.docx
index a97cd445b..45b0410a6 100644
--- a/test/docx/golden/nested_anchors_in_header.docx
+++ b/test/docx/golden/nested_anchors_in_header.docx
Binary files differ
diff --git a/test/docx/golden/notes.docx b/test/docx/golden/notes.docx
index 2562cceb3..a120d87bf 100644
--- a/test/docx/golden/notes.docx
+++ b/test/docx/golden/notes.docx
Binary files differ
diff --git a/test/docx/golden/raw-blocks.docx b/test/docx/golden/raw-blocks.docx
index 145801c0e..de5186b5d 100644
--- a/test/docx/golden/raw-blocks.docx
+++ b/test/docx/golden/raw-blocks.docx
Binary files differ
diff --git a/test/docx/golden/raw-bookmarks.docx b/test/docx/golden/raw-bookmarks.docx
index 6e774aa15..cae7b2a71 100644
--- a/test/docx/golden/raw-bookmarks.docx
+++ b/test/docx/golden/raw-bookmarks.docx
Binary files differ
diff --git a/test/docx/golden/table_one_row.docx b/test/docx/golden/table_one_row.docx
index abbe767a5..d989f2562 100644
--- a/test/docx/golden/table_one_row.docx
+++ b/test/docx/golden/table_one_row.docx
Binary files differ
diff --git a/test/docx/golden/table_with_list_cell.docx b/test/docx/golden/table_with_list_cell.docx
index 8477a7cf1..f623dffdf 100644
--- a/test/docx/golden/table_with_list_cell.docx
+++ b/test/docx/golden/table_with_list_cell.docx
Binary files differ
diff --git a/test/docx/golden/tables-default-widths.docx b/test/docx/golden/tables-default-widths.docx
index 790d8cd63..b82616bd9 100644
--- a/test/docx/golden/tables-default-widths.docx
+++ b/test/docx/golden/tables-default-widths.docx
Binary files differ
diff --git a/test/docx/golden/tables.docx b/test/docx/golden/tables.docx
index 1b80a7904..4272568db 100644
--- a/test/docx/golden/tables.docx
+++ b/test/docx/golden/tables.docx
Binary files differ
diff --git a/test/docx/golden/tables_separated_with_rawblock.docx b/test/docx/golden/tables_separated_with_rawblock.docx
index fd8c68c06..ab99fd05b 100644
--- a/test/docx/golden/tables_separated_with_rawblock.docx
+++ b/test/docx/golden/tables_separated_with_rawblock.docx
Binary files differ
diff --git a/test/docx/golden/task_list.docx b/test/docx/golden/task_list.docx
index 2ca6c7d77..dfebd5873 100644
--- a/test/docx/golden/task_list.docx
+++ b/test/docx/golden/task_list.docx
Binary files differ
diff --git a/test/docx/golden/track_changes_deletion.docx b/test/docx/golden/track_changes_deletion.docx
index f3fd20137..1ed6c0b1a 100644
--- a/test/docx/golden/track_changes_deletion.docx
+++ b/test/docx/golden/track_changes_deletion.docx
Binary files differ
diff --git a/test/docx/golden/track_changes_insertion.docx b/test/docx/golden/track_changes_insertion.docx
index a791641a0..7e53ff9d1 100644
--- a/test/docx/golden/track_changes_insertion.docx
+++ b/test/docx/golden/track_changes_insertion.docx
Binary files differ
diff --git a/test/docx/golden/track_changes_move.docx b/test/docx/golden/track_changes_move.docx
index fb25a5bbb..9c099afc7 100644
--- a/test/docx/golden/track_changes_move.docx
+++ b/test/docx/golden/track_changes_move.docx
Binary files differ
diff --git a/test/docx/golden/track_changes_scrubbed_metadata.docx b/test/docx/golden/track_changes_scrubbed_metadata.docx
index 6305c0d59..7a0fd6c78 100644
--- a/test/docx/golden/track_changes_scrubbed_metadata.docx
+++ b/test/docx/golden/track_changes_scrubbed_metadata.docx
Binary files differ
diff --git a/test/docx/golden/unicode.docx b/test/docx/golden/unicode.docx
index ccd92baa4..396a7d7ca 100644
--- a/test/docx/golden/unicode.docx
+++ b/test/docx/golden/unicode.docx
Binary files differ
diff --git a/test/docx/golden/verbatim_subsuper.docx b/test/docx/golden/verbatim_subsuper.docx
index 55323f885..85bed4c01 100644
--- a/test/docx/golden/verbatim_subsuper.docx
+++ b/test/docx/golden/verbatim_subsuper.docx
Binary files differ