@@ -26,13 +26,43 @@ import Text.Pandoc.Definition
2626import Text.Pandoc.Builder as B
2727import Text.Pandoc.Options
2828import Text.Pandoc.Error
29+import Text.Pandoc.Readers.Metadata (yamlMetaBlock)
2930import Control.Monad.Except
3031import Data.Functor.Identity (runIdentity)
3132import Data.Typeable
33+import Text.Pandoc.Parsing (runParserT, getPosition, sourceLine,
34+ runF, defaultParserState, take1WhileP, option)
35+import qualified Data.Text as T
3236
3337-- | Parse a CommonMark formatted string into a 'Pandoc' structure.
3438readCommonMark :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
3539readCommonMark opts s
40+ | isEnabled Ext_yaml_metadata_block opts
41+ , "---" `T.isPrefixOf` s = do
42+ let metaValueParser = do
43+ inp <- option "" $ take1WhileP (const True)
44+ case runIdentity
45+ (commonmarkWith (specFor opts) "metadata value" inp) of
46+ Left _ -> mzero
47+ Right (Cm bls :: Cm () Blocks)
48+ -> return $ return $ B.toMetaValue bls
49+ res <- runParserT (do meta <- yamlMetaBlock metaValueParser
50+ pos <- getPosition
51+ return (meta, pos))
52+ defaultParserState "YAML metadata" s
53+ case res of
54+ Left _ -> readCommonMarkBody opts s
55+ Right (meta, pos) -> do
56+ let dropLines 0 = id
57+ dropLines n = dropLines (n - 1) . T.drop 1 . T.dropWhile (/='\n')
58+ let metaLines = sourceLine pos - 1
59+ let body = T.replicate metaLines "\n" <> dropLines metaLines s
60+ Pandoc _ bs <- readCommonMarkBody opts body
61+ return $ Pandoc (runF meta defaultParserState) bs
62+ | otherwise = readCommonMarkBody opts s
63+
64+readCommonMarkBody :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
65+readCommonMarkBody opts s
3666 | isEnabled Ext_sourcepos opts =
3767 case runIdentity (commonmarkWith (specFor opts) "" s) of
3868 Left err -> throwError $ PandocParsecError s err