diff options
author | John MacFarlane <jgm@berkeley.edu> | 2021-03-20 15:45:09 -0700 |
---|---|---|
committer | John MacFarlane <jgm@berkeley.edu> | 2021-03-20 15:58:33 -0700 |
commit | c389211e2f678d9327cd2c008d54a1e438f07a07 (patch) | |
tree | 023502cee323fb5ca5793212396124b68cb07648 /src/Text/Pandoc/Readers | |
parent | 2274eb88a4dddf622d86bee94bb6f20db6e148b2 (diff) | |
download | pandoc-c389211e2f678d9327cd2c008d54a1e438f07a07.tar.gz |
Support `yaml_metadata_block` extension form commonmark, gfm.
This is a bit more limited than with markdown, as documented
in the manual:
- The YAML block must be the first thing in the input.
- The leaf notes are parsed in isolation from the rest of
the document. So, for example, you can't use reference
links if the references are defined later in the document.
Closes #6537.
Diffstat (limited to 'src/Text/Pandoc/Readers')
-rw-r--r-- | src/Text/Pandoc/Readers/CommonMark.hs | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/Text/Pandoc/Readers/CommonMark.hs b/src/Text/Pandoc/Readers/CommonMark.hs index 150a837e4..244f77940 100644 --- a/src/Text/Pandoc/Readers/CommonMark.hs +++ b/src/Text/Pandoc/Readers/CommonMark.hs @@ -26,13 +26,43 @@ import Text.Pandoc.Definition import Text.Pandoc.Builder as B import Text.Pandoc.Options import Text.Pandoc.Error +import Text.Pandoc.Readers.Metadata (yamlMetaBlock) import Control.Monad.Except import Data.Functor.Identity (runIdentity) import Data.Typeable +import Text.Pandoc.Parsing (runParserT, getPosition, sourceLine, + runF, defaultParserState, take1WhileP, option) +import qualified Data.Text as T -- | Parse a CommonMark formatted string into a 'Pandoc' structure. readCommonMark :: PandocMonad m => ReaderOptions -> Text -> m Pandoc readCommonMark opts s + | isEnabled Ext_yaml_metadata_block opts + , "---" `T.isPrefixOf` s = do + let metaValueParser = do + inp <- option "" $ take1WhileP (const True) + case runIdentity + (commonmarkWith (specFor opts) "metadata value" inp) of + Left _ -> mzero + Right (Cm bls :: Cm () Blocks) + -> return $ return $ B.toMetaValue bls + res <- runParserT (do meta <- yamlMetaBlock metaValueParser + pos <- getPosition + return (meta, pos)) + defaultParserState "YAML metadata" s + case res of + Left _ -> readCommonMarkBody opts s + Right (meta, pos) -> do + let dropLines 0 = id + dropLines n = dropLines (n - 1) . T.drop 1 . T.dropWhile (/='\n') + let metaLines = sourceLine pos - 1 + let body = T.replicate metaLines "\n" <> dropLines metaLines s + Pandoc _ bs <- readCommonMarkBody opts body + return $ Pandoc (runF meta defaultParserState) bs + | otherwise = readCommonMarkBody opts s + +readCommonMarkBody :: PandocMonad m => ReaderOptions -> Text -> m Pandoc +readCommonMarkBody opts s | isEnabled Ext_sourcepos opts = case runIdentity (commonmarkWith (specFor opts) "" s) of Left err -> throwError $ PandocParsecError s err |