diff options
Diffstat (limited to 'src/Text')
-rw-r--r-- | src/Text/Pandoc/Readers/Man.hs | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/src/Text/Pandoc/Readers/Man.hs b/src/Text/Pandoc/Readers/Man.hs index 6a89f25d9..22e6116fd 100644 --- a/src/Text/Pandoc/Readers/Man.hs +++ b/src/Text/Pandoc/Readers/Man.hs @@ -77,14 +77,24 @@ data ManToken = MStr RoffStr | MEndMacro deriving Show -data RoffState = RoffState { fontKind :: Font +data RoffState = RoffState { fontKind :: Font } deriving Show instance Default RoffState where - def = RoffState {fontKind = singleton Regular} + def = RoffState { fontKind = singleton Regular } + +data ManState = ManState { customMacros :: M.Map String Blocks + , readerOptions :: ReaderOptions + , metadata :: Meta + } deriving Show + +instance Default ManState where + def = ManState { customMacros = mempty + , readerOptions = def + , metadata = nullMeta } type ManLexer m = ParserT [Char] RoffState m -type ManParser m = ParserT [ManToken] ParserState m +type ManParser m = ParserT [ManToken] ManState m -- | Read man (troff) from an input string and return a Pandoc document. @@ -94,15 +104,15 @@ readMan opts txt = do case eithertokens of Left e -> throwError e Right tokenz -> do - let state = def {stateOptions = opts} :: ParserState + let state = def {readerOptions = opts} :: ManState eitherdoc <- readWithMTokens parseMan state tokenz either throwError return eitherdoc where readWithMTokens :: PandocMonad m - => ParserT [ManToken] ParserState m a -- ^ parser - -> ParserState -- ^ initial state + => ParserT [ManToken] ManState m a -- ^ parser + -> ManState -- ^ initial state -> [ManToken] -- ^ input -> m (Either PandocError a) readWithMTokens parser state input = @@ -123,7 +133,7 @@ lexMan = many (lexComment <|> lexMacro <|> lexLine <|> lexEmptyLine) parseMan :: PandocMonad m => ManParser m Pandoc parseMan = do bs <- many parseBlock <* eof - meta <- stateMeta <$> getState + meta <- metadata <$> getState let (Pandoc _ blocks) = doc $ mconcat bs return $ Pandoc meta blocks @@ -137,7 +147,7 @@ parseBlock = choice [ parseList , parseCodeBlock , parseHeader , parseMacroDef - , parseSkipMacro + , parseUnkownMacro ] eofline :: Stream s m Char => ParsecT s u m () @@ -410,7 +420,7 @@ parseTitle = do [x,y] -> setMeta "title" x . setMeta "section" y [x] -> setMeta "title" x [] -> id - modifyState $ \st -> st{ stateMeta = adjustMeta $ stateMeta st } + modifyState $ \st -> st{ metadata = adjustMeta $ metadata st } return mempty parseSkippedContent :: PandocMonad m => ManParser m Blocks @@ -570,9 +580,16 @@ parseDefinitionList = definitionList <$> many1 definitionListItem parseMacroDef :: PandocMonad m => ManParser m Blocks parseMacroDef = do - MMacro _ _args <- mmacro "de" - bs <- manyTill parseBlock endMacro - return mempty -- TODO for now just skip it + MMacro _ args <- mmacro "de" + (macroName, endMacro') <- + case args of + ((x,_):(y,_):_) -> return (x, mmacro y) -- optional second arg + ((x,_):_) -> return (x, endMacro) + [] -> fail "No argument to .de" + bs <- mconcat <$> manyTill parseBlock endMacro' + modifyState $ \st -> + st{ customMacros = M.insert macroName bs (customMacros st) } + return mempty where endMacro = (msatisfy (\t -> case t of @@ -580,11 +597,16 @@ parseMacroDef = do _ -> False)) -- In case of weird man file it will be parsed succesfully -parseSkipMacro :: PandocMonad m => ManParser m Blocks -parseSkipMacro = do +parseUnkownMacro :: PandocMonad m => ManParser m Blocks +parseUnkownMacro = do pos <- getPosition tok <- mmacroAny case tok of - MMacro mkind _ -> report $ SkippedContent ('.':mkind) pos - _ -> return () -- shouldn't happen - return mempty + MMacro mkind _ -> do + macros <- customMacros <$> getState + case M.lookup mkind macros of + Nothing -> do + report $ SkippedContent ('.':mkind) pos + return mempty + Just bs -> return bs + _ -> fail "the impossible happened" |