diff options
Diffstat (limited to 'src/Text/Pandoc/Readers/RST.hs')
-rw-r--r-- | src/Text/Pandoc/Readers/RST.hs | 73 |
1 files changed, 33 insertions, 40 deletions
diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs index 4e0c0a277..0829996a7 100644 --- a/src/Text/Pandoc/Readers/RST.hs +++ b/src/Text/Pandoc/Readers/RST.hs @@ -31,6 +31,7 @@ module Text.Pandoc.Readers.RST ( readRST ) where import Text.Pandoc.Definition +import Text.Pandoc.Builder (setMeta, fromList) import Text.Pandoc.Shared import Text.Pandoc.Parsing import Text.Pandoc.Options @@ -39,7 +40,6 @@ import Data.List ( findIndex, intersperse, intercalate, transpose, sort, deleteFirstsBy, isSuffixOf ) import qualified Data.Map as M import Text.Printf ( printf ) -import Data.Maybe ( catMaybes ) import Control.Applicative ((<$>), (<$), (<*), (*>)) import Text.Pandoc.Builder (Inlines, Blocks, trimInlines, (<>)) import qualified Text.Pandoc.Builder as B @@ -87,16 +87,30 @@ promoteHeaders _ [] = [] -- | If list of blocks starts with a header (or a header and subheader) -- of level that are not found elsewhere, return it as a title and --- promote all the other headers. -titleTransform :: [Block] -- ^ list of blocks - -> ([Block], [Inline]) -- ^ modified list of blocks, title -titleTransform ((Header 1 _ head1):(Header 2 _ head2):rest) | - not (any (isHeader 1) rest || any (isHeader 2) rest) = -- both title & subtitle - (promoteHeaders 2 rest, head1 ++ [Str ":", Space] ++ head2) -titleTransform ((Header 1 _ head1):rest) | - not (any (isHeader 1) rest) = -- title, no subtitle - (promoteHeaders 1 rest, head1) -titleTransform blocks = (blocks, []) +-- promote all the other headers. Also process a definition list right +-- after the title block as metadata. +titleTransform :: ([Block], Meta) -- ^ list of blocks, metadata + -> ([Block], Meta) -- ^ modified list of blocks, metadata +titleTransform (bs, meta) = + let (bs', meta') = + case bs of + ((Header 1 _ head1):(Header 2 _ head2):rest) + | not (any (isHeader 1) rest || any (isHeader 2) rest) -> -- tit/sub + (promoteHeaders 2 rest, setMeta "title" (fromList head1) $ + setMeta "subtitle" (fromList head2) meta) + ((Header 1 _ head1):rest) + | not (any (isHeader 1) rest) -> -- title only + (promoteHeaders 1 rest, + setMeta "title" (fromList head1) meta) + _ -> (bs, meta) + in case bs' of + (DefinitionList ds : rest) -> + (rest, metaFromDefList ds meta') + _ -> (bs', meta') + +metaFromDefList :: [([Inline], [[Block]])] -> Meta -> Meta +metaFromDefList ds meta = foldr f meta ds + where f (k,v) = setMeta (map toLower $ stringify k) (mconcat $ map fromList v) parseRST :: RSTParser Pandoc parseRST = do @@ -114,14 +128,12 @@ parseRST = do -- now parse it for real... blocks <- B.toList <$> parseBlocks standalone <- getOption readerStandalone - let (blocks', title) = if standalone - then titleTransform blocks - else (blocks, []) state <- getState - let authors = stateAuthors state - let date = stateDate state - let title' = if null title then stateTitle state else title - return $ Pandoc (Meta title' authors date) blocks' + let meta = stateMeta state + let (blocks', meta') = if standalone + then titleTransform (blocks, meta) + else (blocks, meta) + return $ Pandoc meta' blocks' -- -- parsing blocks @@ -163,38 +175,19 @@ rawFieldListItem indent = try $ do return (name, raw) fieldListItem :: String - -> RSTParser (Maybe (Inlines, [Blocks])) + -> RSTParser (Inlines, [Blocks]) fieldListItem indent = try $ do (name, raw) <- rawFieldListItem indent let term = B.str name contents <- parseFromString parseBlocks raw optional blanklines - case (name, B.toList contents) of - ("Author", x) -> do - updateState $ \st -> - st{ stateAuthors = stateAuthors st ++ [extractContents x] } - return Nothing - ("Authors", [BulletList auths]) -> do - updateState $ \st -> st{ stateAuthors = map extractContents auths } - return Nothing - ("Date", x) -> do - updateState $ \st -> st{ stateDate = extractContents x } - return Nothing - ("Title", x) -> do - updateState $ \st -> st{ stateTitle = extractContents x } - return Nothing - _ -> return $ Just (term, [contents]) - -extractContents :: [Block] -> [Inline] -extractContents [Plain auth] = auth -extractContents [Para auth] = auth -extractContents _ = [] + return (term, [contents]) fieldList :: RSTParser Blocks fieldList = try $ do indent <- lookAhead $ many spaceChar items <- many1 $ fieldListItem indent - case catMaybes items of + case items of [] -> return mempty items' -> return $ B.definitionList items' |