diff --git a/CHANGES b/CHANGES index b914fd133b..3e8c8ce57a 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Version 2.20.0 * LESS: Support single-line comments (#3005) * LilyPond: Update to 2.25.29 (#2974) * Python: Add ``t``-string support (#3009, #3010) + * TOML: Support TOML 1.1.0 (#3026) - Drop Python 3.8, and add Python 3.14 as a supported version (#2987, #3012) diff --git a/pygments/lexers/configs.py b/pygments/lexers/configs.py index 5e7f47b6dd..71079134af 100644 --- a/pygments/lexers/configs.py +++ b/pygments/lexers/configs.py @@ -1127,7 +1127,7 @@ class TOMLLexer(RegexLexer): # Based on the TOML spec: https://toml.io/en/v1.0.0 # The following is adapted from CPython's tomllib: - _time = r"\d\d:\d\d:\d\d(\.\d+)?" + _time = r"\d\d:\d\d(:\d\d(\.\d+)?)?" _datetime = rf"""(?x) \d\d\d\d-\d\d-\d\d # date, e.g., 1988-10-27 ( @@ -1238,9 +1238,9 @@ class TOMLLexer(RegexLexer): default('value'), ], 'inline-table': [ - # Note that unlike inline arrays, inline tables do not - # allow newlines or comments. - (r'[ \t]+', Whitespace), + # Whitespace (since TOML 1.1.0, same as in array) + (r'\s+', Whitespace), + (r'#.*', Comment.Single), # Keys include('key'), @@ -1275,7 +1275,7 @@ class TOMLLexer(RegexLexer): (r"'", String.Single), ], 'escapes': [ - (r'\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}', String.Escape), + (r'\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}', String.Escape), (r'\\.', String.Escape), ], } diff --git a/tests/snippets/toml/toml-1.1.0.txt b/tests/snippets/toml/toml-1.1.0.txt new file mode 100644 index 0000000000..987e5815a5 --- /dev/null +++ b/tests/snippets/toml/toml-1.1.0.txt @@ -0,0 +1,93 @@ +---input--- +["toml 1.1.0 features"] +tbl = { + key = "a string", + moar-tbl = { + key = 1, + }, +} + +null = "null byte: \x00; letter a: \x61" +csi = "\e[" + +dt = 2010-02-03 14:15 +t = 14:15 + +---tokens--- +'[' Keyword +'"' Literal.String.Double +'toml 1.1.0 features' Literal.String.Double +'"' Literal.String.Double +']' Keyword +'\n' Text.Whitespace + +'tbl' Name +' ' Text.Whitespace +'=' Operator +' ' Text.Whitespace +'{' Punctuation +'\n ' Text.Whitespace +'key' Name +' ' Text.Whitespace +'=' Punctuation +' ' Text.Whitespace +'"' Literal.String.Double +'a string' Literal.String.Double +'"' Literal.String.Double +',' Punctuation +'\n ' Text.Whitespace +'moar-tbl' Name +' ' Text.Whitespace +'=' Punctuation +' ' Text.Whitespace +'{' Punctuation +'\n ' Text.Whitespace +'key' Name +' ' Text.Whitespace +'=' Punctuation +' ' Text.Whitespace +'1' Literal.Number.Integer +',' Punctuation +'\n ' Text.Whitespace +'}' Punctuation +',' Punctuation +'\n' Text.Whitespace + +'}' Punctuation +'\n\n' Text.Whitespace + +'null' Name +' ' Text.Whitespace +'=' Operator +' ' Text.Whitespace +'"' Literal.String.Double +'null byte: ' Literal.String.Double +'\\x00' Literal.String.Escape +'; letter a: ' Literal.String.Double +'\\x61' Literal.String.Escape +'"' Literal.String.Double +'\n' Text.Whitespace + +'csi' Name +' ' Text.Whitespace +'=' Operator +' ' Text.Whitespace +'"' Literal.String.Double +'\\e' Literal.String.Escape +'[' Literal.String.Double +'"' Literal.String.Double +'\n\n' Text.Whitespace + +'dt' Name +' ' Text.Whitespace +'=' Operator +' ' Text.Whitespace +'2010-02-03 14:15' Literal.Date +'\n' Text.Whitespace + +'t' Name +' ' Text.Whitespace +'=' Operator +' ' Text.Whitespace +'14:15' Literal.Date +'\n' Text.Whitespace