diff --git a/src/MdToHTML.hs b/src/MdToHTML.hs index a44a15b..d16a38b 100644 --- a/src/MdToHTML.hs +++ b/src/MdToHTML.hs @@ -272,8 +272,62 @@ parseQuotedLines = -- Parse a blockquote, which is a greater-than sign followed by a paragraph. parseBlockquote :: ReadP MdToken parseBlockquote = do - char '>' - Blockquote <$> (parseBlockquote <++ parsePara) -- Parse another blockquote or a regular paragraph, wrap it in a blockquote. + quotedLines <- parseQuotedLines + -- remaining <- look + -- let quotedLines = fst $ leftmostLongestParse parseQuotedLines remaining + -- string (init $ unlines quotedLines) + let parsedQuotedLines = fst $ leftmostLongestParse (many1 (parseBlockquote <++ parsePara)) (init $ unlines quotedLines) -- unlines joins the lines together with a newline, and adds a trailing newline. init removes the trailing newline. + return (Blockquote parsedQuotedLines) + +-- Parse a nested list item. +parseUListNested :: ReadP MdToken +parseUListNested = do + -- firstChar <- string " " <++ string "\t" + -- skipSpaces + -- restOfLine <- manyTill get (void (char '\n') <++ eof) + -- let restOfLineParsed = fst $ leftmostLongestParse parseLine restOfLine + -- return restOfLineParsed + let firstCharParser = string " " <++ string "\t" + let restOfLineParser = manyTill get (void (char '\n') <++ eof) + lines <- greedyParse1 (firstCharParser *> restOfLineParser) + let linesParsed = fst $ leftmostLongestParse parseUnorderedList (init $ unlines lines) + return linesParsed + +-- Parse an unordered list line item. +parseUListLineItem :: ReadP MdToken +parseUListLineItem = do + firstChar <- choice (map char ['*', '+', '-']) + skipSpaces + restOfLine <- manyTill get (void (char '\n') <++ eof) + let restOfLineParsed = fst $ leftmostLongestParse parseLine restOfLine + nestedList <- parseUListNested <++ return (Unit "") + return $ Line [restOfLineParsed, nestedList] + +-- Parse an unordered list paragraph item. +-- This is defined as a line item, followed by an empty line, followed by one or more +-- lines indented by a space or tab. +parseUListParaItem :: ReadP MdToken +parseUListParaItem = do + firstLine <- parseUListLineItem + char '\n' + lines <- greedyParse1 ((string " " <|> string "\t") *> parseTillEol) + let res = fst $ leftmostLongestParse (greedyParse1 parsePara) (init $ unlines lines) + char '\n' + return $ Document (Para firstLine : res) -- I only wrap this in a document because I want some way of converting [MdToken] to MdToken, without any overhead. There is no other reason to wrap it in a Document. + +-- This is hacky as hell +-- parsedParas <- manyTillLazy parsePara (string "\n\n" *> choice (map char "*-+")) +-- return $ Document parsedParas -- I wrap this in a document because I want some way of converting [MdToken] to MdToken, without any overhead. There is no other reason to wrap it in a Document. + +-- Parse an unordered list item, which can be a line item or another list. +parseUListItem :: ReadP MdToken +parseUListItem = parseUListParaItem <++ parseUListLineItem <++ parseUListNested + +-- Parse an unordered list. +parseUnorderedList :: ReadP MdToken +parseUnorderedList = do + lineItems <- greedyParse1 parseUListItem + return $ UnordList lineItems -- Parse a document, which is multiple paragraphs. parseDocument :: ReadP MdToken