From 6ba37909fee80c9ee910644c25dbca1561056ccd Mon Sep 17 00:00:00 2001
From: Nikolay Yakimov <root@livid.pp.ru>
Date: Sun, 29 Mar 2015 11:43:20 +0300
Subject: [PATCH] Docx Writer: Copy hyphenation settings from reference.docx

---
 src/Text/Pandoc/Writers/Docx.hs | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/Text/Pandoc/Writers/Docx.hs b/src/Text/Pandoc/Writers/Docx.hs
index 81369e278..5903e7689 100644
--- a/src/Text/Pandoc/Writers/Docx.hs
+++ b/src/Text/Pandoc/Writers/Docx.hs
@@ -432,6 +432,17 @@ writeDocx opts doc@(Pandoc meta _) = do
         ]
   let relsEntry = toEntry relsPath epochtime $ renderXml rels
 
+  -- we use dist archive for settings.xml, because Word sometimes
+  -- 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 = [ "w:autoHyphenation"
+                     , "w:consecutiveHyphenLimit"
+                     , "w:hyphenationZone"
+                     , "w:doNotHyphenateCap"
+                     ]
+  settingsEntry <- copyChildren refArchive distArchive settingsPath epochtime settingsList
+
   let entryFromArchive arch path =
          maybe (fail $ path ++ " corrupt or missing in reference docx")
                return
@@ -439,9 +450,6 @@ writeDocx opts doc@(Pandoc meta _) = do
   docPropsAppEntry <- entryFromArchive refArchive "docProps/app.xml"
   themeEntry <- entryFromArchive refArchive "word/theme/theme1.xml"
   fontTableEntry <- entryFromArchive refArchive "word/fontTable.xml"
-  -- we use dist archive for settings.xml, because Word sometimes
-  -- adds references to footnotes or endnotes we don't have...
-  settingsEntry <- entryFromArchive distArchive "word/settings.xml"
   webSettingsEntry <- entryFromArchive refArchive "word/webSettings.xml"
   headerFooterEntries <- mapM (entryFromArchive refArchive) $
                      mapMaybe (fmap ("word/" ++) . extractTarget)
@@ -504,6 +512,21 @@ styleToOpenXml sm style =
                                  $ backgroundColor style )
                              ]
 
+copyChildren :: Archive -> Archive -> String -> Integer -> [String] -> IO Entry
+copyChildren refArchive distArchive path timestamp elNames = do
+  ref  <- parseXml refArchive distArchive path
+  dist <- parseXml distArchive distArchive path
+  return $ toEntry path timestamp $ renderXml dist{
+      elContent = elContent dist ++ copyContent ref
+    }
+  where
+    strName QName{qName=name, qPrefix=prefix}
+      | Just p <- prefix = p++":"++name
+      | otherwise        = name
+    shouldCopy = (`elem` elNames) . strName
+    cleanElem el@Element{elName=name} = Elem el{elName=name{qURI=Nothing}}
+    copyContent = map cleanElem . filterChildrenName shouldCopy
+
 -- this is the lowest number used for a list numId
 baseListId :: Int
 baseListId = 1000