git.iko.soy/typeable/pandoc
on master help sign in
introduce --metadata-file option

closes #1960 API change: Text.Pandoc.Readers.Markdown exports now `yamlToMeta`

commit6aa5fcac13ea702de19ee1a605631e3ac75d7e05 authormb21 <mb21@users.noreply.github.com> dateFri 30 Mar 2018, 21:48 (9 years ago) parent73fa70c
3 files changed+44−3
MANUAL.txt+13−1 src/Text/Pandoc/App.hs+17 src/Text/Pandoc/Readers/Markdown.hs+14−2
MANUAL.txt+13−1
@@ -578,6 +578,16 @@ Reader options
578578 printed in some output formats) and metadata values will be escaped
579579 when inserted into the template.
580580
581+`--metadata-file=`*FILE*
582+
583+: Read metadata from the supplied YAML (or JSON) file.
584+ This option can be used with every input format, but string
585+ scalars in the YAML file will always be parsed as Markdown.
586+ Generally, the input will be handled the same as in
587+ [YAML metadata blocks][Extension: `yaml_metadata_block`].
588+ Metadata values specified inside the document, or by using `-M`,
589+ overwrite values specified with this option.
590+
581591`-p`, `--preserve-tabs`
582592
583593: Preserve tabs instead of converting them to spaces (the default).
@@ -3061,7 +3071,9 @@ and pass it to pandoc as an argument, along with your Markdown files:
30613071 pandoc chap1.md chap2.md chap3.md metadata.yaml -s -o book.html
30623072
30633073Just be sure that the YAML file begins with `---` and ends with `---` or
3064−`...`.)
3074+`...`.) Alternatively, you can use the `--metadata-file` option. Using
3075+that approach however, you cannot reference content (like footnotes)
3076+from the main markdown input document.
30653077
30663078Metadata will be taken from the fields of the YAML object and added to any
30673079existing document metadata. Metadata can contain lists and objects (nested
src/Text/Pandoc/App.hs+17
@@ -89,6 +89,7 @@ import Text.Pandoc.Builder (setMeta, deleteMeta)
8989import Text.Pandoc.Filter (Filter (JSONFilter, LuaFilter), applyFilters)
9090import Text.Pandoc.Highlighting (highlightingStyles)
9191import Text.Pandoc.PDF (makePDF)
92+import Text.Pandoc.Readers.Markdown (yamlToMeta)
9293import Text.Pandoc.SelfContained (makeDataURI, makeSelfContained)
9394import Text.Pandoc.Shared (eastAsianLineBreakFilter, stripEmptyParagraphs,
9495 headerShift, isURI, ordNub, safeRead, tabFilter, uriPathToPath)
@@ -399,6 +400,10 @@ convertWithOpts opts = do
399400 ("application/xml", jatsCSL)
400401 return $ ("csl", jatsEncoded) : optMetadata opts
401402 else return $ optMetadata opts
403+ metadataFromFile <-
404+ case optMetadataFile opts of
405+ Nothing -> return mempty
406+ Just file -> readFileLazy file >>= yamlToMeta
402407
403408 case lookup "lang" (optMetadata opts) of
404409 Just l -> case parseBCP47 l of
@@ -491,6 +496,7 @@ convertWithOpts opts = do
491496 ( (if isJust (optExtractMedia opts)
492497 then fillMediaBag
493498 else return)
499+ >=> return . addNonPresentMetadata metadataFromFile
494500 >=> return . addMetadata metadata
495501 >=> applyTransforms transforms
496502 >=> applyFilters readerOpts filters' [format]
@@ -556,6 +562,7 @@ data Opt = Opt
556562 , optTemplate :: Maybe FilePath -- ^ Custom template
557563 , optVariables :: [(String,String)] -- ^ Template variables to set
558564 , optMetadata :: [(String, String)] -- ^ Metadata fields to set
565+ , optMetadataFile :: Maybe FilePath -- ^ Name of YAML metadata file
559566 , optOutputFile :: Maybe FilePath -- ^ Name of output file
560567 , optInputFiles :: [FilePath] -- ^ Names of input files
561568 , optNumberSections :: Bool -- ^ Number sections in LaTeX
@@ -628,6 +635,7 @@ defaultOpts = Opt
628635 , optTemplate = Nothing
629636 , optVariables = []
630637 , optMetadata = []
638+ , optMetadataFile = Nothing
631639 , optOutputFile = Nothing
632640 , optInputFiles = []
633641 , optNumberSections = False
@@ -687,6 +695,9 @@ defaultOpts = Opt
687695 , optStripComments = False
688696 }
689697
698+addNonPresentMetadata :: Text.Pandoc.Meta -> Pandoc -> Pandoc
699+addNonPresentMetadata newmeta (Pandoc meta bs) = Pandoc (meta <> newmeta) bs
700+
690701addMetadata :: [(String, String)] -> Pandoc -> Pandoc
691702addMetadata kvs pdc = foldr addMeta (removeMetaKeys kvs pdc) kvs
692703
@@ -963,6 +974,12 @@ options =
963974 "KEY[:VALUE]")
964975 ""
965976
977+ , Option "" ["metadata-file"]
978+ (ReqArg
979+ (\arg opt -> return opt{ optMetadataFile = Just arg })
980+ "FILE")
981+ ""
982+
966983 , Option "V" ["variable"]
967984 (ReqArg
968985 (\arg opt -> do
src/Text/Pandoc/Readers/Markdown.hs+14−2
@@ -31,7 +31,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3131
3232Conversion of markdown-formatted plain text to 'Pandoc' document.
3333-}
34−module Text.Pandoc.Readers.Markdown ( readMarkdown ) where
34+module Text.Pandoc.Readers.Markdown ( readMarkdown, yamlToMeta ) where
3535
3636import Prelude
3737import Control.Monad
@@ -246,11 +246,23 @@ yamlMetaBlock = try $ do
246246 updateState $ \st -> st{ stateMeta' = (stateMeta' st) <> newMetaF }
247247 return mempty
248248
249+-- | Read a YAML string and convert it to pandoc metadata.
250+-- String scalars in the YAML are parsed as Markdown.
251+yamlToMeta :: PandocMonad m => BS.ByteString -> m Meta
252+yamlToMeta bstr = do
253+ let parser = do
254+ meta <- yamlBsToMeta bstr
255+ return $ runF meta defaultParserState
256+ parsed <- readWithM parser def ""
257+ case parsed of
258+ Right result -> return result
259+ Left e -> throwError e
260+
249261yamlBsToMeta :: PandocMonad m => BS.ByteString -> MarkdownParser m (F Meta)
250262yamlBsToMeta bstr = do
251263 pos <- getPosition
252264 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
253− Right [YAML.Doc (YAML.Mapping _ o)] -> (fmap Meta) <$> yamlMap o
265+ Right ((YAML.Doc (YAML.Mapping _ o)):_) -> (fmap Meta) <$> yamlMap o
254266 Right [] -> return . return $ mempty
255267 Right [YAML.Doc (YAML.Scalar YAML.SNull)] -> return . return $ mempty
256268 Right _ -> do