@@ -114,6 +114,9 @@ parseMarkdown = parseLines [] . skipEmptyLines
114114parseLines :: [Text ] -> [Text ] -> [MDElement ]
115115parseLines acc [] = processBlock (reverse acc)
116116parseLines acc (line : lines )
117+ | isCodeBlockStart line =
118+ let (codeBlock, rest) = parseCodeBlock (line : lines )
119+ in processBlock (reverse acc) ++ [codeBlock] ++ parseLines [] rest
117120 | isTableLine line =
118121 case identifyTable (line : lines ) of
119122 Just (tableLines, rest) ->
@@ -359,6 +362,7 @@ parseInline text
359362 | T. null text = []
360363 | otherwise =
361364 case T. uncons text of
365+ Just (' `' , _) -> parseInlineCode text
362366 Just (' [' , _) -> parseLinkOrCheckbox text
363367 Just (' *' , _) -> parseDecoration ' *' text
364368 Just (' _' , _) -> parseDecoration ' _' text
@@ -516,3 +520,29 @@ parsePlainText :: Text -> [MDElement]
516520parsePlainText text =
517521 let (content, rest) = T. break (`elem` [' *' , ' _' , ' ~' , ' <' ]) text
518522 in PlainText content : parseInline rest
523+
524+ isCodeBlockStart :: Text -> Bool
525+ isCodeBlockStart line =
526+ T. isPrefixOf (T. pack " ```" ) (T. stripStart line)
527+
528+ parseCodeBlock :: [Text ] -> (MDElement , [Text ])
529+ parseCodeBlock (firstLine : rest) =
530+ let lang = T. strip $ T. drop 3 $ T. stripStart firstLine
531+ (codeLines, remainingLines) = span (not . isCodeBlockStart) rest
532+ codeBlockContent = T. unlines codeLines
533+ in (CodeBlock codeBlockContent, drop 1 remainingLines)
534+ parseCodeBlock _ = (CodeBlock T. empty, [] )
535+
536+ parseInlineCode :: Text -> [MDElement ]
537+ parseInlineCode text
538+ | T. isPrefixOf (T. pack " ``" ) text =
539+ let (content, rest) = T. breakOn (T. pack " ``" ) (T. drop 2 text)
540+ in if T. isPrefixOf (T. pack " ``" ) rest
541+ then InlineCode (T. strip content) : parseInline (T. drop 2 rest)
542+ else PlainText (T. pack " ``" ) : parseInline (T. drop 2 text)
543+ | T. isPrefixOf (T. pack " `" ) text =
544+ let (content, rest) = T. breakOn (T. pack " `" ) (T. drop 1 text)
545+ in if T. isPrefixOf (T. pack " `" ) rest
546+ then InlineCode (T. strip content) : parseInline (T. drop 1 rest)
547+ else PlainText (T. pack " `" ) : parseInline (T. drop 1 text)
548+ | otherwise = [PlainText text]
0 commit comments