diff options
| author | John MacFarlane <jgm@berkeley.edu> | 2023-12-10 12:56:59 -0800 |
|---|---|---|
| committer | John MacFarlane <jgm@berkeley.edu> | 2023-12-10 12:56:59 -0800 |
| commit | 42091d1e13f2c17f477396278b78d3addcf01837 (patch) | |
| tree | 850b24064ef6e59bf44c58fc8c3b0512d357d208 /src | |
| parent | b0e8e99c831c54e1f46d3f5c78ebcc547279e15d (diff) | |
Typst reader: parse metadata from document element.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Text/Pandoc/Readers/Typst.hs | 41 | ||||
| -rw-r--r-- | src/Text/Pandoc/Readers/Typst/Parsing.hs | 17 |
2 files changed, 41 insertions, 17 deletions
diff --git a/src/Text/Pandoc/Readers/Typst.hs b/src/Text/Pandoc/Readers/Typst.hs index 515e33aa6..3b9d5b7cb 100644 --- a/src/Text/Pandoc/Readers/Typst.hs +++ b/src/Text/Pandoc/Readers/Typst.hs @@ -72,10 +72,10 @@ readTypst _opts inp = do res <- evaluateTypst ops inputName parsed case res of Left e -> throwError $ PandocParseError $ tshow e - Right cs -> do - let labs = findLabels cs + Right content -> do + let labs = findLabels [content] runParserT pPandoc defaultPState{ sLabels = labs } - inputName (F.toList cs) >>= + inputName [content] >>= either (throwError . PandocParseError . T.pack . show) pure pBlockElt :: PandocMonad m => P m B.Blocks @@ -128,7 +128,36 @@ pInline = try $ do Just handler -> handler Nothing fields pPandoc :: PandocMonad m => P m B.Pandoc -pPandoc = B.doc <$> pBlocks +pPandoc = do + Elt "document" _ fields <- pTok isDocument + bs <- getField "body" fields >>= pWithContents pBlocks + title <- (getField "title" fields >>= pWithContents pInlines) <|> + pure mempty + authors <- (getField "author" fields >>= + mapM (pWithContents pInlines) . V.toList) <|> + ((:[]) <$> (getField "author" fields >>= + (\x -> guard (not (null x)) *> + pWithContents pInlines x))) <|> + pure [] + date <- (getField "date" fields >>= pWithContents pInlines) <|> + pure mempty + keywords <- (getField "keywords" fields >>= + mapM (pWithContents pInlines) . V.toList) + <|> pure [] + pure $ + (if title == mempty + then id + else B.setMeta "title" title) . + (if null authors + then id + else B.setMeta "author" authors) . + (if null date + then id + else B.setMeta "date" date) . + (if null keywords + then id + else B.setMeta "keywords" keywords) $ + B.doc bs pBlocks :: PandocMonad m => P m B.Blocks pBlocks = mconcat <$> many pBlock @@ -152,6 +181,10 @@ pLab = try $ do ) pure t +isDocument :: Content -> Bool +isDocument (Elt "document" _ _) = True +isDocument _ = False + isBlock :: Content -> Bool isBlock (Elt "raw" _ fields) = M.lookup "block" fields == Just (VBoolean True) isBlock (Elt name _ _) = name `Set.member` blockKeys diff --git a/src/Text/Pandoc/Readers/Typst/Parsing.hs b/src/Text/Pandoc/Readers/Typst/Parsing.hs index 61279e178..b7b725c6f 100644 --- a/src/Text/Pandoc/Readers/Typst/Parsing.hs +++ b/src/Text/Pandoc/Readers/Typst/Parsing.hs @@ -14,7 +14,6 @@ module Text.Pandoc.Readers.Typst.Parsing chunks, ) where -import qualified Text.Pandoc.Builder as B import Control.Monad (MonadPlus) import Control.Monad.Reader (lift) import qualified Data.Foldable as F @@ -29,22 +28,14 @@ import Typst.Types import Text.Pandoc.Class.PandocMonad ( PandocMonad, report ) import Text.Pandoc.Logging (LogMessage(..)) -data PState = PState - { sLabels :: [Text] - , sTitle :: B.Inlines - , sAuthors :: [B.Inlines] - , sDate :: B.Inlines - , sKeywords :: [Text] } - deriving (Show) +newtype PState = PState + { sLabels :: [Text]} + deriving (Show) defaultPState :: PState defaultPState = PState - { sLabels = [] - , sTitle = mempty - , sAuthors = [] - , sDate = mempty - , sKeywords = [] } + { sLabels = [] } type P m a = ParsecT [Content] PState m a -- state tracks a list of labels in the document |
