module Text.Highlighting.Kate.Syntax.Markdown
(highlight, parseExpression, syntaxName, syntaxExtensions)
where
import Text.Highlighting.Kate.Types
import Text.Highlighting.Kate.Common
import Text.ParserCombinators.Parsec hiding (State)
import Control.Monad.State
import Data.Char (isSpace)
syntaxName :: String
syntaxName = "Markdown"
syntaxExtensions :: String
syntaxExtensions = "*.md;*.mmd;*.markdown"
highlight :: String -> [SourceLine]
highlight input = evalState (mapM parseSourceLine $ lines input) startingState
parseSourceLine :: String -> State SyntaxState SourceLine
parseSourceLine = mkParseSourceLine (parseExpression Nothing)
parseExpression :: Maybe (String,String)
-> KateParser Token
parseExpression mbcontext = do
(lang,cont) <- maybe currentContext return mbcontext
result <- parseRules (lang,cont)
optional $ do eof
updateState $ \st -> st{ synStPrevChar = '\n' }
pEndLine
return result
startingState = SyntaxState {synStContexts = [("Markdown","Normal Text")], synStLineNumber = 0, synStPrevChar = '\n', synStPrevNonspace = False, synStCaseSensitive = True, synStKeywordCaseSensitive = True, synStCaptures = []}
pEndLine = do
updateState $ \st -> st{ synStPrevNonspace = False }
context <- currentContext
contexts <- synStContexts `fmap` getState
if length contexts >= 2
then case context of
("Markdown","Normal Text") -> return ()
("Markdown","blockquote") -> (popContext) >> pEndLine
("Markdown","bullet") -> (popContext) >> pEndLine
("Markdown","numlist") -> (popContext) >> pEndLine
("Markdown","comment") -> return ()
("Markdown","inc") -> return ()
_ -> return ()
else return ()
withAttribute attr txt = do
when (null txt) $ fail "Parser matched no text"
updateState $ \st -> st { synStPrevChar = last txt
, synStPrevNonspace = synStPrevNonspace st || not (all isSpace txt) }
return (attr, txt)
regex_'23'5cs'2e'2a'5b'23'5d'3f'24 = compileRegex "#\\s.*[#]?$"
regex_'23'23'5cs'2e'2a'5b'23'5d'3f'24 = compileRegex "##\\s.*[#]?$"
regex_'23'23'23'5cs'2e'2a'5b'23'5d'3f'24 = compileRegex "###\\s.*[#]?$"
regex_'23'23'23'23'5cs'2e'2a'5b'23'5d'3f'24 = compileRegex "####\\s.*[#]?$"
regex_'23'23'23'23'23'5cs'2e'2a'5b'23'5d'3f'24 = compileRegex "#####\\s.*[#]?$"
regex_'23'23'23'23'23'23'5cs'2e'2a'5b'23'5d'3f'24 = compileRegex "######\\s.*[#]?$"
regex_'5cs'2a'28'5b'5c'2a'5c'2d'5f'5d'5cs'3f'29'7b3'2c'7d'5cs'2a = compileRegex "\\s*([\\*\\-_]\\s?){3,}\\s*"
regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b2'7d'5b'5e'5cs'5d'7b1'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b2'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 = compileRegex "(\\s|^)[\\*_]{2}[^\\s]{1}[^\\*_]+[\\*_]{2}(\\s|\\.|,|;|:|\\-|\\?|$)"
regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b1'7d'5b'5e'5cs'5d'7b1'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b1'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 = compileRegex "(\\s|^)[\\*_]{1}[^\\s]{1}[^\\*_]+[\\*_]{1}(\\s|\\.|,|;|:|\\-|\\?|$)"
regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b3'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b3'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 = compileRegex "(\\s|^)[\\*_]{3}[^\\*_]+[\\*_]{3}(\\s|\\.|,|;|:|\\-|\\?|$)"
regex_'28'5b'5cs'5d'7b4'2c'7d'7c'5ct'2b'29'2e'2a'24 = compileRegex "([\\s]{4,}|\\t+).*$"
regex_'5b'5c'2a'5c'2b'5c'2d'5d'5cs = compileRegex "[\\*\\+\\-]\\s"
regex_'5b'5cd'5d'2b'5c'2e'5cs = compileRegex "[\\d]+\\.\\s"
regex_'28Title'7cAuthor'7cDate'7cCopyright'7cRevision'7cCSS'7cLaTeX'5c_XSLT'7cCategories'7cTags'7cBaseName'7cExcerpt'29'3a'28'2e'2a'29'2b'24 = compileRegex "(Title|Author|Date|Copyright|Revision|CSS|LaTeX\\ XSLT|Categories|Tags|BaseName|Excerpt):(.*)+$"
regex_'2d'2d'3e = compileRegex "-->"
regex_'60'5b'5e'60'5d'2b'60 = compileRegex "`[^`]+`"
regex_'3c'21'2d'2d = compileRegex "<!--"
regex_'5c'5b'5b'5e'5c'5d'5c'5e'5d'2b'5c'5d'5cs'2a'5c'5b'5b'5e'5c'5d'5d'2a'5c'5d'5cs'2a'28'5cs'2b'5c'22'5b'5e'5c'22'5d'2a'5c'22'29'7b0'2c1'7d = compileRegex "\\[[^\\]\\^]+\\]\\s*\\[[^\\]]*\\]\\s*(\\s+\\\"[^\\\"]*\\\"){0,1}"
regex_'5c'5b'5c'5e'5b'5e'5c'5d'5d'2b'5c'5d = compileRegex "\\[\\^[^\\]]+\\]"
regex_'5c'5b'5b'5e'5c'5d'5c'5e'5d'2b'5c'5d'5cs'2a'5c'28'5b'5e'5c'28'5d'2a'5c'29 = compileRegex "\\[[^\\]\\^]+\\]\\s*\\([^\\(]*\\)"
regex_'5c'5b'5b'5e'5c'5d'5c'5e'5d'2b'5c'5d'5c'3a'5cs'2b'5b'5e'5cs'5d'2b'28'5cs'2b'5c'22'5b'5e'5c'22'5d'2a'5c'22'29'7b0'2c1'7d = compileRegex "\\[[^\\]\\^]+\\]\\:\\s+[^\\s]+(\\s+\\\"[^\\\"]*\\\"){0,1}"
regex_'5c'21'5c'5b'5b'5e'5c'5d'5c'5e'5d'2b'5c'5d'5c'28'5b'5e'5c'28'5d'2a'5c'29 = compileRegex "\\!\\[[^\\]\\^]+\\]\\([^\\(]*\\)"
regex_'5c'21'5c'5b'5b'5e'5c'5d'5c'5e'5d'2b'5c'5d'5c'5b'5b'5e'5c'5b'5d'2a'5c'5d = compileRegex "\\!\\[[^\\]\\^]+\\]\\[[^\\[]*\\]"
regex_'3c'28https'3f'7cftp'29'3a'5b'5e'5c'22'3e'5cs'5d'2b'3e = compileRegex "<(https?|ftp):[^\\\">\\s]+>"
regex_'3c'28'3f'3amailto'3a'29'3f'28'5b'2d'2e'5cw'5d'2b'5c'40'5b'2da'2dz0'2d9'5d'2b'28'5c'2e'5b'2da'2dz0'2d9'5d'2b'29'2a'5c'2e'5ba'2dz'5d'2b'29'3e = compileRegex "<(?:mailto:)?([-.\\w]+\\@[-a-z0-9]+(\\.[-a-z0-9]+)*\\.[a-z]+)>"
regex_'5b'7e'5d'7b2'7d'5b'5e'7e'5d'2e'2a'5b'5e'7e'5d'5b'7e'5d'7b2'7d = compileRegex "[~]{2}[^~].*[^~][~]{2}"
regex___'24 = compileRegex " $"
parseRules ("Markdown","Normal Text") =
(((pColumn 0 >> pDetectChar False '>' >>= withAttribute NormalTok) >>~ pushContext ("Markdown","blockquote"))
<|>
((pColumn 0 >> pRegExpr regex_'23'5cs'2e'2a'5b'23'5d'3f'24 >>= withAttribute FunctionTok))
<|>
((pColumn 0 >> pRegExpr regex_'23'23'5cs'2e'2a'5b'23'5d'3f'24 >>= withAttribute FunctionTok))
<|>
((pColumn 0 >> pRegExpr regex_'23'23'23'5cs'2e'2a'5b'23'5d'3f'24 >>= withAttribute FunctionTok))
<|>
((pColumn 0 >> pRegExpr regex_'23'23'23'23'5cs'2e'2a'5b'23'5d'3f'24 >>= withAttribute FunctionTok))
<|>
((pColumn 0 >> pRegExpr regex_'23'23'23'23'23'5cs'2e'2a'5b'23'5d'3f'24 >>= withAttribute FunctionTok))
<|>
((pColumn 0 >> pRegExpr regex_'23'23'23'23'23'23'5cs'2e'2a'5b'23'5d'3f'24 >>= withAttribute FunctionTok))
<|>
((pRegExpr regex_'5cs'2a'28'5b'5c'2a'5c'2d'5f'5d'5cs'3f'29'7b3'2c'7d'5cs'2a >>= withAttribute NormalTok))
<|>
((pRegExpr regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b2'7d'5b'5e'5cs'5d'7b1'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b2'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 >>= withAttribute NormalTok))
<|>
((pRegExpr regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b1'7d'5b'5e'5cs'5d'7b1'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b1'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 >>= withAttribute NormalTok))
<|>
((pRegExpr regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b3'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b3'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 >>= withAttribute NormalTok))
<|>
((pColumn 0 >> pRegExpr regex_'28'5b'5cs'5d'7b4'2c'7d'7c'5ct'2b'29'2e'2a'24 >>= withAttribute BaseNTok))
<|>
((pColumn 0 >> pRegExpr regex_'5b'5c'2a'5c'2b'5c'2d'5d'5cs >>= withAttribute NormalTok) >>~ pushContext ("Markdown","bullet"))
<|>
((pColumn 0 >> pRegExpr regex_'5b'5cd'5d'2b'5c'2e'5cs >>= withAttribute NormalTok) >>~ pushContext ("Markdown","numlist"))
<|>
((pColumn 0 >> pRegExpr regex_'28Title'7cAuthor'7cDate'7cCopyright'7cRevision'7cCSS'7cLaTeX'5c_XSLT'7cCategories'7cTags'7cBaseName'7cExcerpt'29'3a'28'2e'2a'29'2b'24 >>= withAttribute CommentTok))
<|>
((parseRules ("Markdown","inc")))
<|>
(currentContext >>= \x -> guard (x == ("Markdown","Normal Text")) >> pDefault >>= withAttribute NormalTok))
parseRules ("Markdown","blockquote") =
(((pRegExpr regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b2'7d'5b'5e'5cs'5d'7b1'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b2'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 >>= withAttribute DataTypeTok))
<|>
((pRegExpr regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b1'7d'5b'5e'5cs'5d'7b1'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b1'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 >>= withAttribute DataTypeTok))
<|>
((parseRules ("Markdown","inc")))
<|>
(currentContext >>= \x -> guard (x == ("Markdown","blockquote")) >> pDefault >>= withAttribute DataTypeTok))
parseRules ("Markdown","bullet") =
(((pRegExpr regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b2'7d'5b'5e'5cs'5d'7b1'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b2'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 >>= withAttribute FloatTok))
<|>
((pRegExpr regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b1'7d'5b'5e'5cs'5d'7b1'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b1'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 >>= withAttribute FloatTok))
<|>
((parseRules ("Markdown","inc")))
<|>
(currentContext >>= \x -> guard (x == ("Markdown","bullet")) >> pDefault >>= withAttribute FloatTok))
parseRules ("Markdown","numlist") =
(((pRegExpr regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b2'7d'5b'5e'5cs'5d'7b1'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b2'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 >>= withAttribute FloatTok))
<|>
((pRegExpr regex_'28'5cs'7c'5e'29'5b'5c'2a'5f'5d'7b1'7d'5b'5e'5cs'5d'7b1'7d'5b'5e'5c'2a'5f'5d'2b'5b'5c'2a'5f'5d'7b1'7d'28'5cs'7c'5c'2e'7c'2c'7c'3b'7c'3a'7c'5c'2d'7c'5c'3f'7c'24'29 >>= withAttribute FloatTok))
<|>
((parseRules ("Markdown","inc")))
<|>
(currentContext >>= \x -> guard (x == ("Markdown","numlist")) >> pDefault >>= withAttribute FloatTok))
parseRules ("Markdown","comment") =
(((pRegExpr regex_'2d'2d'3e >>= withAttribute CommentTok) >>~ (popContext))
<|>
(currentContext >>= \x -> guard (x == ("Markdown","comment")) >> pDefault >>= withAttribute CommentTok))
parseRules ("Markdown","inc") =
(((pRegExpr regex_'60'5b'5e'60'5d'2b'60 >>= withAttribute BaseNTok))
<|>
((pRegExpr regex_'3c'21'2d'2d >>= withAttribute NormalTok) >>~ pushContext ("Markdown","comment"))
<|>
((pRegExpr regex_'5c'5b'5b'5e'5c'5d'5c'5e'5d'2b'5c'5d'5cs'2a'5c'5b'5b'5e'5c'5d'5d'2a'5c'5d'5cs'2a'28'5cs'2b'5c'22'5b'5e'5c'22'5d'2a'5c'22'29'7b0'2c1'7d >>= withAttribute OtherTok))
<|>
((pRegExpr regex_'5c'5b'5c'5e'5b'5e'5c'5d'5d'2b'5c'5d >>= withAttribute OtherTok))
<|>
((pRegExpr regex_'5c'5b'5b'5e'5c'5d'5c'5e'5d'2b'5c'5d'5cs'2a'5c'28'5b'5e'5c'28'5d'2a'5c'29 >>= withAttribute OtherTok))
<|>
((pRegExpr regex_'5c'5b'5b'5e'5c'5d'5c'5e'5d'2b'5c'5d'5c'3a'5cs'2b'5b'5e'5cs'5d'2b'28'5cs'2b'5c'22'5b'5e'5c'22'5d'2a'5c'22'29'7b0'2c1'7d >>= withAttribute OtherTok))
<|>
((pRegExpr regex_'5c'21'5c'5b'5b'5e'5c'5d'5c'5e'5d'2b'5c'5d'5c'28'5b'5e'5c'28'5d'2a'5c'29 >>= withAttribute AlertTok))
<|>
((pRegExpr regex_'5c'21'5c'5b'5b'5e'5c'5d'5c'5e'5d'2b'5c'5d'5c'5b'5b'5e'5c'5b'5d'2a'5c'5d >>= withAttribute AlertTok))
<|>
((pRegExpr regex_'3c'28https'3f'7cftp'29'3a'5b'5e'5c'22'3e'5cs'5d'2b'3e >>= withAttribute OtherTok))
<|>
((pRegExpr regex_'3c'28'3f'3amailto'3a'29'3f'28'5b'2d'2e'5cw'5d'2b'5c'40'5b'2da'2dz0'2d9'5d'2b'28'5c'2e'5b'2da'2dz0'2d9'5d'2b'29'2a'5c'2e'5ba'2dz'5d'2b'29'3e >>= withAttribute OtherTok))
<|>
((pRegExpr regex_'5b'7e'5d'7b2'7d'5b'5e'7e'5d'2e'2a'5b'5e'7e'5d'5b'7e'5d'7b2'7d >>= withAttribute NormalTok))
<|>
((pRegExpr regex___'24 >>= withAttribute NormalTok))
<|>
(currentContext >>= \x -> guard (x == ("Markdown","inc")) >> pDefault >>= withAttribute NormalTok))
parseRules x = parseRules ("Markdown","Normal Text") <|> fail ("Unknown context" ++ show x)