From 7ae868932d5aa11df631a04b86e9293010610cec Mon Sep 17 00:00:00 2001 From: Igor Ranieri Date: Wed, 24 Sep 2025 10:13:16 +0200 Subject: [PATCH] Add located combinator; improved anchor matches with tests --- src/Lexer.hs | 22 +++++++++++++--------- test/Spec.hs | 5 +++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/Lexer.hs b/src/Lexer.hs index 5b29aa8..abced93 100644 --- a/src/Lexer.hs +++ b/src/Lexer.hs @@ -175,22 +175,26 @@ anchors = do where anchor' = (string "#" <|> string "\\#") +located :: Parser a -> Parser (SourcePos, a) +located p = (,) <$> getPosition <*> p + +startPosition :: Parser a -> Parser SourcePos +startPosition = fmap fst . located + -- "Module.Name" -- "Module.Name#anchor" +-- "Module.Name\#anchor" -- this has been deprecated for 9 years, thanks Ben modules :: Lexer modules = do - pos <- getPosition - void $ char '"' - pos' <- getPosition - modName <- modId + startPos <- startPosition $ char '"' + (modPos, modName) <- located modId anch <- option [] do - pos'' <- getPosition - void $ try (string "#" <|> string "\\#") - a <- Text.pack <$> many (satisfy (\c -> c /= '"' && not (isSpace c))) - pure [(pos'', Anchor a)] + anchPos <- startPosition (string "#" <|> string' "\\#") + txt <- Text.pack <$> many (satisfy (\c -> c /= '"' && not (isSpace c))) + pure [(anchPos, Anchor txt)] void $ char '"' - pure $ [(pos, Module), (pos', Token modName)] <> anch + pure $ [(startPos, Module), (modPos, Token modName)] <> anch where modId = intercalate "." <$> (fmap Text.pack <$> (conId `sepBy1` (char '.'))) diff --git a/test/Spec.hs b/test/Spec.hs index 9f76b8b..d202ac2 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -54,6 +54,11 @@ modules = do , (1, 18, Anchor "myAnchor") ] + "\"OtherModule.Name\\#myAnchor\"" + `shouldLexTo` [ (1, 1, Module) + , (1, 2, Token "OtherModule.Name") + , (1, 18, Anchor "myAnchor") + ] link :: Expectation link = "[link to](http://some.website)"