changeset 162:11ce0903ff8b

Yield lone backslash characters in expressions that not really escape anything as "Generic.Error" now. In text-mode do this not.
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 08 May 2026 17:58:50 +0200
parents 00a432d14508
children 315cfe0a836f
files docs/details-algpseudocode.rst pygments_lexer_pseudocode2/algpseudocode.py tests/test_algpseudo.py
diffstat 3 files changed, 18 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/docs/details-algpseudocode.rst	Fri May 08 17:57:56 2026 +0200
+++ b/docs/details-algpseudocode.rst	Fri May 08 17:58:50 2026 +0200
@@ -175,6 +175,10 @@
   of space or TAB characters.
   This is true for required and optional parameters.
 
+.. todo:: Escaping
+
+          A single backslash is a Generic.Error token
+
 
 With Required Parameters
 ~~~~~~~~~~~~~~~~~~~~~~~~
--- a/pygments_lexer_pseudocode2/algpseudocode.py	Fri May 08 17:57:56 2026 +0200
+++ b/pygments_lexer_pseudocode2/algpseudocode.py	Fri May 08 17:58:50 2026 +0200
@@ -346,14 +346,14 @@
             (r"\}", LexBase.op_ignore, "#pop"),
             (r"\\\}", LexBase.op_fixed(Name.Entity, "}")),
             (r"\\\\", LexBase.op_fixed(Name.Entity, "\\")),
-            (r"\\", LexBase.op_fixed(Name.Entity, "\\")),
+            (r"\\", LexBase.op_fixed(Generic.Error, "\\")),
         ],
         "entity-name-end": [  # may be multiline -- suppressed if no_end
             (r"[^\\}]+", op_opt_ignore(Name.Entity)),
             (r"\}", LexBase.op_ignore, "#pop"),
             (r"\\\}", op_opt_ignore_or_fixed(Name.Entity, "}")),
             (r"\\\\", op_opt_ignore_or_fixed(Name.Entity, "\\")),
-            (r"\\", op_opt_ignore_or_fixed(Name.Entity, "\\")),
+            (r"\\", op_opt_ignore_or_fixed(Generic.Error, "\\")),
         ],
         "expr": [
             include("math-symbols"),          # must be before punctuation
@@ -394,7 +394,7 @@
             (r"\n", Whitespace),
             include("expr-in-braces"),
             (r"\\\\", LexBase.op_fixed(Text, "\\")),
-            (r"\\", LexBase.op_fixed(Text, "\\")),
+            (r"\\", LexBase.op_fixed(Generic.Error, "\\")),
             include("unicode-separators"),
             include("unicode-other"),
             (r"[^\S\n]+", Text),
@@ -411,7 +411,7 @@
             include("explicit-tokentype"),
             include("remark"),
             (r"\\\\", LexBase.op_fixed(Text, "\\")),
-            (r"\\", LexBase.op_fixed(Text, "\\")),
+            (r"\\", LexBase.op_fixed(Text, "\\")),  # in text-mode: leave Text
             (r".", Error),
         ],
         "text-in-expr": [
@@ -425,7 +425,7 @@
             include("explicit-tokentype"),
             include("remark"),
             (r"\\\\", LexBase.op_fixed(Text, "\\")),
-            (r"\\", LexBase.op_fixed(Text, "\\")),
+            (r"\\", LexBase.op_fixed(Text, "\\")),  # in text-mode: leave Text
             (r".", Error),
         ],
         "math-builtins": [
--- a/tests/test_algpseudo.py	Fri May 08 17:57:56 2026 +0200
+++ b/tests/test_algpseudo.py	Fri May 08 17:58:50 2026 +0200
@@ -165,7 +165,7 @@
             [("Keyword", "PROCEDURE"),
              ("Text.Whitespace", " "),
              ("Name.Entity", "t"),
-             ("Name.Entity", "\\"),
+             ("Generic.Error", "\\"),
              ("Name.Entity", "he "),
              ("Name.Entity", "\\"),
              ("Name.Entity", "}"),
@@ -259,7 +259,7 @@
         self.assertTokenStreamEqualComplete(
             [("Keyword", "FUNCTION"),
              ("Text.Whitespace", " "),
-             ("Name.Entity", "\\"),
+             ("Generic.Error", "\\"),
              ("Name.Entity", "n"),
              ("Name.Entity", "}"),
              ("Text.Whitespace", "\n"),
@@ -270,12 +270,13 @@
         self.assertTokenStreamEqualComplete(
             [("Keyword", "CLASS"),
              ("Text.Whitespace", " "),
+             ("Generic.Error", "\\"),
+             ("Name.Entity", "n"),
              ("Name.Entity", "\\"),
-             ("Name.Entity", "n"),
              ("Name.Entity", "}"),
              ("Text.Whitespace", "\n"),
              ],
-            pygments.lex(r"\CLASS {\n\}}", self.lexer))
+            pygments.lex(r"\CLASS {\n\\\}}", self.lexer))
 
     def test_class_fr(self):
         lexer = pygments.lexers.load_lexer_from_file(
@@ -283,7 +284,7 @@
         self.assertTokenStreamEqualComplete(
             [("Keyword", "CLASSE"),
              ("Text.Whitespace", " "),
-             ("Name.Entity", "\\"),
+             ("Generic.Error", "\\"),
              ("Name.Entity", "n"),
              ("Name.Entity", "}"),
              ("Text.Whitespace", "\n"),
@@ -302,7 +303,7 @@
              ("Text.Whitespace", "\n"),
              ("Text.Whitespace", "\n"),
              ],
-            pygments.lex("\\CLASS {\\n\\}}\n\\ENDCLASS", lexer))
+            pygments.lex("\\CLASS {\\\\n\\}}\n\\ENDCLASS", lexer))
 
     def test_class_de_with_noend_option_and_name(self):
         lexer = pygments.lexers.load_lexer_from_file(
@@ -310,7 +311,7 @@
         self.assertTokenStreamEqualComplete(
             [("Keyword", "KLASSE"),
              ("Text.Whitespace", " "),
-             ("Name.Entity", "\\"),
+             ("Generic.Error", "\\"),
              ("Name.Entity", "n"),
              ("Name.Entity", "}"),
              ("Text.Whitespace", "\n"),
@@ -1029,7 +1030,7 @@
             [("Punctuation", "...."),
              ("Text.Whitespace", "\n"),
              ],
-            pygments.lex(r"....", self.lexer))        
+            pygments.lex(r"....", self.lexer))
 
 
 class PygmentizeCompletely(unittest.TestCase):