git.iko.soy/typeable/pandoc
on master help sign in
Raise informative errors when YAML metadata parsing fails.

Closes #6730. Previously the command would succeed, returning empty metadata, with no errors or warnings. API changes: - Remove now unused CouldNotParseYamlMetadata constructor for LogMessage (T.P.Logging). - Add 'Maybe FilePath' parameter to yamlToMeta in T.P.Readers.Markdown.

commit428f8b4d204bf90118f01b0a03b6763b626a6532 authorJohn MacFarlane <jgm@berkeley.edu> dateWed 7 Oct 2020, 13:02 (6 years ago) parent69b030c
6 files changed+37−42
src/Text/Pandoc/App.hs+3−2 src/Text/Pandoc/Citeproc.hs+4−2 src/Text/Pandoc/Logging.hs−10 src/Text/Pandoc/Parsing.hs+2 src/Text/Pandoc/Readers/Markdown.hs+14−2 src/Text/Pandoc/Readers/Metadata.hs+14−26
src/Text/Pandoc/App.hs+3−2
@@ -221,8 +221,9 @@ convertWithOpts opts = do
221221 metadataFromFile <-
222222 case optMetadataFiles opts of
223223 [] -> return mempty
224− paths -> mapM readFileLazy paths >>=
225− fmap mconcat . mapM (yamlToMeta readerOpts)
224+ paths -> mconcat <$>
225+ mapM (\path -> do raw <- readFileLazy path
226+ yamlToMeta readerOpts (Just path) raw) paths
226227
227228 let transforms = (case optShiftHeadingLevelBy opts of
228229 0 -> id
src/Text/Pandoc/Citeproc.hs+4−2
@@ -191,7 +191,7 @@ getRefsFromBib locale idpred t = do
191191 let fp = T.unpack t
192192 raw <- readFileStrict fp
193193 case formatFromExtension fp of
194− Just f -> getRefs locale f idpred raw
194+ Just f -> getRefs locale f idpred (Just fp) raw
195195 Nothing -> throwError $ PandocAppError $
196196 "Could not deterine bibliography format for " <> t
197197
@@ -199,9 +199,10 @@ getRefs :: PandocMonad m
199199 => Locale
200200 -> BibFormat
201201 -> (Text -> Bool)
202+ -> Maybe FilePath
202203 -> ByteString
203204 -> m [Reference Inlines]
204−getRefs locale format idpred raw =
205+getRefs locale format idpred mbfp raw =
205206 case format of
206207 Format_bibtex ->
207208 either (throwError . PandocAppError . T.pack . show) return .
@@ -216,6 +217,7 @@ getRefs locale format idpred raw =
216217 Format_yaml -> do
217218 rs <- yamlToRefs idpred
218219 def{ readerExtensions = pandocExtensions }
220+ mbfp
219221 (L.fromStrict raw)
220222 return $ mapMaybe metaValueToReference rs
221223
src/Text/Pandoc/Logging.hs−10
@@ -61,7 +61,6 @@ instance FromYAML Verbosity where
6161data LogMessage =
6262 SkippedContent Text.Text SourcePos
6363 | IgnoredElement Text.Text
64− | CouldNotParseYamlMetadata Text.Text SourcePos
6564 | DuplicateLinkReference Text.Text SourcePos
6665 | DuplicateNoteReference Text.Text SourcePos
6766 | NoteDefinedButNotUsed Text.Text SourcePos
@@ -113,11 +112,6 @@ instance ToJSON LogMessage where
113112 "column" .= sourceColumn pos]
114113 IgnoredElement s ->
115114 ["contents" .= s]
116− CouldNotParseYamlMetadata s pos ->
117− ["message" .= s,
118− "source" .= sourceName pos,
119− "line" .= toJSON (sourceLine pos),
120− "column" .= toJSON (sourceColumn pos)]
121115 DuplicateLinkReference s pos ->
122116 ["contents" .= s,
123117 "source" .= sourceName pos,
@@ -251,9 +245,6 @@ showLogMessage msg =
251245 "Skipped '" <> s <> "' at " <> showPos pos
252246 IgnoredElement s ->
253247 "Ignored element " <> s
254− CouldNotParseYamlMetadata s pos ->
255− "Could not parse YAML metadata at " <> showPos pos <>
256− if Text.null s then "" else ": " <> s
257248 DuplicateLinkReference s pos ->
258249 "Duplicate link reference '" <> s <> "' at " <> showPos pos
259250 DuplicateNoteReference s pos ->
@@ -348,7 +339,6 @@ messageVerbosity msg =
348339 case msg of
349340 SkippedContent{} -> INFO
350341 IgnoredElement{} -> INFO
351− CouldNotParseYamlMetadata{} -> WARNING
352342 DuplicateLinkReference{} -> WARNING
353343 DuplicateNoteReference{} -> WARNING
354344 NoteDefinedButNotUsed{} -> WARNING
src/Text/Pandoc/Parsing.hs+2
@@ -179,7 +179,9 @@ module Text.Pandoc.Parsing ( take1WhileP,
179179 setSourceColumn,
180180 setSourceLine,
181181 incSourceColumn,
182+ incSourceLine,
182183 newPos,
184+ initialPos,
183185 Line,
184186 Column
185187 )
src/Text/Pandoc/Readers/Markdown.hs+14−2
@@ -67,11 +67,17 @@ readMarkdown opts s = do
6767-- String scalars in the YAML are parsed as Markdown.
6868yamlToMeta :: PandocMonad m
6969 => ReaderOptions
70+ -> Maybe FilePath
7071 -> BL.ByteString
7172 -> m Meta
72−yamlToMeta opts bstr = do
73+yamlToMeta opts mbfp bstr = do
7374 let parser = do
75+ oldPos <- getPosition
76+ case mbfp of
77+ Nothing -> return ()
78+ Just fp -> setPosition $ initialPos fp
7479 meta <- yamlBsToMeta (fmap B.toMetaValue <$> parseBlocks) bstr
80+ setPosition oldPos
7581 return $ runF meta defaultParserState
7682 parsed <- readWithM parser def{ stateOptions = opts } ""
7783 case parsed of
@@ -84,11 +90,17 @@ yamlToMeta opts bstr = do
8490yamlToRefs :: PandocMonad m
8591 => (Text -> Bool)
8692 -> ReaderOptions
93+ -> Maybe FilePath
8794 -> BL.ByteString
8895 -> m [MetaValue]
89−yamlToRefs idpred opts bstr = do
96+yamlToRefs idpred opts mbfp bstr = do
9097 let parser = do
98+ oldPos <- getPosition
99+ case mbfp of
100+ Nothing -> return ()
101+ Just fp -> setPosition $ initialPos fp
91102 refs <- yamlBsToRefs (fmap B.toMetaValue <$> parseBlocks) idpred bstr
103+ setPosition oldPos
92104 return $ runF refs defaultParserState
93105 parsed <- readWithM parser def{ stateOptions = opts } ""
94106 case parsed of
src/Text/Pandoc/Readers/Metadata.hs+14−26
@@ -37,21 +37,19 @@ yamlBsToMeta :: PandocMonad m
3737 -> BL.ByteString
3838 -> ParserT Text ParserState m (F Meta)
3939yamlBsToMeta pMetaValue bstr = do
40− pos <- getPosition
4140 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
4241 Right (YAML.Doc (YAML.Mapping _ _ o):_)
4342 -> fmap Meta <$> yamlMap pMetaValue o
4443 Right [] -> return . return $ mempty
4544 Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
4645 -> return . return $ mempty
47− Right _ -> do logMessage $ CouldNotParseYamlMetadata "not an object"
48− pos
49− return . return $ mempty
50− Left (_pos, err')
51− -> do logMessage $ CouldNotParseYamlMetadata
52− (T.pack err') pos
53− return . return $ mempty
54−
46+ Right _ -> fail "expected YAML object"
47+ Left (yamlpos, err')
48+ -> do pos <- getPosition
49+ setPosition $ incSourceLine
50+ (setSourceColumn pos (YE.posColumn yamlpos))
51+ (YE.posLine yamlpos - 1)
52+ fail err'
5553
5654fakePos :: YAML.Pos
5755fakePos = YAML.Pos (-1) (-1) 1 0
@@ -71,8 +69,7 @@ yamlBsToRefs :: PandocMonad m
7169 -> (Text -> Bool) -- ^ Filter for id
7270 -> BL.ByteString
7371 -> ParserT Text ParserState m (F [MetaValue])
74−yamlBsToRefs pMetaValue idpred bstr = do
75− pos <- getPosition
72+yamlBsToRefs pMetaValue idpred bstr =
7673 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
7774 Right (YAML.Doc o@(YAML.Mapping _ _ _):_)
7875 -> case lookupYAML "references" o of
@@ -90,26 +87,17 @@ yamlBsToRefs pMetaValue idpred bstr = do
9087 Nothing -> False
9188 sequence <$>
9289 mapM (yamlToMetaValue pMetaValue) (filter g ns)
93− Just _ -> do
94− logMessage $ CouldNotParseYamlMetadata
95− ("expecting sequence in 'references' field") pos
96− return . return $ mempty
97− Nothing -> do
98− logMessage $ CouldNotParseYamlMetadata
99− ("expecting 'references' field") pos
100− return . return $ mempty
90+ Just _ ->
91+ fail "expecting sequence in 'references' field"
92+ Nothing ->
93+ fail "expecting 'references' field"
10194
10295 Right [] -> return . return $ mempty
10396 Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
10497 -> return . return $ mempty
105− Right _ -> do logMessage $ CouldNotParseYamlMetadata "not an object"
106− pos
107− return . return $ mempty
98+ Right _ -> fail "expecting YAML object"
10899 Left (_pos, err')
109− -> do logMessage $ CouldNotParseYamlMetadata
110− (T.pack err') pos
111− return . return $ mempty
112−
100+ -> fail err'
113101
114102
115103nodeToKey :: YAML.Node YE.Pos -> Maybe Text