Compare commits

...

4 Commits

@ -53,7 +53,7 @@ instance Show MdToken where
show (OrdList tokens) = "ORD" ++ concatMap show tokens show (OrdList tokens) = "ORD" ++ concatMap show tokens
show (Code code) = show code show (Code code) = show code
show (Codeblock code) = show code show (Codeblock code) = show code
show (Link txt url) = "<a href=" ++ getUrl url ++ ">" ++ show txt ++ "</a>" show (Link txt url) = "<a href=\"" ++ getUrl url ++ "\">" ++ show txt ++ "</a>"
show (Image txt imgPath) = "<img src=" ++ getPath imgPath ++ ">" ++ show txt ++ "</img>" show (Image txt imgPath) = "<img src=" ++ getPath imgPath ++ ">" ++ show txt ++ "</img>"
show (Bold token) = "<b>" ++ show token ++ "</b>" show (Bold token) = "<b>" ++ show token ++ "</b>"
show (Italic token) = "<i>" ++ show token ++ "</i>" show (Italic token) = "<i>" ++ show token ++ "</i>"
@ -83,6 +83,8 @@ lookaheadParse stringCmp = do
lineToList :: MdToken -> [MdToken] lineToList :: MdToken -> [MdToken]
lineToList (Line tokens) = tokens lineToList (Line tokens) = tokens
specialChars = "\\#*_[\n "
-- --------------- -- ---------------
-- Parse a markdown header, denoted by 1-6 #'s followed by some text, followed by EOL. -- Parse a markdown header, denoted by 1-6 #'s followed by some text, followed by EOL.
@ -121,6 +123,14 @@ parseItalic = do
let parsedText = fst $ leftmostLongestParse parseLine text let parsedText = fst $ leftmostLongestParse parseLine text
return (Italic parsedText) return (Italic parsedText)
-- Parse a link
parseLink :: ReadP MdToken
parseLink = do
linkText <- between (string "[") (string "]") (many1 get)
linkURL <- between (string "(") (string ")") (many1 get)
let parsedLinkText = fst $ leftmostLongestParse parseLine linkText
return $ Link parsedLinkText (URL linkURL)
-- Parse a linebreak character -- Parse a linebreak character
parseLinebreak :: ReadP MdToken parseLinebreak :: ReadP MdToken
parseLinebreak = do parseLinebreak = do
@ -134,15 +144,30 @@ parseSingleNewline = do
char '\n' char '\n'
return SingleNewline return SingleNewline
-- Parse an escaped character
parseEscapedChar :: ReadP MdToken
parseEscapedChar = do
char '\\'
escapedChar <- choice (map char specialChars)
return (Unit [escapedChar])
-- Parse a regular string as a Unit. -- Parse a regular string as a Unit.
parseString :: ReadP MdToken parseString :: ReadP MdToken
parseString = do parseString = do
firstChar <- satisfy (/= '\n') -- Must parse at least one non-newline character here firstChar <- satisfy (/= '\n') -- Must parse at least one non-newline character here
text <- munch (`notElem` "#*_[\n ") text <- munch (`notElem` specialChars)
return (Unit (firstChar : text)) return (Unit (firstChar : text))
lineParsers :: [ReadP MdToken] lineParsers :: [ReadP MdToken]
lineParsers = [parseLinebreak, parseSingleNewline, parseBold, parseItalic, parseString] -- A 'line' doesn't include a 'header' lineParsers =
[ parseLinebreak,
parseSingleNewline,
parseEscapedChar,
parseBold,
parseItalic,
parseLink,
parseString
] -- A 'line' doesn't include a 'header'
-- List of all parsers -- List of all parsers
allParsers :: [ReadP MdToken] allParsers :: [ReadP MdToken]

@ -26,19 +26,35 @@ boldTests =
check_equal "Should convert bold and italic in a sentence" "<p>It <i>is</i> a <b>wonderful</b> day</p>" (convert "It _is_ a __wonderful__ day") check_equal "Should convert bold and italic in a sentence" "<p>It <i>is</i> a <b>wonderful</b> day</p>" (convert "It _is_ a __wonderful__ day")
] ]
linkTests =
TestList
[ check_equal "Should convert normal link" "<p><a href=\"https://example.com\">This is an example link.</a></p>" (convert "[This is an example link.](https://example.com)"),
check_equal "Should convert styled link" "<p><a href=\"https://example.com\"><b>Fancy</b>!!!</a></p>" (convert "[__Fancy__!!!](https://example.com)")
]
escapedCharTests =
TestList
[ check_equal "Should print literal underscore" "<p>This is an underscore - _</p>" (convert "This is an underscore - \\_"),
check_equal "Should print literal asterisk" "<p>This is an asterisk - *</p>" (convert "This is an asterisk - \\*"),
check_equal "Should print literal asterisk in bold" "<p>This is a bolded asterisk - <b>*</b></p>" (convert "This is a bolded asterisk - **\\***")
]
integrationTests = integrationTests =
TestList TestList
[ check_equal "Integration 1" "<h1>Sample Markdown</h1><p>This is some basic, sample markdown.</p><h2><b>Second</b> <i>Heading</i></h2>" (convert "# Sample Markdown\n\n This is some basic, sample markdown.\n\n ## __Second__ _Heading_"), [ check_equal "Integration 1" "<h1>Sample Markdown</h1><p>This is some basic, sample markdown.</p><h2><b>Second</b> <i>Heading</i></h2>" (convert "# Sample Markdown\n\n This is some basic, sample markdown.\n\n ## __Second__ _Heading_"),
check_equal "Integration 2" "<p><b>Hello</b> <i>World</i></p>" (convert "__Hello__\n_World_"), check_equal "Integration 2" "<p><b>Hello</b> <i>World</i></p>" (convert "__Hello__\n_World_"),
check_equal "Integration 3" "<h1>Hello</h1><p>World</p>" (convert "# Hello\nWorld"), check_equal "Integration 3" "<h1>Hello</h1><p>World</p>" (convert "# Hello\nWorld"),
check_equal "Integration 4" "<p>a b</p>" (convert "a\nb"), check_equal "Integration 4" "<p>a b</p>" (convert "a\nb"),
check_equal "Integration 5" "<h1>Hello</h1>" (convert "# Hello\n") check_equal "Integration 5" "<h1>Hello</h1>" (convert "# Hello\n"),
check_equal "Integration 6" "<p>First line<br>Second line</p>" (convert "First line \nSecond line")
] ]
tests = tests =
TestList TestList
[ headerTests, [ headerTests,
boldTests, boldTests,
linkTests,
escapedCharTests,
integrationTests integrationTests
] ]

Loading…
Cancel
Save