@@ -362,7 +362,10 @@ parseInline text
362362 Just (' *' , _) -> parseDecoration ' *' text
363363 Just (' _' , _) -> parseDecoration ' _' text
364364 Just (' ~' , _) -> parseStrikethrough text
365- Just (' <' , _) -> parseHtmlTags text
365+ Just (' <' , _) ->
366+ if T. isPrefixOf (T. pack " <u>" ) text || T. isPrefixOf (T. pack " </u>" ) text
367+ then parseHtmlTags text
368+ else parseAngleBracketLink text
366369 _ -> parsePlainText text
367370
368371parseLinkOrCheckbox :: Text -> [MDElement ]
@@ -375,37 +378,54 @@ parseLinkOrCheckbox text
375378
376379parseBracketLink :: Text -> [MDElement ]
377380parseBracketLink text =
378- let linkTextStart = T. tail $ T. takeWhile (/= ' ]' ) text
379- urlStart = T. drop 2 $ T. dropWhile (/= ' (' ) text
380- (linkUrl, rest) = T. break (== ' )' ) urlStart
381- cleanUrl = T. strip linkUrl
382-
383- -- Check for optional title
384- (titlePart, remainingText) =
385- case T. uncons rest of
386- Just (_, titleText) ->
387- let stripped = T. strip $ T. takeWhile (/= ' )' ) titleText
388- titleRemaining = T. drop (T. length stripped + 1 ) titleText
389- in if T. isPrefixOf (T. pack " \" " ) stripped && T. isSuffixOf (T. pack " \" " ) stripped
390- then (Just (T. init $ T. tail stripped), titleRemaining)
391- else (Nothing , rest)
392- Nothing -> (Nothing , rest)
393-
394- linkTextParsed = parseInline linkTextStart
395- nextText = T. drop 1 remainingText
396- in case linkTextParsed of
397- [] -> Link cleanUrl cleanUrl Nothing : parseInline nextText
398- [PlainText t] -> Link t cleanUrl titlePart : parseInline nextText
399- multipleElems -> Link (T. concat $ map renderPlainText multipleElems) cleanUrl titlePart : parseInline nextText
381+ let (linkText, afterText) = parseLinkText text
382+ (url, title, remaining) = parseLinkUrlAndTitle afterText
383+ in case parseInline linkText of
384+ [] -> Link url url Nothing : parseInline remaining
385+ [PlainText t] -> Link t url title : parseInline remaining
386+ multipleElems ->
387+ let renderedText = T. concat $ map renderPlainText multipleElems
388+ in Link renderedText url title : parseInline remaining
400389 where
401- renderPlainText (PlainText t) = t
402- renderPlainText _ = T. empty
390+ -- Parse the link text between square brackets
391+ parseLinkText :: Text -> (Text , Text )
392+ parseLinkText t =
393+ let linkTextStart = T. tail $ T. takeWhile (/= ' ]' ) t
394+ remaining = T. drop (T. length linkTextStart + 2 ) t
395+ in (linkTextStart, remaining)
396+
397+ -- Parse URL and optional title
398+ parseLinkUrlAndTitle :: Text -> (Text , Maybe Text , Text )
399+ parseLinkUrlAndTitle t
400+ | T. isPrefixOf (T. pack " (" ) t =
401+ let urlAndRest = T. tail t
402+ (rawUrl, afterUrl) = T. break (\ c -> c == ' )' || c == ' "' ) urlAndRest
403+ cleanUrl = T. strip rawUrl
404+ in case T. uncons afterUrl of
405+ Just (' "' , titleRest) ->
406+ let (rawTitle, afterTitle) = T. break (== ' "' ) (T. tail titleRest)
407+ cleanTitle = unescapeTitle rawTitle
408+ finalRest = T. drop (T. length rawTitle + 2 ) afterTitle
409+ in (cleanUrl, Just cleanTitle, finalRest)
410+ Just (' )' , rest) -> (cleanUrl, Nothing , rest)
411+ _ -> (cleanUrl, Nothing , T. empty)
412+ | otherwise = (T. pack " " , Nothing , t)
413+
414+ -- Unescape title, particularly handling "
415+ unescapeTitle :: Text -> Text
416+ unescapeTitle =
417+ T. replace (T. pack " "" ) (T. pack " \" " )
418+ . T. replace (T. pack " &" ) (T. pack " &" )
419+ . T. replace (T. pack " <" ) (T. pack " <" )
420+ . T. replace (T. pack " >" ) (T. pack " >" )
403421
404422parseAngleBracketLink :: Text -> [MDElement ]
405- parseAngleBracketLink text =
406- let (link, rest) = T. break (== ' >' ) (T. tail text)
407- cleanLink = T. strip link
408- in Link cleanLink cleanLink Nothing : parseInline (T. drop 1 rest)
423+ parseAngleBracketLink text
424+ | T. isPrefixOf (T. pack " <" ) text && T. isSuffixOf (T. pack " >" ) text =
425+ let link = T. init $ T. tail text
426+ cleanLink = T. strip link
427+ in Link cleanLink cleanLink Nothing : parseInline (T. drop (T. length link + 2 ) text)
428+ | otherwise = [PlainText text]
409429
410430renderPlainText :: MDElement -> Text
411431renderPlainText (PlainText t) = t
0 commit comments