states, code block compiling
This commit is contained in:
parent
533d450507
commit
d8c51ad788
1 changed files with 62 additions and 35 deletions
|
@ -41,7 +41,7 @@ import Data.Maybe (isJust, catMaybes)
|
|||
import Data.List (intersperse, intercalate)
|
||||
import qualified Data.Text as T
|
||||
|
||||
import Text.Pandoc.Class (PandocMonad(..), runPure, runIOorExplode)
|
||||
import Text.Pandoc.Class (PandocMonad(..), runIOorExplode)
|
||||
import Text.Pandoc.Definition
|
||||
import Text.Pandoc.Error (PandocError (PandocParsecError))
|
||||
import Text.Pandoc.Logging (LogMessage(..))
|
||||
|
@ -69,7 +69,7 @@ data ManToken = MStr String FontKind
|
|||
| MLine [(String, FontKind)]
|
||||
| MLink String Target
|
||||
| MEmptyLine
|
||||
| MHeader Integer String
|
||||
| MHeader Int String
|
||||
| MMacro MacroKind [String]
|
||||
| MUnknownMacro String [String]
|
||||
| MComment String
|
||||
|
@ -80,25 +80,18 @@ data EscapeThing = EFont FontKind
|
|||
| ENothing
|
||||
deriving Show
|
||||
|
||||
data RoffState = RoffState { inCodeBlock :: Bool
|
||||
, fontKind :: FontKind
|
||||
data RoffState = RoffState { fontKind :: FontKind
|
||||
} deriving Show
|
||||
|
||||
instance Default RoffState where
|
||||
def = RoffState {inCodeBlock = False, fontKind = Regular}
|
||||
def = RoffState {fontKind = Regular}
|
||||
|
||||
data ManState = ManState {pState :: ParserState, rState :: RoffState}
|
||||
|
||||
type ManParser m = ParserT [Char] ManState m
|
||||
type ManCompiler m = ParserT [ManToken] ManState m
|
||||
|
||||
instance HasLogMessages ManState where
|
||||
addLogMessage lm mst = mst {pState = addLogMessage lm (pState mst)}
|
||||
getLogMessages mst = getLogMessages $ pState mst
|
||||
type ManParser m = ParserT [Char] RoffState m
|
||||
type ManCompiler m = ParserT [ManToken] ParserState m
|
||||
|
||||
----
|
||||
testStrr :: [Char] -> Either PandocError Pandoc
|
||||
testStrr s = runPure $ readMan def (T.pack s)
|
||||
-- testStrr :: [Char] -> Either PandocError Pandoc
|
||||
-- testStrr s = runPure $ readMan def (T.pack s)
|
||||
|
||||
printPandoc :: Pandoc -> [Char]
|
||||
printPandoc (Pandoc m content) =
|
||||
|
@ -106,10 +99,10 @@ printPandoc (Pandoc m content) =
|
|||
cnt = intercalate "\n" $ map show content
|
||||
in ttl ++ "\n" ++ cnt
|
||||
|
||||
strrepr :: Either PandocError Pandoc -> [Char]
|
||||
strrepr obj = case obj of
|
||||
Right x -> printPandoc x
|
||||
Left y -> show y
|
||||
-- strrepr :: Either PandocError Pandoc -> [Char]
|
||||
-- strrepr obj = case obj of
|
||||
-- Right x -> printPandoc x
|
||||
-- Left y -> show y
|
||||
|
||||
testFile :: FilePath -> IO ()
|
||||
testFile fname = do
|
||||
|
@ -122,10 +115,10 @@ testFile fname = do
|
|||
-- | Read man (troff) from an input string and return a Pandoc document.
|
||||
readMan :: PandocMonad m => ReaderOptions -> T.Text -> m Pandoc
|
||||
readMan opts txt = do
|
||||
let state = ManState { pState = def{ stateOptions = opts }, rState = def}
|
||||
eithertokens <- readWithM parseMan state (T.unpack $ crFilter txt)
|
||||
eithertokens <- readWithM parseMan def (T.unpack $ crFilter txt)
|
||||
case eithertokens of
|
||||
Right tokenz -> do
|
||||
let state = def {stateOptions = opts} :: ParserState
|
||||
eitherdoc <- readWithMTokens compileMan state tokenz
|
||||
case eitherdoc of
|
||||
Right doc -> return doc
|
||||
|
@ -135,8 +128,8 @@ readMan opts txt = do
|
|||
where
|
||||
|
||||
readWithMTokens :: PandocMonad m
|
||||
=> ParserT [ManToken] ManState m a -- ^ parser
|
||||
-> ManState -- ^ initial state
|
||||
=> ParserT [ManToken] ParserState m a -- ^ parser
|
||||
-> ParserState -- ^ initial state
|
||||
-> [ManToken] -- ^ input
|
||||
-> m (Either PandocError a)
|
||||
readWithMTokens parser state input =
|
||||
|
@ -155,15 +148,16 @@ parseMan = many (parseMacro <|> parseLine <|> parseEmptyLine)
|
|||
|
||||
compileMan :: PandocMonad m => ManCompiler m Pandoc
|
||||
compileMan = do
|
||||
let compilers = [compileTitle, compilePara, compileSkippedContent]
|
||||
let compilers = [compileTitle, compilePara, compileSkippedContent
|
||||
, compileCodeBlock, compileHeader, compileSkipMacro]
|
||||
blocks <- many $ choice compilers
|
||||
parserst <- pState <$> getState
|
||||
return $ Pandoc (stateMeta parserst) blocks
|
||||
parserst <- getState
|
||||
return $ Pandoc (stateMeta parserst) (filter (not . isNull) blocks)
|
||||
|
||||
modifyRoffState :: PandocMonad m => (RoffState -> RoffState) -> ParsecT a ManState m ()
|
||||
modifyRoffState f = do
|
||||
mst <- getState
|
||||
setState mst { rState = f $ rState mst }
|
||||
where
|
||||
|
||||
isNull Null = True
|
||||
isNull _ = False
|
||||
|
||||
parseMacro :: PandocMonad m => ManParser m ManToken
|
||||
parseMacro = do
|
||||
|
@ -253,7 +247,7 @@ escapeParser = do
|
|||
, string "[]" >> return Regular
|
||||
, char '[' >> many1 letter >> char ']' >> return Regular
|
||||
]
|
||||
modifyRoffState (\r -> r {fontKind = font})
|
||||
modifyState (\r -> r {fontKind = font})
|
||||
return $ EFont font
|
||||
|
||||
parseLine :: PandocMonad m => ManParser m ManToken
|
||||
|
@ -280,7 +274,7 @@ parseLine = do
|
|||
|
||||
currentFont :: PandocMonad m => ManParser m FontKind
|
||||
currentFont = do
|
||||
RoffState {fontKind = fk} <- rState <$> getState
|
||||
RoffState {fontKind = fk} <- getState
|
||||
return fk
|
||||
|
||||
|
||||
|
@ -328,6 +322,11 @@ mmacro mk = msatisfy isMMacro where
|
|||
| otherwise = False
|
||||
isMMacro _ = False
|
||||
|
||||
mmacroAny :: PandocMonad m => ManCompiler m ManToken
|
||||
mmacroAny = msatisfy isMMacro where
|
||||
isMMacro (MMacro _ _) = True
|
||||
isMMacro _ = False
|
||||
|
||||
munknownMacro :: PandocMonad m => ManCompiler m ManToken
|
||||
munknownMacro = msatisfy isMUnknownMacro where
|
||||
isMUnknownMacro (MUnknownMacro _ _) = True
|
||||
|
@ -352,11 +351,11 @@ compileTitle = do
|
|||
modifyState (changeTitle mantitle)
|
||||
return $ Header 1 nullAttr [Str mantitle]
|
||||
where
|
||||
changeTitle title mst@ManState{ pState = pst} =
|
||||
changeTitle title pst =
|
||||
let meta = stateMeta pst
|
||||
metaUp = Meta $ insert "title" (MetaString title) (unMeta meta)
|
||||
in
|
||||
mst { pState = pst {stateMeta = metaUp} }
|
||||
pst {stateMeta = metaUp}
|
||||
|
||||
compileSkippedContent :: PandocMonad m => ManCompiler m Block
|
||||
compileSkippedContent = do
|
||||
|
@ -380,7 +379,7 @@ strToInline s ItalicBold = Strong [Emph [Str s]]
|
|||
|
||||
compilePara :: PandocMonad m => ManCompiler m Block
|
||||
compilePara = do
|
||||
inls <- many1 (strInl <|> lineInl)
|
||||
inls <- many1 (strInl <|> lineInl <|> comment)
|
||||
let withspaces = intersperse [Str " "] inls
|
||||
return $ Para (concat withspaces)
|
||||
|
||||
|
@ -395,3 +394,31 @@ compilePara = do
|
|||
lineInl = do
|
||||
(MLine fragments) <- mline
|
||||
return $ fmap (\(s,f) -> strToInline s f) fragments
|
||||
|
||||
comment :: PandocMonad m => ManCompiler m [Inline]
|
||||
comment = mcomment >> return []
|
||||
|
||||
|
||||
compileCodeBlock :: PandocMonad m => ManCompiler m Block
|
||||
compileCodeBlock = do
|
||||
mmacro KCodeBlStart
|
||||
toks <- many (mstr <|> mline <|> mlink <|> memplyLine <|> munknownMacro <|> mcomment)
|
||||
mmacro KCodeBlEnd
|
||||
return $ CodeBlock nullAttr (intercalate "\n" . catMaybes $ extractText <$> toks)
|
||||
|
||||
where
|
||||
|
||||
extractText :: ManToken -> Maybe String
|
||||
extractText (MStr s _) = Just s
|
||||
extractText (MLine ss) = Just . intercalate " " $ map fst ss
|
||||
extractText (MLink s _) = Just s
|
||||
extractText MEmptyLine = Just "" -- string are intercalated with '\n', this prevents double '\n'
|
||||
extractText _ = Nothing
|
||||
|
||||
compileHeader :: PandocMonad m => ManCompiler m Block
|
||||
compileHeader = do
|
||||
(MHeader lvl s) <- mheader
|
||||
return $ Header lvl nullAttr [Str s]
|
||||
|
||||
compileSkipMacro :: PandocMonad m => ManCompiler m Block
|
||||
compileSkipMacro = mmacroAny >> return Null
|
||||
|
|
Loading…
Add table
Reference in a new issue