URL special case for line comments

This commit is contained in:
Laurenz 2021-07-08 19:37:38 +02:00
parent 5a500fb8a7
commit f85e5aac64
5 changed files with 25 additions and 16 deletions

View File

@ -96,11 +96,6 @@ impl<'s> Scanner<'s> {
self.peek().map(f).unwrap_or(false) self.peek().map(f).unwrap_or(false)
} }
/// Checks whether the remaining source starts with the given string.
pub fn starts_with(&self, string: &str) -> bool {
self.rest().starts_with(string)
}
/// The previous index in the source string. /// The previous index in the source string.
pub fn last_index(&self) -> usize { pub fn last_index(&self) -> usize {
self.eaten() self.eaten()

View File

@ -72,9 +72,9 @@ impl<'s> Iterator for Tokens<'s> {
// Whitespace. // Whitespace.
c if c.is_whitespace() => self.whitespace(c), c if c.is_whitespace() => self.whitespace(c),
// Comments. // Comments with special case for URLs.
'/' if self.s.eat_if('/') => self.line_comment(),
'/' if self.s.eat_if('*') => self.block_comment(), '/' if self.s.eat_if('*') => self.block_comment(),
'/' if !self.maybe_in_url() && self.s.eat_if('/') => self.line_comment(),
'*' if self.s.eat_if('/') => Token::Invalid(self.s.eaten_from(start)), '*' if self.s.eat_if('/') => Token::Invalid(self.s.eaten_from(start)),
// Other things. // Other things.
@ -216,7 +216,7 @@ impl<'s> Tokens<'s> {
self.s.eat_assert(c); self.s.eat_assert(c);
Token::Text(&self.s.eaten_from(start)) Token::Text(&self.s.eaten_from(start))
} }
'u' if self.s.starts_with("u{") => { 'u' if self.s.rest().starts_with("u{") => {
self.s.eat_assert('u'); self.s.eat_assert('u');
self.s.eat_assert('{'); self.s.eat_assert('{');
Token::UnicodeEscape(UnicodeEscapeToken { Token::UnicodeEscape(UnicodeEscapeToken {
@ -367,7 +367,7 @@ impl<'s> Tokens<'s> {
// Read the fractional part if not already done. // Read the fractional part if not already done.
// Make sure not to confuse a range for the decimal separator. // Make sure not to confuse a range for the decimal separator.
if c != '.' && !self.s.starts_with("..") && self.s.eat_if('.') { if c != '.' && !self.s.rest().starts_with("..") && self.s.eat_if('.') {
self.s.eat_while(|c| c.is_ascii_digit()); self.s.eat_while(|c| c.is_ascii_digit());
} }
@ -464,6 +464,10 @@ impl<'s> Tokens<'s> {
Token::BlockComment(self.s.get(start .. end)) Token::BlockComment(self.s.get(start .. end))
} }
fn maybe_in_url(&self) -> bool {
self.mode == TokenMode::Markup && self.s.eaten().ends_with(":/")
}
} }
impl Debug for Tokens<'_> { impl Debug for Tokens<'_> {
@ -688,7 +692,6 @@ mod tests {
t!(Markup[" /"]: r"\a" => Text(r"\"), Text("a")); t!(Markup[" /"]: r"\a" => Text(r"\"), Text("a"));
t!(Markup[" /"]: r"\u" => Text(r"\"), Text("u")); t!(Markup[" /"]: r"\u" => Text(r"\"), Text("u"));
t!(Markup[" /"]: r"\1" => Text(r"\"), Text("1")); t!(Markup[" /"]: r"\1" => Text(r"\"), Text("1"));
t!(Markup[" /"]: r"\:" => Text(r"\"), Text(":"));
t!(Markup[" /"]: r#"\""# => Text(r"\"), Text("\"")); t!(Markup[" /"]: r#"\""# => Text(r"\"), Text("\""));
// Test basic unicode escapes. // Test basic unicode escapes.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 708 B

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -14,6 +14,11 @@ C/*
#test(type(/*1*/ 1) // #test(type(/*1*/ 1) //
, "integer") , "integer")
---
// Line comments have a special case for URLs.
https://example.com \
https:/* block comments don't ... */
--- ---
// End should not appear without start. // End should not appear without start.
// Error: 1:7-1:9 unexpected end of block comment // Error: 1:7-1:9 unexpected end of block comment

View File

@ -6,12 +6,6 @@
"repository": { "repository": {
"common": { "common": {
"patterns": [ "patterns": [
{
"name": "comment.line.double-slash.typst",
"begin": "//",
"end": "\n",
"beginCaptures": { "0": { "name": "punctuation.definition.comment.typst" } }
},
{ {
"name": "comment.block.typst", "name": "comment.block.typst",
"begin": "/\\*", "begin": "/\\*",
@ -38,6 +32,12 @@
"markup": { "markup": {
"patterns": [ "patterns": [
{ "include": "#common" }, { "include": "#common" },
{
"name": "comment.line.double-slash.typst",
"begin": "(?<!:)//",
"end": "\n",
"beginCaptures": { "0": { "name": "punctuation.definition.comment.typst" } }
},
{ {
"name": "constant.character.escape.content.typst", "name": "constant.character.escape.content.typst",
"match": "\\\\([\\\\/\\[\\]{}#*_=~`$-.]|u\\{[0-9a-zA-Z]*\\}?)" "match": "\\\\([\\\\/\\[\\]{}#*_=~`$-.]|u\\{[0-9a-zA-Z]*\\}?)"
@ -191,6 +191,12 @@
"code": { "code": {
"patterns": [ "patterns": [
{ "include": "#common" }, { "include": "#common" },
{
"name": "comment.line.double-slash.typst",
"begin": "//",
"end": "\n",
"beginCaptures": { "0": { "name": "punctuation.definition.comment.typst" } }
},
{ {
"name": "punctuation.separator.colon.typst", "name": "punctuation.separator.colon.typst",
"match": ":" "match": ":"