diff --git a/src/MdToHTML.hs b/src/MdToHTML.hs
index d7ec5f0..c9712a7 100644
--- a/src/MdToHTML.hs
+++ b/src/MdToHTML.hs
@@ -48,6 +48,8 @@ data MdToken
| Figure MdToken URL (Maybe [CssClass])
| Bold MdToken
| Italic MdToken
+ | Superscript MdToken
+ | Subscript MdToken
| Strikethrough MdToken
| Unit String
deriving (Eq)
@@ -72,6 +74,8 @@ instance Show MdToken where
show (Figure txt url cssClasses) = " " class=\"" ++ unwords classes ++ "\"") cssClasses ++ "/>
" ++ show token ++ ""
show (Unit unit) = printf "%s" unit
@@ -201,6 +205,20 @@ parseItalic = parseItalicWith '*' <|> parseItalicWith '_'
inside <- someTill parseLineToken (char delim)
return (Italic (Line inside))
+-- Parse subscript
+parseSubscript :: Parser MdToken
+parseSubscript = do
+ char '~'
+ inside <- someTill parseLineToken (char '~')
+ return (Subscript (Line inside))
+
+-- Parse superscript
+parseSuperscript :: Parser MdToken
+parseSuperscript = do
+ char '^'
+ inside <- someTill parseLineToken (char '^')
+ return (Superscript (Line inside))
+
-- Parse strikethrough text
parseStrikethrough :: Parser MdToken
parseStrikethrough = do
@@ -326,6 +344,8 @@ lineParsers =
parseBold,
parseItalic,
parseStrikethrough,
+ parseSubscript,
+ parseSuperscript,
parseLink,
parseUnit
] -- A 'line' doesn't include a 'header'
@@ -338,6 +358,8 @@ lineParsersWithoutNewline =
parseBold,
parseItalic,
parseStrikethrough,
+ parseSubscript,
+ parseSuperscript,
parseLink,
parseUnitExceptNewline
] -- A list line cannot contain newlines.
@@ -406,10 +428,16 @@ parseBlockquote = do
-- Parse a nested list item.
parseListNested :: Parser MdToken
parseListNested = do
- let firstCharParser = string (T.pack " ") <|> string (T.pack "\t")
+ let firstCharParser = (<>) <$> (string (T.pack " ") <|> string (T.pack "\t")) <*> (T.pack <$> many (char ' '))
let restOfLineParser = manyTill anySingle (void (char '\n') <|> eof)
- lines <- greedyParse1 (firstCharParser *> restOfLineParser)
- let linesParsed = leftmostLongestParse (parseUnorderedList <|> parseOrderedList) (init $ unlines lines)
+ -- For the first line, I manually run firstCharParser and restOfLineParser. The
+ -- result of firstCharParser is saved. For every subsequent line, I parse exactly
+ -- the same string as firstCharParser.
+ firstLineSpaces <- firstCharParser
+ firstLine <- restOfLineParser
+ lines <- greedyParse (string firstLineSpaces *> restOfLineParser)
+ let allLines = firstLine : lines
+ let linesParsed = leftmostLongestParse (parseUnorderedList <|> parseOrderedList) (init $ unlines allLines)
when (null (show linesParsed)) empty
return linesParsed
diff --git a/src/MdToHtmlTest.hs b/src/MdToHtmlTest.hs
index 324afb0..5773ebe 100644
--- a/src/MdToHtmlTest.hs
+++ b/src/MdToHtmlTest.hs
@@ -31,7 +31,7 @@ boldTests =
strikethroughTests =
TestList
[ check_equal "Should convert strikethrough" "
Hello
The universe is ~7 days old. The universe is 13 billion years old.
The universe is ~7 days old. The universe is 13 billion years old.
This is a list
Item 2
Quote
a
b
" (convert "a\n\n---\n\nb")] +subscriptTests = + TestList + [check_equal "Should convert subscript" "Ab" (convert "A~b~")] + +superscriptTests = + TestList + [check_equal "Should convert superscript" "Ab" (convert "A^b^")] + tableTests = TestList [ check_equal