git.iko.soy/typeable/pandoc
on master help sign in
Raise informative errors when YAML metadata parsing fails.
428f8b4John MacFarlane
src/Text/Pandoc/App.hs+3−2
@@ -221,8 +221,9 @@ convertWithOpts opts = do
221 metadataFromFile <-
221 metadataFromFile <-
222 case optMetadataFiles opts of
222 case optMetadataFiles opts of
223 [] -> return mempty
223 [] -> return mempty
224+ paths -> mconcat <$>
224− paths -> mapM readFileLazy paths >>=
225+ mapM (\path -> do raw <- readFileLazy path
225− fmap mconcat . mapM (yamlToMeta readerOpts)
226+ yamlToMeta readerOpts (Just path) raw) paths
226
227
227 let transforms = (case optShiftHeadingLevelBy opts of
228 let transforms = (case optShiftHeadingLevelBy opts of
228 0 -> id
229 0 -> id
src/Text/Pandoc/Citeproc.hs+4−2
@@ -191,7 +191,7 @@ getRefsFromBib locale idpred t = do
191 let fp = T.unpack t
191 let fp = T.unpack t
192 raw <- readFileStrict fp
192 raw <- readFileStrict fp
193 case formatFromExtension fp of
193 case formatFromExtension fp of
194− Just f -> getRefs locale f idpred raw
194+ Just f -> getRefs locale f idpred (Just fp) raw
195 Nothing -> throwError $ PandocAppError $
195 Nothing -> throwError $ PandocAppError $
196 "Could not deterine bibliography format for " <> t
196 "Could not deterine bibliography format for " <> t
197
197
@@ -199,9 +199,10 @@ getRefs :: PandocMonad m
199 => Locale
199 => Locale
200 -> BibFormat
200 -> BibFormat
201 -> (Text -> Bool)
201 -> (Text -> Bool)
202+ -> Maybe FilePath
202 -> ByteString
203 -> ByteString
203 -> m [Reference Inlines]
204 -> m [Reference Inlines]
204−getRefs locale format idpred raw =
205+getRefs locale format idpred mbfp raw =
205 case format of
206 case format of
206 Format_bibtex ->
207 Format_bibtex ->
207 either (throwError . PandocAppError . T.pack . show) return .
208 either (throwError . PandocAppError . T.pack . show) return .
@@ -216,6 +217,7 @@ getRefs locale format idpred raw =
216 Format_yaml -> do
217 Format_yaml -> do
217 rs <- yamlToRefs idpred
218 rs <- yamlToRefs idpred
218 def{ readerExtensions = pandocExtensions }
219 def{ readerExtensions = pandocExtensions }
220+ mbfp
219 (L.fromStrict raw)
221 (L.fromStrict raw)
220 return $ mapMaybe metaValueToReference rs
222 return $ mapMaybe metaValueToReference rs
221
223
src/Text/Pandoc/Logging.hs−10
@@ -61,7 +61,6 @@ instance FromYAML Verbosity where
61data LogMessage =
61data LogMessage =
62 SkippedContent Text.Text SourcePos
62 SkippedContent Text.Text SourcePos
63 | IgnoredElement Text.Text
63 | IgnoredElement Text.Text
64− | CouldNotParseYamlMetadata Text.Text SourcePos
65 | DuplicateLinkReference Text.Text SourcePos
64 | DuplicateLinkReference Text.Text SourcePos
66 | DuplicateNoteReference Text.Text SourcePos
65 | DuplicateNoteReference Text.Text SourcePos
67 | NoteDefinedButNotUsed Text.Text SourcePos
66 | NoteDefinedButNotUsed Text.Text SourcePos
@@ -113,11 +112,6 @@ instance ToJSON LogMessage where
113 "column" .= sourceColumn pos]
112 "column" .= sourceColumn pos]
114 IgnoredElement s ->
113 IgnoredElement s ->
115 ["contents" .= s]
114 ["contents" .= s]
116− CouldNotParseYamlMetadata s pos ->
117− ["message" .= s,
118− "source" .= sourceName pos,
119− "line" .= toJSON (sourceLine pos),
120− "column" .= toJSON (sourceColumn pos)]
121 DuplicateLinkReference s pos ->
115 DuplicateLinkReference s pos ->
122 ["contents" .= s,
116 ["contents" .= s,
123 "source" .= sourceName pos,
117 "source" .= sourceName pos,
@@ -251,9 +245,6 @@ showLogMessage msg =
251 "Skipped '" <> s <> "' at " <> showPos pos
245 "Skipped '" <> s <> "' at " <> showPos pos
252 IgnoredElement s ->
246 IgnoredElement s ->
253 "Ignored element " <> s
247 "Ignored element " <> s
254− CouldNotParseYamlMetadata s pos ->
255− "Could not parse YAML metadata at " <> showPos pos <>
256− if Text.null s then "" else ": " <> s
257 DuplicateLinkReference s pos ->
248 DuplicateLinkReference s pos ->
258 "Duplicate link reference '" <> s <> "' at " <> showPos pos
249 "Duplicate link reference '" <> s <> "' at " <> showPos pos
259 DuplicateNoteReference s pos ->
250 DuplicateNoteReference s pos ->
@@ -348,7 +339,6 @@ messageVerbosity msg =
348 case msg of
339 case msg of
349 SkippedContent{} -> INFO
340 SkippedContent{} -> INFO
350 IgnoredElement{} -> INFO
341 IgnoredElement{} -> INFO
351− CouldNotParseYamlMetadata{} -> WARNING
352 DuplicateLinkReference{} -> WARNING
342 DuplicateLinkReference{} -> WARNING
353 DuplicateNoteReference{} -> WARNING
343 DuplicateNoteReference{} -> WARNING
354 NoteDefinedButNotUsed{} -> WARNING
344 NoteDefinedButNotUsed{} -> WARNING
src/Text/Pandoc/Parsing.hs+2
@@ -179,7 +179,9 @@ module Text.Pandoc.Parsing ( take1WhileP,
179 setSourceColumn,
179 setSourceColumn,
180 setSourceLine,
180 setSourceLine,
181 incSourceColumn,
181 incSourceColumn,
182+ incSourceLine,
182 newPos,
183 newPos,
184+ initialPos,
183 Line,
185 Line,
184 Column
186 Column
185 )
187 )
src/Text/Pandoc/Readers/Markdown.hs+14−2
@@ -67,11 +67,17 @@ readMarkdown opts s = do
67-- String scalars in the YAML are parsed as Markdown.
67-- String scalars in the YAML are parsed as Markdown.
68yamlToMeta :: PandocMonad m
68yamlToMeta :: PandocMonad m
69 => ReaderOptions
69 => ReaderOptions
70+ -> Maybe FilePath
70 -> BL.ByteString
71 -> BL.ByteString
71 -> m Meta
72 -> m Meta
72−yamlToMeta opts bstr = do
73+yamlToMeta opts mbfp bstr = do
73 let parser = do
74 let parser = do
75+ oldPos <- getPosition
76+ case mbfp of
77+ Nothing -> return ()
78+ Just fp -> setPosition $ initialPos fp
74 meta <- yamlBsToMeta (fmap B.toMetaValue <$> parseBlocks) bstr
79 meta <- yamlBsToMeta (fmap B.toMetaValue <$> parseBlocks) bstr
80+ setPosition oldPos
75 return $ runF meta defaultParserState
81 return $ runF meta defaultParserState
76 parsed <- readWithM parser def{ stateOptions = opts } ""
82 parsed <- readWithM parser def{ stateOptions = opts } ""
77 case parsed of
83 case parsed of
@@ -84,11 +90,17 @@ yamlToMeta opts bstr = do
84yamlToRefs :: PandocMonad m
90yamlToRefs :: PandocMonad m
85 => (Text -> Bool)
91 => (Text -> Bool)
86 -> ReaderOptions
92 -> ReaderOptions
93+ -> Maybe FilePath
87 -> BL.ByteString
94 -> BL.ByteString
88 -> m [MetaValue]
95 -> m [MetaValue]
89−yamlToRefs idpred opts bstr = do
96+yamlToRefs idpred opts mbfp bstr = do
90 let parser = do
97 let parser = do
98+ oldPos <- getPosition
99+ case mbfp of
100+ Nothing -> return ()
101+ Just fp -> setPosition $ initialPos fp
91 refs <- yamlBsToRefs (fmap B.toMetaValue <$> parseBlocks) idpred bstr
102 refs <- yamlBsToRefs (fmap B.toMetaValue <$> parseBlocks) idpred bstr
103+ setPosition oldPos
92 return $ runF refs defaultParserState
104 return $ runF refs defaultParserState
93 parsed <- readWithM parser def{ stateOptions = opts } ""
105 parsed <- readWithM parser def{ stateOptions = opts } ""
94 case parsed of
106 case parsed of
src/Text/Pandoc/Readers/Metadata.hs+14−26
@@ -37,21 +37,19 @@ yamlBsToMeta :: PandocMonad m
37 -> BL.ByteString
37 -> BL.ByteString
38 -> ParserT Text ParserState m (F Meta)
38 -> ParserT Text ParserState m (F Meta)
39yamlBsToMeta pMetaValue bstr = do
39yamlBsToMeta pMetaValue bstr = do
40− pos <- getPosition
41 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
40 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
42 Right (YAML.Doc (YAML.Mapping _ _ o):_)
41 Right (YAML.Doc (YAML.Mapping _ _ o):_)
43 -> fmap Meta <$> yamlMap pMetaValue o
42 -> fmap Meta <$> yamlMap pMetaValue o
44 Right [] -> return . return $ mempty
43 Right [] -> return . return $ mempty
45 Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
44 Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
46 -> return . return $ mempty
45 -> return . return $ mempty
47− Right _ -> do logMessage $ CouldNotParseYamlMetadata "not an object"
46+ Right _ -> fail "expected YAML object"
48− pos
49− return . return $ mempty
50− Left (_pos, err')
47+ Left (yamlpos, err')
51− -> do logMessage $ CouldNotParseYamlMetadata
48+ -> do pos <- getPosition
52− (T.pack err') pos
49+ setPosition $ incSourceLine
53− return . return $ mempty
50+ (setSourceColumn pos (YE.posColumn yamlpos))
54−
51+ (YE.posLine yamlpos - 1)
52+ fail err'
55
53
56fakePos :: YAML.Pos
54fakePos :: YAML.Pos
57fakePos = YAML.Pos (-1) (-1) 1 0
55fakePos = YAML.Pos (-1) (-1) 1 0
@@ -71,8 +69,7 @@ yamlBsToRefs :: PandocMonad m
71 -> (Text -> Bool) -- ^ Filter for id
69 -> (Text -> Bool) -- ^ Filter for id
72 -> BL.ByteString
70 -> BL.ByteString
73 -> ParserT Text ParserState m (F [MetaValue])
71 -> ParserT Text ParserState m (F [MetaValue])
74−yamlBsToRefs pMetaValue idpred bstr = do
72+yamlBsToRefs pMetaValue idpred bstr =
75− pos <- getPosition
76 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
73 case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
77 Right (YAML.Doc o@(YAML.Mapping _ _ _):_)
74 Right (YAML.Doc o@(YAML.Mapping _ _ _):_)
78 -> case lookupYAML "references" o of
75 -> case lookupYAML "references" o of
@@ -90,26 +87,17 @@ yamlBsToRefs pMetaValue idpred bstr = do
90 Nothing -> False
87 Nothing -> False
91 sequence <$>
88 sequence <$>
92 mapM (yamlToMetaValue pMetaValue) (filter g ns)
89 mapM (yamlToMetaValue pMetaValue) (filter g ns)
93− Just _ -> do
90+ Just _ ->
94− logMessage $ CouldNotParseYamlMetadata
95− ("expecting sequence in 'references' field") pos
91+ fail "expecting sequence in 'references' field"
96− return . return $ mempty
97− Nothing -> do
92+ Nothing ->
98− logMessage $ CouldNotParseYamlMetadata
99− ("expecting 'references' field") pos
93+ fail "expecting 'references' field"
100− return . return $ mempty
101
94
102 Right [] -> return . return $ mempty
95 Right [] -> return . return $ mempty
103 Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
96 Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
104 -> return . return $ mempty
97 -> return . return $ mempty
105− Right _ -> do logMessage $ CouldNotParseYamlMetadata "not an object"
98+ Right _ -> fail "expecting YAML object"
106− pos
107− return . return $ mempty
108 Left (_pos, err')
99 Left (_pos, err')
109− -> do logMessage $ CouldNotParseYamlMetadata
100+ -> fail err'
110− (T.pack err') pos
111− return . return $ mempty
112−
113
101
114
102
115nodeToKey :: YAML.Node YE.Pos -> Maybe Text
103nodeToKey :: YAML.Node YE.Pos -> Maybe Text