Hlint changes to Docx writer.
This commit is contained in:
parent
c956eb617d
commit
9f8051d95d
1 changed files with 19 additions and 22 deletions
|
@ -29,7 +29,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
Conversion of 'Pandoc' documents to docx.
|
Conversion of 'Pandoc' documents to docx.
|
||||||
-}
|
-}
|
||||||
module Text.Pandoc.Writers.Docx ( writeDocx ) where
|
module Text.Pandoc.Writers.Docx ( writeDocx ) where
|
||||||
import Data.Maybe (fromMaybe)
|
|
||||||
import Data.List ( intercalate, isPrefixOf, isSuffixOf )
|
import Data.List ( intercalate, isPrefixOf, isSuffixOf )
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
|
@ -59,7 +58,7 @@ import Text.Printf (printf)
|
||||||
import qualified Control.Exception as E
|
import qualified Control.Exception as E
|
||||||
import Text.Pandoc.MIME (getMimeType, extensionFromMimeType)
|
import Text.Pandoc.MIME (getMimeType, extensionFromMimeType)
|
||||||
import Control.Applicative ((<|>), (<$>))
|
import Control.Applicative ((<|>), (<$>))
|
||||||
import Data.Maybe (mapMaybe)
|
import Data.Maybe (fromMaybe, mapMaybe)
|
||||||
|
|
||||||
data ListMarker = NoMarker
|
data ListMarker = NoMarker
|
||||||
| BulletMarker
|
| BulletMarker
|
||||||
|
@ -119,8 +118,8 @@ mknode s attrs =
|
||||||
nodename :: String -> QName
|
nodename :: String -> QName
|
||||||
nodename s = QName{ qName = name, qURI = Nothing, qPrefix = prefix }
|
nodename s = QName{ qName = name, qURI = Nothing, qPrefix = prefix }
|
||||||
where (name, prefix) = case break (==':') s of
|
where (name, prefix) = case break (==':') s of
|
||||||
(xs,[]) -> (xs, Nothing)
|
(xs,[]) -> (xs, Nothing)
|
||||||
(ys,(_:zs)) -> (zs, Just ys)
|
(ys, _:zs) -> (zs, Just ys)
|
||||||
|
|
||||||
toLazy :: B.ByteString -> BL.ByteString
|
toLazy :: B.ByteString -> BL.ByteString
|
||||||
toLazy = BL.fromChunks . (:[])
|
toLazy = BL.fromChunks . (:[])
|
||||||
|
@ -156,7 +155,7 @@ writeDocx opts doc@(Pandoc meta _) = do
|
||||||
let wname f qn = qPrefix qn == Just "w" && f (qName qn)
|
let wname f qn = qPrefix qn == Just "w" && f (qName qn)
|
||||||
let mbsectpr = filterElementName (wname (=="sectPr")) parsedDoc
|
let mbsectpr = filterElementName (wname (=="sectPr")) parsedDoc
|
||||||
|
|
||||||
let sectpr = maybe (mknode "w:sectPr" [] $ ()) id mbsectpr
|
let sectpr = fromMaybe (mknode "w:sectPr" [] ()) mbsectpr
|
||||||
|
|
||||||
let stdAttributes =
|
let stdAttributes =
|
||||||
[("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")
|
[("xmlns:w","http://schemas.openxmlformats.org/wordprocessingml/2006/main")
|
||||||
|
@ -171,7 +170,7 @@ writeDocx opts doc@(Pandoc meta _) = do
|
||||||
|
|
||||||
let contents' = contents ++ [sectpr]
|
let contents' = contents ++ [sectpr]
|
||||||
let docContents = mknode "w:document" stdAttributes
|
let docContents = mknode "w:document" stdAttributes
|
||||||
$ mknode "w:body" [] $ contents'
|
$ mknode "w:body" [] contents'
|
||||||
|
|
||||||
parsedRels <- parseXml refArchive distArchive "word/_rels/document.xml.rels"
|
parsedRels <- parseXml refArchive distArchive "word/_rels/document.xml.rels"
|
||||||
let isHeaderNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header"
|
let isHeaderNode e = findAttr (QName "Type" Nothing Nothing) e == Just "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header"
|
||||||
|
@ -179,7 +178,7 @@ writeDocx opts doc@(Pandoc meta _) = do
|
||||||
let headers = filterElements isHeaderNode parsedRels
|
let headers = filterElements isHeaderNode parsedRels
|
||||||
let footers = filterElements isFooterNode parsedRels
|
let footers = filterElements isFooterNode parsedRels
|
||||||
|
|
||||||
let extractTarget e = findAttr (QName "Target" Nothing Nothing) e
|
let extractTarget = findAttr (QName "Target" Nothing Nothing)
|
||||||
|
|
||||||
-- we create [Content_Types].xml and word/_rels/document.xml.rels
|
-- we create [Content_Types].xml and word/_rels/document.xml.rels
|
||||||
-- from scratch rather than reading from reference.docx,
|
-- from scratch rather than reading from reference.docx,
|
||||||
|
@ -283,7 +282,7 @@ writeDocx opts doc@(Pandoc meta _) = do
|
||||||
-- footnote rels
|
-- footnote rels
|
||||||
let footnoteRelEntry = toEntry "word/_rels/footnotes.xml.rels" epochtime
|
let footnoteRelEntry = toEntry "word/_rels/footnotes.xml.rels" epochtime
|
||||||
$ renderXml $ mknode "Relationships" [("xmlns","http://schemas.openxmlformats.org/package/2006/relationships")]
|
$ renderXml $ mknode "Relationships" [("xmlns","http://schemas.openxmlformats.org/package/2006/relationships")]
|
||||||
$ linkrels
|
linkrels
|
||||||
|
|
||||||
-- styles
|
-- styles
|
||||||
let newstyles = styleToOpenXml $ writerHighlightStyle opts
|
let newstyles = styleToOpenXml $ writerHighlightStyle opts
|
||||||
|
@ -315,8 +314,8 @@ writeDocx opts doc@(Pandoc meta _) = do
|
||||||
$ mknode "dc:title" [] (stringify $ docTitle meta)
|
$ mknode "dc:title" [] (stringify $ docTitle meta)
|
||||||
: mknode "dc:creator" [] (intercalate "; " (map stringify $ docAuthors meta))
|
: mknode "dc:creator" [] (intercalate "; " (map stringify $ docAuthors meta))
|
||||||
: maybe []
|
: maybe []
|
||||||
(\x -> [ mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")] $ x
|
(\x -> [ mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")] x
|
||||||
, mknode "dcterms:modified" [("xsi:type","dcterms:W3CDTF")] $ x
|
, mknode "dcterms:modified" [("xsi:type","dcterms:W3CDTF")] x
|
||||||
]) (normalizeDate $ stringify $ docDate meta)
|
]) (normalizeDate $ stringify $ docDate meta)
|
||||||
let docPropsEntry = toEntry docPropsPath epochtime $ renderXml docProps
|
let docPropsEntry = toEntry docPropsPath epochtime $ renderXml docProps
|
||||||
|
|
||||||
|
@ -347,7 +346,7 @@ writeDocx opts doc@(Pandoc meta _) = do
|
||||||
settingsEntry <- entryFromArchive distArchive "word/settings.xml"
|
settingsEntry <- entryFromArchive distArchive "word/settings.xml"
|
||||||
webSettingsEntry <- entryFromArchive refArchive "word/webSettings.xml"
|
webSettingsEntry <- entryFromArchive refArchive "word/webSettings.xml"
|
||||||
headerFooterEntries <- mapM (entryFromArchive refArchive) $
|
headerFooterEntries <- mapM (entryFromArchive refArchive) $
|
||||||
mapMaybe (\e -> fmap ("word/" ++) $ extractTarget e)
|
mapMaybe (fmap ("word/" ++) . extractTarget)
|
||||||
(headers ++ footers)
|
(headers ++ footers)
|
||||||
let miscRelEntries = [ e | e <- zEntries refArchive
|
let miscRelEntries = [ e | e <- zEntries refArchive
|
||||||
, "word/_rels/" `isPrefixOf` (eRelativePath e)
|
, "word/_rels/" `isPrefixOf` (eRelativePath e)
|
||||||
|
@ -508,7 +507,7 @@ writeOpenXML opts (Pandoc meta blocks) = do
|
||||||
let convertSpace (Str x : Space : Str y : xs) = Str (x ++ " " ++ y) : xs
|
let convertSpace (Str x : Space : Str y : xs) = Str (x ++ " " ++ y) : xs
|
||||||
convertSpace (Str x : Str y : xs) = Str (x ++ y) : xs
|
convertSpace (Str x : Str y : xs) = Str (x ++ y) : xs
|
||||||
convertSpace xs = xs
|
convertSpace xs = xs
|
||||||
let blocks' = bottomUp convertSpace $ blocks
|
let blocks' = bottomUp convertSpace blocks
|
||||||
doc' <- blocksToOpenXML opts blocks'
|
doc' <- blocksToOpenXML opts blocks'
|
||||||
notes' <- reverse `fmap` gets stFootnotes
|
notes' <- reverse `fmap` gets stFootnotes
|
||||||
let meta' = title ++ subtitle ++ authors ++ date ++ abstract
|
let meta' = title ++ subtitle ++ authors ++ date ++ abstract
|
||||||
|
@ -592,13 +591,12 @@ blockToOpenXML opts (Table caption aligns widths headers rows) = do
|
||||||
let cellToOpenXML (al, cell) = withParaProp (alignmentFor al)
|
let cellToOpenXML (al, cell) = withParaProp (alignmentFor al)
|
||||||
$ blocksToOpenXML opts cell
|
$ blocksToOpenXML opts cell
|
||||||
headers' <- mapM cellToOpenXML $ zip aligns headers
|
headers' <- mapM cellToOpenXML $ zip aligns headers
|
||||||
rows' <- mapM (\cells -> mapM cellToOpenXML $ zip aligns cells)
|
rows' <- mapM (mapM cellToOpenXML . zip aligns) rows
|
||||||
$ rows
|
|
||||||
let borderProps = mknode "w:tcPr" []
|
let borderProps = mknode "w:tcPr" []
|
||||||
[ mknode "w:tcBorders" []
|
[ mknode "w:tcBorders" []
|
||||||
$ mknode "w:bottom" [("w:val","single")] ()
|
$ mknode "w:bottom" [("w:val","single")] ()
|
||||||
, mknode "w:vAlign" [("w:val","bottom")] () ]
|
, mknode "w:vAlign" [("w:val","bottom")] () ]
|
||||||
let emptyCell = [mknode "w:p" [] [mknode "w:pPr" [] $
|
let emptyCell = [mknode "w:p" [] [mknode "w:pPr" []
|
||||||
[mknode "w:pStyle" [("w:val","Compact")] ()]]]
|
[mknode "w:pStyle" [("w:val","Compact")] ()]]]
|
||||||
let mkcell border contents = mknode "w:tc" []
|
let mkcell border contents = mknode "w:tc" []
|
||||||
$ [ borderProps | border ] ++
|
$ [ borderProps | border ] ++
|
||||||
|
@ -610,12 +608,12 @@ blockToOpenXML opts (Table caption aligns widths headers rows) = do
|
||||||
let fullrow = 5000 -- 100% specified in pct
|
let fullrow = 5000 -- 100% specified in pct
|
||||||
let rowwidth = fullrow * sum widths
|
let rowwidth = fullrow * sum widths
|
||||||
let mkgridcol w = mknode "w:gridCol"
|
let mkgridcol w = mknode "w:gridCol"
|
||||||
[("w:w", show $ (floor (textwidth * w) :: Integer))] ()
|
[("w:w", show (floor (textwidth * w) :: Integer))] ()
|
||||||
return $
|
return $
|
||||||
[ mknode "w:tbl" []
|
mknode "w:tbl" []
|
||||||
( mknode "w:tblPr" []
|
( mknode "w:tblPr" []
|
||||||
( [ mknode "w:tblStyle" [("w:val","TableNormal")] () ] ++
|
( mknode "w:tblStyle" [("w:val","TableNormal")] () :
|
||||||
[ mknode "w:tblW" [("w:type", "pct"), ("w:w", (show rowwidth))] () ] ++
|
mknode "w:tblW" [("w:type", "pct"), ("w:w", show rowwidth)] () :
|
||||||
[ mknode "w:tblCaption" [("w:val", captionStr)] ()
|
[ mknode "w:tblCaption" [("w:val", captionStr)] ()
|
||||||
| not (null caption) ] )
|
| not (null caption) ] )
|
||||||
: mknode "w:tblGrid" []
|
: mknode "w:tblGrid" []
|
||||||
|
@ -624,8 +622,7 @@ blockToOpenXML opts (Table caption aligns widths headers rows) = do
|
||||||
else map mkgridcol widths)
|
else map mkgridcol widths)
|
||||||
: [ mkrow True headers' | not (all null headers) ] ++
|
: [ mkrow True headers' | not (all null headers) ] ++
|
||||||
map (mkrow False) rows'
|
map (mkrow False) rows'
|
||||||
)
|
) : caption'
|
||||||
] ++ caption'
|
|
||||||
blockToOpenXML opts (BulletList lst) = do
|
blockToOpenXML opts (BulletList lst) = do
|
||||||
let marker = BulletMarker
|
let marker = BulletMarker
|
||||||
addList marker
|
addList marker
|
||||||
|
@ -692,7 +689,7 @@ getTextProps = do
|
||||||
props <- gets stTextProperties
|
props <- gets stTextProperties
|
||||||
return $ if null props
|
return $ if null props
|
||||||
then []
|
then []
|
||||||
else [mknode "w:rPr" [] $ props]
|
else [mknode "w:rPr" [] props]
|
||||||
|
|
||||||
pushTextProp :: Element -> WS ()
|
pushTextProp :: Element -> WS ()
|
||||||
pushTextProp d = modify $ \s -> s{ stTextProperties = d : stTextProperties s }
|
pushTextProp d = modify $ \s -> s{ stTextProperties = d : stTextProperties s }
|
||||||
|
|
Loading…
Add table
Reference in a new issue