git.iko.soy/typeable/pandoc
on master help sign in
Improve writing metadata for docx, pptx and odt (#5252)

* docx writer: support custom properties. Solves the writer part of #3024. Also supports additional core properties: `subject`, `lang`, `category`, `description`. * odt writer: improve standard properties, including the following core properties: `generator` (Pandoc/VERSION), `description`, `subject`, `keywords`, `initial-creator` (from authors), `creation-date` (actual creation date). Also fix date. * pptx writer: support custom properties. Also supports additional core properties: `subject`, `category`, `description`. * Includes golden tests. * MANUAL: document metadata support for docx, odt, pptx writers

commit9894d05fe3fd239247f755c60dc22247360be958 authorAgustín Martín Barbero <agusmbaterra@gmail.com> dateSat 26 Jan 2019, 16:14 (8 years ago) parentff0aaa5
45 files changed+165−24
MANUAL.txt+40−6 src/Text/Pandoc/Writers/Docx.hs+17−2 src/Text/Pandoc/Writers/ODT.hs+27−9 src/Text/Pandoc/Writers/Powerpoint/Output.hs+36−5 src/Text/Pandoc/Writers/Powerpoint/Presentation.hs+19−2 test/Tests/Writers/Docx.hs+10 test/Tests/Writers/Powerpoint.hs+8 test/docx/document-properties-short-desc.native+2 test/docx/document-properties.native+2 test/docx/golden/document-properties-short-desc.docx test/docx/golden/document-properties.docx test/pptx/document-properties-short-desc.native+2 test/pptx/document-properties-short-desc.pptx test/pptx/document-properties-short-desc_templated.pptx test/pptx/document-properties.native+2 test/pptx/document-properties.pptx test/pptx/document-properties_templated.pptx test/pptx/endnotes.pptx test/pptx/endnotes_templated.pptx test/pptx/endnotes_toc.pptx test/pptx/endnotes_toc_templated.pptx test/pptx/images.pptx test/pptx/images_templated.pptx test/pptx/inline_formatting.pptx test/pptx/inline_formatting_templated.pptx test/pptx/lists.pptx test/pptx/lists_templated.pptx test/pptx/raw_ooxml.pptx test/pptx/raw_ooxml_templated.pptx test/pptx/remove_empty_slides.pptx test/pptx/remove_empty_slides_templated.pptx test/pptx/slide_breaks.pptx test/pptx/slide_breaks_slide_level_1.pptx test/pptx/slide_breaks_slide_level_1_templated.pptx test/pptx/slide_breaks_templated.pptx test/pptx/slide_breaks_toc.pptx test/pptx/slide_breaks_toc_templated.pptx test/pptx/speaker_notes.pptx test/pptx/speaker_notes_afterseps.pptx test/pptx/speaker_notes_afterseps_templated.pptx test/pptx/speaker_notes_templated.pptx test/pptx/tables.pptx test/pptx/tables_templated.pptx test/pptx/two_column.pptx test/pptx/two_column_templated.pptx
MANUAL.txt+40−6
@@ -1355,7 +1355,7 @@ directory (see `--data-dir`, above). *Exceptions:*
13551355 (or the `default.context` template, if you use `-t context`,
13561356 or the `default.ms` template, if you use `-t ms`, or the
13571357 `default.html` template, if you use `-t html`).
1358−- `docx` has no template (however, you can use
1358+- `docx` and `pptx` have no template (however, you can use
13591359 `--reference-doc` to customize the output).
13601360
13611361Templates contain *variables*, which allow for the inclusion of
@@ -1363,7 +1363,7 @@ arbitrary information at any point in the file. They may be set at the
13631363command line using the `-V/--variable` option. If a variable is not set,
13641364pandoc will look for the key in the document's metadata – which can be set
13651365using either [YAML metadata blocks][Extension: `yaml_metadata_block`]
1366−or with the `--metadata` option.
1366+or with the `-M/--metadata` option.
13671367
13681368Metadata variables
13691369------------------
@@ -1381,14 +1381,48 @@ Metadata variables
13811381 ...
13821382
13831383`subtitle`
1384−: document subtitle, included in HTML, EPUB, LaTeX, ConTeXt, and Word docx
1384+: document subtitle, included in HTML, EPUB, LaTeX, ConTeXt, and docx
1385+ documents
13851386
13861387`abstract`
1387−: document summary, included in LaTeX, ConTeXt, AsciiDoc, and Word docx
1388+: document summary, included in LaTeX, ConTeXt, AsciiDoc, and docx
1389+ documents
13881390
13891391`keywords`
1390−: list of keywords to be included in HTML, PDF, and AsciiDoc metadata;
1391− repeat as for `author`, above
1392+: list of keywords to be included in HTML, PDF, ODT, pptx, docx
1393+ and AsciiDoc metadata; repeat as for `author`, above
1394+
1395+`subject`
1396+: document subject, included in ODT, docx and pptx metadata
1397+
1398+`description`
1399+: document description, included in ODT, docx and pptx metadata. Some
1400+ applications show this as `Comments` metadata.
1401+
1402+`category`
1403+: document category, included in docx and pptx metadata
1404+
1405+Additionally,
1406+any root-level string metadata, not included in ODT, docx
1407+or pptx metadata is added as a *custom property*.
1408+The following YAML metadata block for instance:
1409+
1410+ ---
1411+ title: 'This is the title'
1412+ subtitle: "This is the subtitle"
1413+ author:
1414+ - Author One
1415+ - Author Two
1416+ description: |
1417+ This is a long
1418+ description.
1419+
1420+ It consists of two paragraphs
1421+ ...
1422+
1423+will include `title`, `author` and `description` as standard document
1424+properties and `subtitle` as a custom property when converting to docx,
1425+ODT or pptx.
13921426
13931427Language variables
13941428------------------
src/Text/Pandoc/Writers/Docx.hs+17−2
@@ -496,7 +496,17 @@ writeDocx opts doc@(Pandoc meta _) = do
496496 Just (MetaList xs) -> map stringify xs
497497 _ -> []
498498
499+ -- docProps/core.xml
499500 let docPropsPath = "docProps/core.xml"
501+ let extraCoreProps = ["subject","lang","category","description"]
502+ let extraCorePropsMap = M.fromList $ zip extraCoreProps
503+ ["dc:subject","dc:language","cp:category","dc:description"]
504+ let lookupMetaString' :: String -> Meta -> String
505+ lookupMetaString' key' meta' =
506+ case key' of
507+ "description" -> intercalate "_x000d_\n" (map stringify $ lookupMetaBlocks "description" meta')
508+ _ -> lookupMetaString key' meta'
509+
500510 let docProps = mknode "cp:coreProperties"
501511 [("xmlns:cp","http://schemas.openxmlformats.org/package/2006/metadata/core-properties")
502512 ,("xmlns:dc","http://purl.org/dc/elements/1.1/")
@@ -505,14 +515,19 @@ writeDocx opts doc@(Pandoc meta _) = do
505515 ,("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance")]
506516 $ mknode "dc:title" [] (stringify $ docTitle meta)
507517 : mknode "dc:creator" [] (intercalate "; " (map stringify $ docAuthors meta))
508− : mknode "cp:keywords" [] (intercalate ", " keywords)
518+ : [ mknode (M.findWithDefault "" k extraCorePropsMap) [] (lookupMetaString' k meta)
519+ | k <- M.keys (unMeta meta), k `elem` extraCoreProps]
520+ ++ mknode "cp:keywords" [] (intercalate ", " keywords)
509521 : (\x -> [ mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")] x
510522 , mknode "dcterms:modified" [("xsi:type","dcterms:W3CDTF")] x
511523 ]) (formatTime defaultTimeLocale "%FT%XZ" utctime)
512524 let docPropsEntry = toEntry docPropsPath epochtime $ renderXml docProps
513525
526+ -- docProps/custom.xml
514527 let customProperties :: [(String, String)]
515− customProperties = [] -- FIXME
528+ customProperties = [(k, lookupMetaString k meta) | k <- M.keys (unMeta meta)
529+ , k `notElem` (["title", "author", "keywords"]
530+ ++ extraCoreProps)]
516531 let mkCustomProp (k, v) pid = mknode "property"
517532 [("fmtid","{D5CDD505-2E9C-101B-9397-08002B2CF9AE}")
518533 ,("pid", show pid)
src/Text/Pandoc/Writers/ODT.hs+27−9
@@ -40,6 +40,7 @@ import Data.List (isPrefixOf, intercalate)
4040import Data.Maybe (fromMaybe)
4141import qualified Data.Map as Map
4242import qualified Data.Text.Lazy as TL
43+import Data.Time
4344import System.FilePath (takeDirectory, takeExtension, (<.>))
4445import Text.Pandoc.BCP47 (Lang (..), getLang, renderLang)
4546import Text.Pandoc.Class (PandocMonad, report, toLang)
@@ -50,8 +51,9 @@ import Text.Pandoc.Logging
5051import Text.Pandoc.MIME (extensionFromMimeType, getMimeType)
5152import Text.Pandoc.Options (WrapOption (..), WriterOptions (..))
5253import Text.Pandoc.Pretty
53−import Text.Pandoc.Shared (stringify, normalizeDate)
54−import Text.Pandoc.Writers.Shared (lookupMetaString, fixDisplayMath)
54+import Text.Pandoc.Shared (stringify, pandocVersion)
55+import Text.Pandoc.Writers.Shared (lookupMetaString, lookupMetaBlocks,
56+ fixDisplayMath)
5557import Text.Pandoc.UTF8 (fromStringLazy, fromTextLazy, toStringLazy)
5658import Text.Pandoc.Walk
5759import Text.Pandoc.Writers.OpenDocument (writeOpenDocument)
@@ -83,6 +85,7 @@ pandocToODT :: PandocMonad m
8385pandocToODT opts doc@(Pandoc meta _) = do
8486 let title = docTitle meta
8587 let authors = docAuthors meta
88+ utctime <- P.getCurrentTime
8689 lang <- toLang (getLang opts meta)
8790 refArchive <-
8891 case writerReferenceDoc opts of
@@ -125,9 +128,14 @@ pandocToODT opts doc@(Pandoc meta _) = do
125128 )
126129 )
127130 let archive' = addEntryToArchive manifestEntry archive
131+ -- create meta.xml
128132 let userDefinedMetaFields = [k | k <- Map.keys (unMeta meta)
129− , k `notElem` ["title", "lang", "author", "date"]]
133+ , k `notElem` ["title", "lang", "author"
134+ , "description", "subject", "keywords"]]
130135 let escapedText = text . escapeStringForXML
136+ let keywords = case lookupMeta "keywords" meta of
137+ Just (MetaList xs) -> map stringify xs
138+ _ -> []
131139 let userDefinedMeta =
132140 map (\k -> inTags False "meta:user-defined"
133141 [ ("meta:name", escapeStringForXML k)
@@ -146,19 +154,29 @@ pandocToODT opts doc@(Pandoc meta _) = do
146154 ,("xmlns:ooo","http://openoffice.org/2004/office")
147155 ,("xmlns:grddl","http://www.w3.org/2003/g/data-view#")
148156 ,("office:version","1.2")] ( inTags True "office:meta" [] $
149− ( metaTag "dc:title" (stringify title)
157+ ( metaTag "meta:generator" ("Pandoc/" ++ pandocVersion)
158+ $$
159+ metaTag "dc:title" (stringify title)
160+ $$
161+ metaTag "dc:description"
162+ (intercalate "\n" (map stringify $
163+ lookupMetaBlocks "description" meta))
164+ $$
165+ metaTag "dc:subject" (lookupMetaString "subject" meta)
166+ $$
167+ metaTag "meta:keyword" (intercalate ", " keywords)
150168 $$
151169 case lang of
152170 Just l -> metaTag "dc:language" (renderLang l)
153171 Nothing -> empty
154172 $$
155− metaTag "dc:creator"
173+ (\d a -> metaTag "meta:initial-creator" a
174+ $$ metaTag "dc:creator" a
175+ $$ metaTag "meta:creation-date" d
176+ $$ metaTag "dc:date" d
177+ ) (formatTime defaultTimeLocale "%FT%XZ" utctime)
156178 (intercalate "; " (map stringify authors))
157179 $$
158− maybe mempty
159− (metaTag "dc:date")
160− (normalizeDate (lookupMetaString "date" meta))
161− $$
162180 vcat userDefinedMeta
163181 )
164182 )
src/Text/Pandoc/Writers/Powerpoint/Output.hs+36−5
@@ -58,7 +58,7 @@ import Text.Pandoc.MIME
5858import qualified Data.ByteString.Lazy as BL
5959import Text.Pandoc.Writers.OOXML
6060import qualified Data.Map as M
61−import Data.Maybe (mapMaybe, listToMaybe, fromMaybe, maybeToList, catMaybes)
61+import Data.Maybe (mapMaybe, listToMaybe, fromMaybe, maybeToList, catMaybes, isNothing)
6262import Text.Pandoc.ImageSize
6363import Control.Applicative ((<|>))
6464import System.FilePath.Glob
@@ -252,6 +252,8 @@ presentationToArchiveP p@(Presentation docProps slides) = do
252252 newArch' <- foldM copyFileToArchive emptyArchive filePaths
253253 -- we make a docProps/core.xml entry out of the presentation docprops
254254 docPropsEntry <- docPropsToEntry docProps
255+ -- we make a docProps/custom.xml entry out of the custom properties
256+ docCustomPropsEntry <- docCustomPropsToEntry docProps
255257 -- we make this ourself in case there's something unexpected in the
256258 -- one in the reference doc.
257259 relsEntry <- topLevelRelsEntry
@@ -274,7 +276,8 @@ presentationToArchiveP p@(Presentation docProps slides) = do
274276 spkNotesEntries ++
275277 spkNotesRelEntries ++
276278 mediaEntries ++
277− [contentTypesEntry, docPropsEntry, relsEntry, presEntry, presRelsEntry]
279+ [contentTypesEntry, docPropsEntry, docCustomPropsEntry, relsEntry,
280+ presEntry, presRelsEntry]
278281
279282makeSlideIdMap :: Presentation -> M.Map SlideId Int
280283makeSlideIdMap (Presentation _ slides) =
@@ -1425,6 +1428,10 @@ topLevelRels =
14251428 , relType = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/extended-properties"
14261429 , relTarget = "docProps/app.xml"
14271430 }
1431+ , Relationship { relId = 4
1432+ , relType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties"
1433+ , relTarget = "docProps/custom.xml"
1434+ }
14281435 ]
14291436
14301437topLevelRelsEntry :: PandocMonad m => P m Entry
@@ -1657,7 +1664,7 @@ docPropsElement :: PandocMonad m => DocProps -> P m Element
16571664docPropsElement docProps = do
16581665 utctime <- asks envUTCTime
16591666 let keywords = case dcKeywords docProps of
1660− Just xs -> intercalate "," xs
1667+ Just xs -> intercalate ", " xs
16611668 Nothing -> ""
16621669 return $
16631670 mknode "cp:coreProperties"
@@ -1669,7 +1676,13 @@ docPropsElement docProps = do
16691676 $ (mknode "dc:title" [] $ fromMaybe "" $ dcTitle docProps)
16701677 : (mknode "dc:creator" [] $ fromMaybe "" $ dcCreator docProps)
16711678 : (mknode "cp:keywords" [] keywords)
1672− : (\x -> [ mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")] x
1679+ : (if isNothing (dcSubject docProps) then [] else
1680+ [mknode "dc:subject" [] $ fromMaybe "" $ dcSubject docProps])
1681+ ++ (if isNothing (dcDescription docProps) then [] else
1682+ [mknode "dc:description" [] $ fromMaybe "" $ dcDescription docProps])
1683+ ++ (if isNothing (cpCategory docProps) then [] else
1684+ [mknode "cp:category" [] $ fromMaybe "" $ cpCategory docProps])
1685+ ++ (\x -> [ mknode "dcterms:created" [("xsi:type","dcterms:W3CDTF")] x
16731686 , mknode "dcterms:modified" [("xsi:type","dcterms:W3CDTF")] x
16741687 ]) (formatTime defaultTimeLocale "%FT%XZ" utctime)
16751688
@@ -1677,6 +1690,21 @@ docPropsToEntry :: PandocMonad m => DocProps -> P m Entry
16771690docPropsToEntry docProps = docPropsElement docProps >>=
16781691 elemToEntry "docProps/core.xml"
16791692
1693+-- adapted from the Docx writer
1694+docCustomPropsElement :: PandocMonad m => DocProps -> P m Element
1695+docCustomPropsElement docProps = do
1696+ let mkCustomProp (k, v) pid = mknode "property"
1697+ [("fmtid","{D5CDD505-2E9C-101B-9397-08002B2CF9AE}")
1698+ ,("pid", show pid)
1699+ ,("name", k)] $ mknode "vt:lpwstr" [] v
1700+ return $ mknode "Properties"
1701+ [("xmlns","http://schemas.openxmlformats.org/officeDocument/2006/custom-properties")
1702+ ,("xmlns:vt","http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes")
1703+ ] $ zipWith mkCustomProp (fromMaybe [] $ customProperties docProps) [(2 :: Int)..]
1704+
1705+docCustomPropsToEntry :: PandocMonad m => DocProps -> P m Entry
1706+docCustomPropsToEntry docProps = docCustomPropsElement docProps >>=
1707+ elemToEntry "docProps/custom.xml"
16801708
16811709defaultContentTypeToElem :: DefaultContentType -> Element
16821710defaultContentTypeToElem dct =
@@ -1765,6 +1793,7 @@ presentationToContentTypes p@(Presentation _ slides) = do
17651793
17661794 inheritedOverrides = mapMaybe pathToOverride filePaths
17671795 docPropsOverride = mapMaybe pathToOverride ["docProps/core.xml"]
1796+ docCustomPropsOverride = mapMaybe pathToOverride ["docProps/custom.xml"]
17681797 presOverride = mapMaybe pathToOverride ["ppt/presentation.xml"]
17691798 relativePaths <- mapM slideToFilePath slides
17701799 let slideOverrides = mapMaybe
@@ -1773,7 +1802,8 @@ presentationToContentTypes p@(Presentation _ slides) = do
17731802 speakerNotesOverrides <- (mapMaybe pathToOverride) <$> getSpeakerNotesFilePaths
17741803 return $ ContentTypes
17751804 (defaults ++ mediaDefaults)
1776− (inheritedOverrides ++ docPropsOverride ++ presOverride ++ slideOverrides ++ speakerNotesOverrides)
1805+ (inheritedOverrides ++ docPropsOverride ++ docCustomPropsOverride ++
1806+ presOverride ++ slideOverrides ++ speakerNotesOverrides)
17771807
17781808presML :: String
17791809presML = "application/vnd.openxmlformats-officedocument.presentationml"
@@ -1788,6 +1818,7 @@ getContentType fp
17881818 | fp == "ppt/viewProps.xml" = Just $ presML ++ ".viewProps+xml"
17891819 | fp == "ppt/tableStyles.xml" = Just $ presML ++ ".tableStyles+xml"
17901820 | fp == "docProps/core.xml" = Just $ "application/vnd.openxmlformats-package.core-properties+xml"
1821+ | fp == "docProps/custom.xml" = Just $ "application/vnd.openxmlformats-officedocument.custom-properties+xml"
17911822 | fp == "docProps/app.xml" = Just $ noPresML ++ ".extended-properties+xml"
17921823 | "ppt" : "slideMasters" : f : [] <- splitDirectories fp
17931824 , (_, ".xml") <- splitExtension f =
src/Text/Pandoc/Writers/Powerpoint/Presentation.hs+19−2
@@ -72,7 +72,8 @@ import Text.Pandoc.Logging
7272import Text.Pandoc.Walk
7373import Data.Time (UTCTime)
7474import qualified Text.Pandoc.Shared as Shared -- so we don't overlap "Element"
75−import Text.Pandoc.Writers.Shared (lookupMetaInlines, toTableOfContents)
75+import Text.Pandoc.Writers.Shared (lookupMetaInlines, lookupMetaBlocks
76+ , lookupMetaString, toTableOfContents)
7677import qualified Data.Map as M
7778import qualified Data.Set as S
7879import Data.Maybe (maybeToList, fromMaybe)
@@ -180,7 +181,10 @@ data DocProps = DocProps { dcTitle :: Maybe String
180181 , dcSubject :: Maybe String
181182 , dcCreator :: Maybe String
182183 , dcKeywords :: Maybe [String]
184+ , dcDescription :: Maybe String
185+ , cpCategory :: Maybe String
183186 , dcCreated :: Maybe UTCTime
187+ , customProperties :: Maybe [(String, String)]
184188 } deriving (Show, Eq)
185189
186190
@@ -930,13 +934,26 @@ metaToDocProps meta =
930934
931935 authors = case map Shared.stringify $ docAuthors meta of
932936 [] -> Nothing
933− ss -> Just $ intercalate ";" ss
937+ ss -> Just $ intercalate "; " ss
938+
939+ description = case map Shared.stringify $ lookupMetaBlocks "description" meta of
940+ [] -> Nothing
941+ ss -> Just $ intercalate "_x000d_\n" ss
942+
943+ customProperties' = case [(k, lookupMetaString k meta) | k <- M.keys (unMeta meta)
944+ , k `notElem` (["title", "author", "keywords", "description"
945+ , "subject","lang","category"])] of
946+ [] -> Nothing
947+ ss -> Just ss
934948 in
935949 DocProps{ dcTitle = Shared.stringify <$> lookupMeta "title" meta
936950 , dcSubject = Shared.stringify <$> lookupMeta "subject" meta
937951 , dcCreator = authors
938952 , dcKeywords = keywords
953+ , dcDescription = description
954+ , cpCategory = Shared.stringify <$> lookupMeta "category" meta
939955 , dcCreated = Nothing
956+ , customProperties = customProperties'
940957 }
941958
942959documentToPresentation :: WriterOptions
test/Tests/Writers/Docx.hs+10
@@ -156,4 +156,14 @@ tests = [ testGroup "inlines"
156156 "docx/custom_style.native"
157157 "docx/golden/custom_style_reference.docx"
158158 ]
159+ , testGroup "metadata"
160+ [ docxTest "document properties (core, custom)"
161+ def
162+ "docx/document-properties.native"
163+ "docx/golden/document-properties.docx"
164+ , docxTest "document properties (short description)"
165+ def
166+ "docx/document-properties-short-desc.native"
167+ "docx/golden/document-properties-short-desc.docx"
168+ ]
159169 ]
test/Tests/Writers/Powerpoint.hs+8
@@ -99,4 +99,12 @@ tests = groupPptxTests [ pptxTests "Inline formatting"
9999 def
100100 "pptx/raw_ooxml.native"
101101 "pptx/raw_ooxml.pptx"
102+ , pptxTests "metadata, custom properties"
103+ def
104+ "pptx/document-properties.native"
105+ "pptx/document-properties.pptx"
106+ , pptxTests "metadata, short description"
107+ def
108+ "pptx/document-properties-short-desc.native"
109+ "pptx/document-properties-short-desc.pptx"
102110 ]
test/docx/document-properties-short-desc.nativenew file+2
@@ -0,0 +1,2 @@
1+Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "A.",Space,Str "M."]]),("description",MetaInlines [Str "Short",Space,RawInline (Format "html") "<i>",Str "description",RawInline (Format "html") "</i>",Space,Str "&."]),("keywords",MetaList [MetaInlines [Str "keyword",Space,Str "1"],MetaInlines [Str "keyword",Space,Str "2"]]),("subject",MetaInlines [Str "This",Space,Str "is",Space,Str "the",Space,Str "subject"]),("title",MetaInlines [Str "Testing",Space,Str "custom",Space,Str "properties"])]})
2+[Para [Str "Testing",Space,Str "document",Space,Str "properties"]]
test/docx/document-properties.nativenew file+2
@@ -0,0 +1,2 @@
1+Pandoc (Meta {unMeta = fromList [("Company",MetaInlines [Str "My",Space,Str "Company"]),("Second Custom Property",MetaInlines [Str "Second",Space,Str "custom",Space,Str "property",Space,Str "value"]),("abstract",MetaBlocks [Plain [Str "Quite",Space,Str "a",Space,Str "long",Space,Str "description",SoftBreak,Str "spanning",Space,Str "several",Space,Str "lines"]]),("author",MetaList [MetaInlines [Str "A.",Space,Str "M."]]),("category",MetaInlines [Str "My",Space,Str "Category"]),("custom1",MetaInlines [Str "First",Space,Str "custom",Space,Str "property",Space,Str "value"]),("custom3",MetaInlines [Str "Escaping",Space,Str "amp",Space,Str "&",Space,Str "."]),("custom4",MetaInlines [Str "Escaping",Space,Str "LT,GT",Space,Str "<",Space,Str "asdf",Space,Str ">",Space,Str "<"]),("custom5",MetaInlines [Str "Escaping",Space,Str "html",Space,RawInline (Format "html") "<i>",Str "asdf",RawInline (Format "html") "</i>"]),("custom6",MetaInlines [Str "Escaping",Space,Emph [Str "MD"],Space,Str "\225",Space,Str "a"]),("custom9",MetaInlines [Str "Extended",Space,Str "chars:",Space,Str "\8364",Space,Str "\225",Space,Str "\233",Space,Str "\237",Space,Str "\243",Space,Str "\250",Space,Str "$"]),("description",MetaBlocks [Para [Str "Long",Space,Str "description",Space,Str "spanning",SoftBreak,Str "several",Space,Str "lines."],Plain [Str "This",Space,Str "is",Space,Str "\225",Space,Str "second",Space,RawInline (Format "html") "<i>",Str "line",RawInline (Format "html") "</i>",Str "."]]),("keywords",MetaList [MetaInlines [Str "keyword",Space,Str "1"],MetaInlines [Str "keyword",Space,Str "2"]]),("lang",MetaInlines [Str "en-US"]),("nested-custom",MetaList [MetaMap (fromList [("custom 7",MetaInlines [Str "Nested",Space,Str "Custom",Space,Str "value",Space,Str "7"])]),MetaMap (fromList [("custom 8",MetaInlines [Str "Nested",Space,Str "Custom",Space,Str "value",Space,Str "8"])])]),("subject",MetaInlines [Str "This",Space,Str "is",Space,Str "the",Space,Str "subject"]),("subtitle",MetaInlines [Str "This",Space,Str "is",Space,Str "a",Space,Str "subtitle"]),("title",MetaInlines [Str "Testing",Space,Str "custom",Space,Str "properties"])]})
2+[Para [Str "Testing",Space,Str "document",Space,Str "properties"]]
test/docx/golden/document-properties-short-desc.docxnew file

Binary file not shown.

test/docx/golden/document-properties.docxnew file

Binary file not shown.

test/pptx/document-properties-short-desc.nativenew file+2
@@ -0,0 +1,2 @@
1+Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "A.",Space,Str "M."]]),("description",MetaInlines [Str "Short",Space,RawInline (Format "html") "<i>",Str "description",RawInline (Format "html") "</i>",Space,Str "&."]),("keywords",MetaList [MetaInlines [Str "keyword",Space,Str "1"],MetaInlines [Str "keyword",Space,Str "2"]]),("subject",MetaInlines [Str "This",Space,Str "is",Space,Str "the",Space,Str "subject"]),("title",MetaInlines [Str "Testing",Space,Str "custom",Space,Str "properties"])]})
2+[Para [Str "Testing",Space,Str "document",Space,Str "properties"]]
test/pptx/document-properties-short-desc.pptxnew file

Binary file not shown.

test/pptx/document-properties-short-desc_templated.pptxnew file

Binary file not shown.

test/pptx/document-properties.nativenew file+2
@@ -0,0 +1,2 @@
1+Pandoc (Meta {unMeta = fromList [("Company",MetaInlines [Str "My",Space,Str "Company"]),("Second Custom Property",MetaInlines [Str "Second",Space,Str "custom",Space,Str "property",Space,Str "value"]),("abstract",MetaBlocks [Plain [Str "Quite",Space,Str "a",Space,Str "long",Space,Str "description",SoftBreak,Str "spanning",Space,Str "several",Space,Str "lines"]]),("author",MetaList [MetaInlines [Str "A.",Space,Str "M."]]),("category",MetaInlines [Str "My",Space,Str "Category"]),("custom1",MetaInlines [Str "First",Space,Str "custom",Space,Str "property",Space,Str "value"]),("custom3",MetaInlines [Str "Escaping",Space,Str "amp",Space,Str "&",Space,Str "."]),("custom4",MetaInlines [Str "Escaping",Space,Str "LT,GT",Space,Str "<",Space,Str "asdf",Space,Str ">",Space,Str "<"]),("custom5",MetaInlines [Str "Escaping",Space,Str "html",Space,RawInline (Format "html") "<i>",Str "asdf",RawInline (Format "html") "</i>"]),("custom6",MetaInlines [Str "Escaping",Space,Emph [Str "MD"],Space,Str "\225",Space,Str "a"]),("custom9",MetaInlines [Str "Extended",Space,Str "chars:",Space,Str "\8364",Space,Str "\225",Space,Str "\233",Space,Str "\237",Space,Str "\243",Space,Str "\250",Space,Str "$"]),("description",MetaBlocks [Para [Str "Long",Space,Str "description",Space,Str "spanning",SoftBreak,Str "several",Space,Str "lines."],Plain [Str "This",Space,Str "is",Space,Str "\225",Space,Str "second",Space,RawInline (Format "html") "<i>",Str "line",RawInline (Format "html") "</i>",Str "."]]),("keywords",MetaList [MetaInlines [Str "keyword",Space,Str "1"],MetaInlines [Str "keyword",Space,Str "2"]]),("lang",MetaInlines [Str "en-US"]),("nested-custom",MetaList [MetaMap (fromList [("custom 7",MetaInlines [Str "Nested",Space,Str "Custom",Space,Str "value",Space,Str "7"])]),MetaMap (fromList [("custom 8",MetaInlines [Str "Nested",Space,Str "Custom",Space,Str "value",Space,Str "8"])])]),("subject",MetaInlines [Str "This",Space,Str "is",Space,Str "the",Space,Str "subject"]),("subtitle",MetaInlines [Str "This",Space,Str "is",Space,Str "a",Space,Str "subtitle"]),("title",MetaInlines [Str "Testing",Space,Str "custom",Space,Str "properties"])]})
2+[Para [Str "Testing",Space,Str "document",Space,Str "properties"]]
test/pptx/document-properties.pptxnew file

Binary file not shown.

test/pptx/document-properties_templated.pptxnew file

Binary file not shown.

test/pptx/endnotes.pptx

Binary file not shown.

test/pptx/endnotes_templated.pptx

Binary file not shown.

test/pptx/endnotes_toc.pptx

Binary file not shown.

test/pptx/endnotes_toc_templated.pptx

Binary file not shown.

test/pptx/images.pptx

Binary file not shown.

test/pptx/images_templated.pptx

Binary file not shown.

test/pptx/inline_formatting.pptx

Binary file not shown.

test/pptx/inline_formatting_templated.pptx

Binary file not shown.

test/pptx/lists.pptx

Binary file not shown.

test/pptx/lists_templated.pptx

Binary file not shown.

test/pptx/raw_ooxml.pptx

Binary file not shown.

test/pptx/raw_ooxml_templated.pptx

Binary file not shown.

test/pptx/remove_empty_slides.pptx

Binary file not shown.

test/pptx/remove_empty_slides_templated.pptx

Binary file not shown.

test/pptx/slide_breaks.pptx

Binary file not shown.

test/pptx/slide_breaks_slide_level_1.pptx

Binary file not shown.

test/pptx/slide_breaks_slide_level_1_templated.pptx

Binary file not shown.

test/pptx/slide_breaks_templated.pptx

Binary file not shown.

test/pptx/slide_breaks_toc.pptx

Binary file not shown.

test/pptx/slide_breaks_toc_templated.pptx

Binary file not shown.

test/pptx/speaker_notes.pptx

Binary file not shown.

test/pptx/speaker_notes_afterseps.pptx

Binary file not shown.

test/pptx/speaker_notes_afterseps_templated.pptx

Binary file not shown.

test/pptx/speaker_notes_templated.pptx

Binary file not shown.

test/pptx/tables.pptx

Binary file not shown.

test/pptx/tables_templated.pptx

Binary file not shown.

test/pptx/two_column.pptx

Binary file not shown.

test/pptx/two_column_templated.pptx

Binary file not shown.