@@ -1125,9 +1125,15 @@ htmlTag :: (HasReaderOptions st, Monad m)
11251125htmlTag f = try $ do
11261126 lookAhead (char '<')
11271127 inp <- getInput
1128− let (next : _) = canonicalizeTags $ parseTagsOptions
1129− parseOptions{ optTagWarning = False } inp
1130− guard $ f next
1128+ let ts = canonicalizeTags $ parseTagsOptions
1129+ parseOptions{ optTagWarning = False
1130+ , optTagPosition = True }
1131+ (inp ++ " ") -- add space to ensure that
1132+ -- we get a TagPosition after the tag
1133+ (next, ln, col) <- case ts of
1134+ (TagPosition{} : next : TagPosition ln col : _)
1135+ | f next -> return (next, ln, col)
1136+ _ -> mzero
11311137
11321138 -- <www.boe.es/buscar/act.php?id=BOE-A-1996-8930#a66>
11331139 -- should NOT be parsed as an HTML tag, see #2277,
@@ -1138,6 +1144,11 @@ htmlTag f = try $ do
11381144 [] -> False
11391145 (c:cs) -> isLetter c && all isNameChar cs
11401146
1147+ let endAngle = try $ do char '>'
1148+ pos <- getPosition
1149+ guard $ (sourceLine pos == ln &&
1150+ sourceColumn pos >= col) ||
1151+ sourceLine pos > ln
11411152 let handleTag tagname = do
11421153 -- basic sanity check, since the parser is very forgiving
11431154 -- and finds tags in stuff like x<y)
@@ -1146,14 +1157,14 @@ htmlTag f = try $ do
11461157 -- <https://example.org> should NOT be a tag either.
11471158 -- tagsoup will parse it as TagOpen "https:" [("example.org","")]
11481159 guard $ last tagname /= ':'
1149− rendered <- manyTill anyChar (char '>')
1150− return (next, rendered <> ">")
1160+ char '<'
1161+ rendered <- manyTill anyChar endAngle
1162+ return (next, "<" ++ rendered ++ ">")
11511163 case next of
11521164 TagComment s
11531165 | "<!--" `isPrefixOf` inp -> do
1154− count (length s + 4) anyChar
1155− skipMany (satisfy (/='>'))
1156− char '>'
1166+ char '<'
1167+ manyTill anyChar endAngle
11571168 stripComments <- getOption readerStripComments
11581169 if stripComments
11591170 then return (next, "")