summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/syntax/lexer.rs37
-rw-r--r--tests/ref/meta/link.pngbin52099 -> 92205 bytes
-rw-r--r--tests/typ/meta/link.typ16
3 files changed, 44 insertions, 9 deletions
diff --git a/src/syntax/lexer.rs b/src/syntax/lexer.rs
index a5e4a9e0..748cb076 100644
--- a/src/syntax/lexer.rs
+++ b/src/syntax/lexer.rs
@@ -264,16 +264,35 @@ impl Lexer<'_> {
}
fn link(&mut self) -> SyntaxKind {
+ let mut bracket_stack = Vec::new();
#[rustfmt::skip]
- self.s.eat_while(|c: char| matches!(c,
- | '0' ..= '9'
- | 'a' ..= 'z'
- | 'A' ..= 'Z'
- | '~' | '/' | '%' | '?' | '#' | '&' | '+' | '='
- | '\'' | '.' | ',' | ';'
- ));
-
- if self.s.scout(-1) == Some('.') {
+ self.s.eat_while(|c: char| {
+ match c {
+ | '0' ..= '9'
+ | 'a' ..= 'z'
+ | 'A' ..= 'Z'
+ | '!' | '#' | '$' | '%' | '&' | '*' | '+'
+ | ',' | '-' | '.' | '/' | ':' | ';' | '='
+ | '?' | '@' | '_' | '~' | '\'' => true,
+ '[' => {
+ bracket_stack.push(SyntaxKind::LeftBracket);
+ true
+ }
+ '(' => {
+ bracket_stack.push(SyntaxKind::LeftParen);
+ true
+ }
+ ']' => bracket_stack.pop() == Some(SyntaxKind::LeftBracket),
+ ')' => bracket_stack.pop() == Some(SyntaxKind::LeftParen),
+ _ => false,
+ }
+ });
+ if !bracket_stack.is_empty() {
+ return self.error_at_end("expected closing bracket in link");
+ }
+
+ // Don't include the trailing characters likely to be part of another expression.
+ if matches!(self.s.scout(-1), Some('!' | ',' | '.' | ':' | ';' | '?' | '\'')) {
self.s.uneat();
}
diff --git a/tests/ref/meta/link.png b/tests/ref/meta/link.png
index 4e182e9b..075ca6e1 100644
--- a/tests/ref/meta/link.png
+++ b/tests/ref/meta/link.png
Binary files differ
diff --git a/tests/typ/meta/link.typ b/tests/typ/meta/link.typ
index de4c91c9..36f88f90 100644
--- a/tests/typ/meta/link.typ
+++ b/tests/typ/meta/link.typ
@@ -23,6 +23,22 @@ Nohttps:\//link \
Nohttp\://comment
---
+// Verify that brackets are included in links.
+https://[::1]:8080/ \
+https://example.com/(paren) \
+https://example.com/#(((nested))) \
+
+---
+// Check that unbalanced brackets are not included in links.
+#[https://example.com/] \
+https://example.com/)
+
+---
+// Verify that opening brackets without closing brackets throw an error.
+// Error: 22-22 expected closing bracket in link
+https://exam(ple.com/
+
+---
// Styled with underline and color.
#show link: it => underline(text(fill: rgb("283663"), it))
You could also make the