diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Text/Pandoc/Citeproc.hs | 12 | ||||
| -rw-r--r-- | src/Text/Pandoc/Readers/Markdown.hs | 27 | ||||
| -rw-r--r-- | src/Text/Pandoc/Readers/Metadata.hs | 45 | 
3 files changed, 74 insertions, 10 deletions
| diff --git a/src/Text/Pandoc/Citeproc.hs b/src/Text/Pandoc/Citeproc.hs index 8274e35d7..4f92cf8ca 100644 --- a/src/Text/Pandoc/Citeproc.hs +++ b/src/Text/Pandoc/Citeproc.hs @@ -18,7 +18,7 @@ import Text.Pandoc.Citeproc.Locator (parseLocator)  import Text.Pandoc.Citeproc.CslJson (cslJsonToReferences)  import Text.Pandoc.Citeproc.BibTeX (readBibtexString, Variant(..))  import Text.Pandoc.Citeproc.MetaValue (metaValueToReference, metaValueToText) -import Text.Pandoc.Readers.Markdown (yamlToMeta) +import Text.Pandoc.Readers.Markdown (yamlToRefs)  import Text.Pandoc.Class (setResourcePath, getResourcePath, getUserDataDir)  import Data.ByteString (ByteString)  import qualified Data.ByteString.Lazy as L @@ -213,12 +213,10 @@ getRefs locale format idpred raw =               (return . filter (idpred . unItemId . referenceId)) .          cslJsonToReferences $ raw      Format_yaml -> do -      meta <- yamlToMeta def{ readerExtensions = pandocExtensions } -                          (L.fromStrict raw) -      case lookupMeta "references" meta of -          Just (MetaList rs) -> -               return $ mapMaybe (metaValueToReference idpred) rs -          _ -> throwError $ PandocAppError "No references field" +      rs <- yamlToRefs idpred +              def{ readerExtensions = pandocExtensions } +              (L.fromStrict raw) +      return $ mapMaybe (metaValueToReference idpred . MetaMap) rs  -- localized quotes  convertQuotes :: Locale -> Inline -> Inline diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs index 257788081..65925ee95 100644 --- a/src/Text/Pandoc/Readers/Markdown.hs +++ b/src/Text/Pandoc/Readers/Markdown.hs @@ -13,7 +13,10 @@  Conversion of markdown-formatted plain text to 'Pandoc' document.  -} -module Text.Pandoc.Readers.Markdown ( readMarkdown, yamlToMeta ) where +module Text.Pandoc.Readers.Markdown ( +  readMarkdown, +  yamlToMeta, +  yamlToRefs ) where  import Control.Monad  import Control.Monad.Except (throwError) @@ -44,7 +47,7 @@ import Text.Pandoc.Readers.LaTeX (applyMacros, rawLaTeXBlock, rawLaTeXInline)  import Text.Pandoc.Shared  import qualified Text.Pandoc.UTF8 as UTF8  import Text.Pandoc.XML (fromEntities) -import Text.Pandoc.Readers.Metadata (yamlBsToMeta) +import Text.Pandoc.Readers.Metadata (yamlBsToMeta, yamlBsToRefs)  type MarkdownParser m = ParserT Text ParserState m @@ -75,6 +78,26 @@ yamlToMeta opts bstr = do      Right result -> return result      Left e       -> throwError e +-- | Read a YAML string and extract references from the +-- 'references' field, filter using an id predicate and +-- parsing fields as Markdown. +yamlToRefs :: PandocMonad m +           => (Text -> Bool) +           -> ReaderOptions +           -> BL.ByteString +           -> m [M.Map Text MetaValue] +yamlToRefs idpred opts bstr = do +  let parser = do +        refs <- yamlBsToRefs (fmap B.toMetaValue <$> parseBlocks) idpred bstr +        return $ runF refs defaultParserState +  parsed <- readWithM parser def{ stateOptions = opts } "" +  case parsed of +    Right result -> return result +    Left e       -> throwError e + + + +  --  -- Constants and data structure definitions  -- diff --git a/src/Text/Pandoc/Readers/Metadata.hs b/src/Text/Pandoc/Readers/Metadata.hs index 826111756..b802c752b 100644 --- a/src/Text/Pandoc/Readers/Metadata.hs +++ b/src/Text/Pandoc/Readers/Metadata.hs @@ -1,4 +1,5 @@  {-# LANGUAGE OverloadedStrings   #-} +{-# LANGUAGE ScopedTypeVariables #-}  {- |     Module      : Text.Pandoc.Readers.Metadata     Copyright   : Copyright (C) 2006-2020 John MacFarlane @@ -10,7 +11,10 @@  Parse YAML/JSON metadata to 'Pandoc' 'Meta'.  -} -module Text.Pandoc.Readers.Metadata ( yamlBsToMeta, yamlMap ) where +module Text.Pandoc.Readers.Metadata ( +  yamlBsToMeta, +  yamlBsToRefs, +  yamlMap ) where  import Control.Monad  import Control.Monad.Except (throwError) @@ -47,6 +51,45 @@ yamlBsToMeta pMetaValue bstr = do                                     (T.pack err') pos                        return . return $ mempty +-- Returns filtered list of references. +yamlBsToRefs :: PandocMonad m +             => ParserT Text ParserState m (F MetaValue) +             -> (Text -> Bool) -- ^ Filter for id +             -> BL.ByteString +             -> ParserT Text ParserState m (F [M.Map Text MetaValue]) +yamlBsToRefs pMetaValue idpred bstr = do +  pos <- getPosition +  case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of +       Right (YAML.Doc (YAML.Mapping _ _ o):_) +                -> case YAML.parseEither (o YAML..: "references") of +                     Right ns -> do +                       let g n = case YAML.parseEither (n YAML..: "id") of +                                    Right t -> idpred t || +                                      case YAML.parseEither (n YAML..: +                                             "other-ids") of +                                            Right (oids :: [Text]) -> +                                              any idpred oids +                                            _ -> False +                                    _       -> False +                       sequence <$> mapM (yamlMap pMetaValue) (filter g ns) +                     Left _ -> do +                       logMessage $ CouldNotParseYamlMetadata +                                      ("expecting 'references' field") pos +                       return . return $ mempty + +       Right [] -> return . return $ mempty +       Right [YAML.Doc (YAML.Scalar _ YAML.SNull)] +                -> return . return $ mempty +       Right _  -> do logMessage $ CouldNotParseYamlMetadata "not an object" +                                   pos +                      return . return $ mempty +       Left (_pos, err') +                -> do logMessage $ CouldNotParseYamlMetadata +                                   (T.pack err') pos +                      return . return $ mempty + + +  nodeToKey :: PandocMonad m            => YAML.Node YE.Pos            -> m Text | 
