diff --git a/src/MdToHTML.hs b/src/MdToHTML.hs index a99555b..9e0d5e6 100644 --- a/src/MdToHTML.hs +++ b/src/MdToHTML.hs @@ -21,6 +21,7 @@ data MdToken | Header HeaderLevel MdToken | Para MdToken | Line [MdToken] + | SingleNewline -- A single newline is rendered as a space. | Linebreak | HorizontalRule | Blockquote MdToken @@ -42,6 +43,7 @@ instance Show MdToken where show (Para token) = "

" ++ show token ++ "

" show (Line tokens) = concat (map show tokens) show Linebreak = "
" + show SingleNewline = " " show HorizontalRule = "---------" show (Blockquote token) = "BLOCK" ++ show token show (UnordList tokens) = "UNORD" ++ concat (map show tokens) @@ -87,12 +89,11 @@ lineToList (Line tokens) = tokens parseHeader :: ReadP MdToken parseHeader = do skipSpaces - headers <- many1 mustBeHash + headers <- munch1 (== '#') when ((length headers) > 6) pfail - _ <- string " " --- text <- manyTill (get) ((string "\n") <|> (eof >> return ""))-- Parse until EOL or EOF + skipSpaces text <- munch1 (/= '\n') Text.ParserCombinators.ReadP.optional (char '\n') let parsedText = fst $ leftmostLongestParse parseLine text @@ -128,6 +129,11 @@ parseLinebreak = do char '\n' return Linebreak +parseSingleNewline :: ReadP MdToken +parseSingleNewline = do + char '\n' + return SingleNewline + -- Parse a regular string as a Unit. parseString :: ReadP MdToken parseString = do @@ -136,7 +142,7 @@ parseString = do return (Unit (firstChar : text)) lineParsers :: [ReadP MdToken] -lineParsers = [parseLinebreak, parseBold, parseItalic, parseString] -- A 'line' doesn't include a 'header' +lineParsers = [parseLinebreak, parseSingleNewline, parseBold, parseItalic, parseString] -- A 'line' doesn't include a 'header' -- List of all parsers allParsers :: [ReadP MdToken] @@ -154,7 +160,6 @@ parseLine = do remaining <- look when (null remaining) pfail parsed <- parseMany parseLineToken - -- traceM $ show parsed return (Line parsed) -- Parse a paragraph, which is a 'Line' (can span multiple actual lines), separated by double-newlines. diff --git a/src/Test.hs b/src/Test.hs index 22859f7..240d895 100644 --- a/src/Test.hs +++ b/src/Test.hs @@ -9,36 +9,36 @@ check_equal desc expected actual = TestCase (assertEqual desc expected actual) convert :: String -> String convert md = show . fst $ leftmostLongestParse parseDocument md -headerTests = TestList - [ - check_equal "Should convert H1 heading" "

Hello

" (convert "# Hello"), - check_equal "Should convert H2 heading" "

Hello

" (convert "## Hello"), - check_equal "Should convert H3 heading" "

Hello

" (convert "### Hello"), - check_equal "Should convert H4 heading" "

Hello

" (convert "#### Hello"), - check_equal "Should convert H5 heading" "
Hello
" (convert "##### Hello"), - check_equal "Should convert H6 heading" "
Hello
" (convert "###### Hello") - ] - -boldTests = TestList - [ - check_equal "Should convert bold" "

Hello

" (convert "__Hello__"), - check_equal "Should convert italic" "

Hello

" (convert "_Hello_"), - check_equal "Should convert bold and italic in a sentence" "

It is a wonderful day

" (convert "It _is_ a __wonderful__ day") - ] - -integrationTests = TestList - [ - check_equal "Integration 1" "

Sample Markdown

This is some basic, sample markdown.

Second Heading

" (convert "# Sample Markdown\n\n This is some basic, sample markdown.\n\n ## __Second__ _Heading_"), - check_equal "Integration 2" "

Hello World

" (convert "__Hello__\n_World_"), - check_equal "Integration 3" "

Hello

World

" (convert "# Hello\nWorld") +headerTests = + TestList + [ check_equal "Should convert H1 heading" "

Hello

" (convert "# Hello"), + check_equal "Should convert H2 heading" "

Hello

" (convert "## Hello"), + check_equal "Should convert H3 heading" "

Hello

" (convert "### Hello"), + check_equal "Should convert H4 heading" "

Hello

" (convert "#### Hello"), + check_equal "Should convert H5 heading" "
Hello
" (convert "##### Hello"), + check_equal "Should convert H6 heading" "
Hello
" (convert "###### Hello") ] +boldTests = + TestList + [ check_equal "Should convert bold" "

Hello

" (convert "__Hello__"), + check_equal "Should convert italic" "

Hello

" (convert "_Hello_"), + check_equal "Should convert bold and italic in a sentence" "

It is a wonderful day

" (convert "It _is_ a __wonderful__ day") + ] + +integrationTests = + TestList + [ check_equal "Integration 1" "

Sample Markdown

This is some basic, sample markdown.

Second Heading

" (convert "# Sample Markdown\n\n This is some basic, sample markdown.\n\n ## __Second__ _Heading_"), + check_equal "Integration 2" "

Hello World

" (convert "__Hello__\n_World_"), + check_equal "Integration 3" "

Hello

World

" (convert "# Hello\nWorld"), + check_equal "Integration 4" "

Hello

" (convert "# Hello\n") + ] -tests = TestList - [ - headerTests, +tests = + TestList + [ headerTests, boldTests, integrationTests - ] + ] runTests = runTestTT tests