ehaskell-0.7: GetCodeText.hs
module GetCodeText (
getCodeText
, CodeText(..)
) where
import Text.ParserCombinators.MTLParse
import Control.Monad.Tools
import Types
type SymCodePair = ( (String, String), CodeText )
symCodePairs :: [ SymCodePair ]
symCodePairs = [
( ("" , "" ), Code )
, ( ("%" , "%"), CodeTop )
, ( ("" , "-"), CodeBegin )
, ( ("-" , "-"), CodeCont )
, ( ("-" , "" ), CodeEnd )
, ( ("=" , "" ), CodeEq )
, ( ("==" , "" ), CodeEqEq )
, ( ("=$" , "" ), CodeEqShow )
, ( ("==$", "" ), CodeEqEqShow )
]
getCodeText :: String -> [ (CodeText, String) ]
getCodeText = fst . myHead . runParse parseCodeText . (,) ""
where
myHead (h:_) = h
myHead _ = error "parseCodeText in module GetCodeText: parse error"
parseCodeText :: Parse Char [ (CodeText, String) ]
parseCodeText
= ( fmap concat $ list $ parseText >:> (fmap (:[]) parseCode) ) >++>
(fmap (:[]) parseText) >>= endOfInput
parseText :: Parse Char (CodeText, String)
parseText = do
txt <- list $ do
still (parseNot () $ tokens "<%")
spot $ const True
return (Text, txt)
parseCode :: Parse Char (CodeText, String)
parseCode =
(tokens "<%" >> msum (map parseCodeGen symCodePairs) >>= skipRet (tokens "%>"))
`mplus` (tokens "<%-%>" >> return (CodeEnd, ""))
`mplus` (tokens "<%--%>" >> return (CodeCont, ""))
parseCodeGen :: SymCodePair -> Parse Char (CodeText, String)
parseCodeGen ((b, e), c) = do
tokens b
still $ spot $ flip notElem "%-=$"
code <- fmap concat $ list $
do { still (parseNot () $ tokens "%>");
fmap (:[]) $ spot $ flip notElem "()\""; }
`mplus` parseDQ `mplus` parseParen
still $ spotBack (/='-')
tokens e
return (c, code)
parseDQ :: Parse Char String
parseDQ = do
token '"'
ret <- fmap concat $ list $ (fmap (:[]) $ spot $ flip notElem "\\\"") `mplus`
(token '\\' >:> (fmap (:[]) $ spot $ const True))
token '"'
return $ '"' : ret ++ "\""
parseParen :: Parse Char String
parseParen = do
token '('
ret <- fmap concat $ list $ ( fmap (:[]) $ spot $ flip notElem "()" )
`mplus` parseParen
token ')'
return $ '(' : ret ++ ")"