git.iko.soy/typeable/pandoc
on master help sign in
Docx writer: Header and footer are now carried over from reference.docx.
6848f64John MacFarlane
data/reference.docx

Binary file not shown.

src/Text/Pandoc/Writers/Docx.hs+38−16
@@ -155,8 +155,11 @@ writeDocx opts doc@(Pandoc meta _) = do
155 ,("/word/document.xml",
155 ,("/word/document.xml",
156 "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")
156 "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")
157 ,("/word/footnotes.xml",
157 ,("/word/footnotes.xml",
158− "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml")
158+ "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"),
159− ] ++ map mkImageOverride imgs
159+ ("/word/header1.xml",
160+ "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"),
161+ ("/word/footer1.xml",
162+ "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml") ] ++ map mkImageOverride imgs
160 let defaultnodes = [mknode "Default"
163 let defaultnodes = [mknode "Default"
161 [("Extension","xml"),("ContentType","application/xml")] (),
164 [("Extension","xml"),("ContentType","application/xml")] (),
162 mknode "Default"
165 mknode "Default"
@@ -191,7 +194,14 @@ writeDocx opts doc@(Pandoc meta _) = do
191 "theme/theme1.xml")
194 "theme/theme1.xml")
192 ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
195 ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
193 "rId7",
196 "rId7",
194− "footnotes.xml")]
197+ "footnotes.xml")
198+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
199+ "rId8",
200+ "header1.xml")
201+ ,("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
202+ "rId9",
203+ "footer1.xml")
204+ ]
195 let toImgRel (ident,path,_,_,_) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"),("Id",ident),("Target",path)] ()
205 let toImgRel (ident,path,_,_,_) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"),("Id",ident),("Target",path)] ()
196 let imgrels = map toImgRel imgs
206 let imgrels = map toImgRel imgs
197 let toLinkRel (src,ident) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"),("Id",ident),("Target",src),("TargetMode","External") ] ()
207 let toLinkRel (src,ident) = mknode "Relationship" [("Type","http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"),("Id",ident),("Target",src),("TargetMode","External") ] ()
@@ -207,9 +217,16 @@ writeDocx opts doc@(Pandoc meta _) = do
207 -- adjust contents to add sectPr from reference.docx
217 -- adjust contents to add sectPr from reference.docx
208 let docpath = "word/document.xml"
218 let docpath = "word/document.xml"
209 parsedDoc <- parseXml refArchive distArchive docpath
219 parsedDoc <- parseXml refArchive distArchive docpath
210− let sectprs = filterElementsName (\qn -> qPrefix qn == Just "w" &&
220+ let mbsectpr = filterElementName (\qn -> qPrefix qn == Just "w" &&
211− qName qn == "sectPr")
221+ qName qn == "sectPr") parsedDoc
212− parsedDoc
222+ let sectPrProps = case mbsectpr of
223+ Nothing -> []
224+ Just e -> filterElementsName (\qn ->
225+ qPrefix qn == Just "w" &&
226+ qName qn `notElem` ["headerReference","footerReference","sectPr"]) e
227+ let headerPr = mknode "w:headerReference" [("w:type","default"),("r:id","rId8")] $ ()
228+ let footerPr = mknode "w:footerReference" [("w:type","default"),("r:id","rId9")] $ ()
229+ let sectpr = mknode "w:sectPr" [] $ [headerPr, footerPr] ++ sectPrProps
213
230
214 let stdAttributes =
231 let stdAttributes =
215 [("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")
232 [("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")
@@ -222,7 +239,7 @@ writeDocx opts doc@(Pandoc meta _) = do
222 ,("xmlns:pic","http://schemas.openxmlformats.org/drawingml/2006/picture")
239 ,("xmlns:pic","http://schemas.openxmlformats.org/drawingml/2006/picture")
223 ,("xmlns:wp","http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing")]
240 ,("xmlns:wp","http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing")]
224
241
225− let contents' = contents ++ sectprs
242+ let contents' = contents ++ [sectpr]
226 let docContents = mknode "w:document" stdAttributes
243 let docContents = mknode "w:document" stdAttributes
227 $ mknode "w:body" [] $ contents'
244 $ mknode "w:body" [] $ contents'
228
245
@@ -281,20 +298,25 @@ writeDocx opts doc@(Pandoc meta _) = do
281 ]
298 ]
282 let relsEntry = toEntry relsPath epochtime $ renderXml rels
299 let relsEntry = toEntry relsPath epochtime $ renderXml rels
283
300
284− let entryFromArchive path =
301+ let entryFromArchive arch path =
285 (toEntry path epochtime . renderXml) `fmap`
302 (toEntry path epochtime . renderXml) `fmap`
286− parseXml refArchive distArchive path
303+ parseXml arch distArchive path
287− docPropsAppEntry <- entryFromArchive "docProps/app.xml"
304+ docPropsAppEntry <- entryFromArchive refArchive "docProps/app.xml"
288− themeEntry <- entryFromArchive "word/theme/theme1.xml"
305+ themeEntry <- entryFromArchive refArchive "word/theme/theme1.xml"
289− fontTableEntry <- entryFromArchive "word/fontTable.xml"
306+ fontTableEntry <- entryFromArchive refArchive "word/fontTable.xml"
307+ -- we take settings.xml from dist archive because the ref archive
308+ -- sometimes references special footnotes and endnotes that may
309+ -- not be defined in footnotes.xml or endnotes.xml.
290− settingsEntry <- entryFromArchive "word/settings.xml"
310+ settingsEntry <- entryFromArchive distArchive "word/settings.xml"
291− webSettingsEntry <- entryFromArchive "word/webSettings.xml"
311+ webSettingsEntry <- entryFromArchive distArchive "word/webSettings.xml"
312+ headerEntry <- entryFromArchive refArchive "word/header1.xml"
313+ footerEntry <- entryFromArchive refArchive "word/footer1.xml"
292 let miscRels = [ f | f <- filesInArchive refArchive
314 let miscRels = [ f | f <- filesInArchive refArchive
293 , "word/_rels/" `isPrefixOf` f
315 , "word/_rels/" `isPrefixOf` f
294 , ".xml.rels" `isSuffixOf` f
316 , ".xml.rels" `isSuffixOf` f
295 , f /= "word/_rels/document.xml.rels"
317 , f /= "word/_rels/document.xml.rels"
296 , f /= "word/_rels/footnotes.xml.rels" ]
318 , f /= "word/_rels/footnotes.xml.rels" ]
297− miscRelEntries <- mapM entryFromArchive miscRels
319+ miscRelEntries <- mapM (entryFromArchive refArchive) miscRels
298
320
299 -- Create archive
321 -- Create archive
300 let archive = foldr addEntryToArchive emptyArchive $
322 let archive = foldr addEntryToArchive emptyArchive $
@@ -302,7 +324,7 @@ writeDocx opts doc@(Pandoc meta _) = do
302 footnoteRelEntry : numEntry : styleEntry : footnotesEntry :
324 footnoteRelEntry : numEntry : styleEntry : footnotesEntry :
303 docPropsEntry : docPropsAppEntry : themeEntry :
325 docPropsEntry : docPropsAppEntry : themeEntry :
304 fontTableEntry : settingsEntry : webSettingsEntry :
326 fontTableEntry : settingsEntry : webSettingsEntry :
305− imageEntries ++ miscRelEntries
327+ headerEntry : footerEntry : imageEntries ++ miscRelEntries
306 return $ fromArchive archive
328 return $ fromArchive archive
307
329
308styleToOpenXml :: Style -> [Element]
330styleToOpenXml :: Style -> [Element]