# HG changeset patch # User Franz Glasner # Date 1778255188 -7200 # Node ID b4028838e0c8ffc933a2a3b2f19d82925c8f13d1 # Parent 4ee0b1536ea663770074d6d46bca4e8a8c0968cc Implement lexer option "prohibit_raiseonerror_filter". Sphinx raises by default when an Error token is seen (by means of the "raiseonerror" filter that is applied by default to lexers in Sphinx). This option skips this and allows error locations to be seen and highlighted properly. While there convert most Generic.Error tokens to Error tokens because now they can be handled by a lexer with "prohibit_raiseonerror_filter=True". diff -r 4ee0b1536ea6 -r b4028838e0c8 docs/conf.py --- a/docs/conf.py Fri May 08 17:13:26 2026 +0200 +++ b/docs/conf.py Fri May 08 17:46:28 2026 +0200 @@ -92,3 +92,7 @@ # app.add_lexer("NoEndAlgPseudocode", functools.partial(AlgPseudocodeLexer, no_end=True)) + # For developing a lexer with smoother error handling + app.add_lexer("no-raiseonerror-algpseudocode", + functools.partial(AlgPseudocodeLexer, + prohibit_raiseonerror_filter=True)) diff -r 4ee0b1536ea6 -r b4028838e0c8 docs/details-algpseudocode.rst --- a/docs/details-algpseudocode.rst Fri May 08 17:13:26 2026 +0200 +++ b/docs/details-algpseudocode.rst Fri May 08 17:46:28 2026 +0200 @@ -10,6 +10,18 @@ Lexer Options ============= + .. describe:: prohibit_raiseonerror_filter + + **Type:** `bool` + + **Default:** `False` + + If ``True`` the `raiseonerror` filter is not allowed to be applied by + `Sphinx`_ when :py:meth:`Lexer.add_filter` is called. + + This setting does not apply to filters that are set by the standard + lexer option `filters`. + .. describe:: no_end **Type:** `bool` diff -r 4ee0b1536ea6 -r b4028838e0c8 pygments_lexer_pseudocode2/algpseudocode.py --- a/pygments_lexer_pseudocode2/algpseudocode.py Fri May 08 17:13:26 2026 +0200 +++ b/pygments_lexer_pseudocode2/algpseudocode.py Fri May 08 17:46:28 2026 +0200 @@ -17,7 +17,7 @@ import pygments.util from pygments.lexer import bygroups, include, words -from pygments.token import (Comment, Generic, Keyword, Name, Operator, +from pygments.token import (Comment, Error, Generic, Keyword, Name, Operator, Punctuation, Text, Whitespace) # @@ -334,7 +334,8 @@ include("unicode-separators"), include("unicode-other"), (r"[^\S\n]+", Text), - (r".", Generic.Error), # tolerance for errors + # (r".", Generic.Error), # tolerance for errors + (r".", Error), ], "remark": [ (r"(?i)\\(remark|rem)\b(.*)$", @@ -397,7 +398,7 @@ include("unicode-separators"), include("unicode-other"), (r"[^\S\n]+", Text), - (r".", Generic.Error), # tolerance for errors + (r".", Error), ], "text-statement": [ # like block but default to text-mode (r"[^\\}\n]+", Text), @@ -411,7 +412,7 @@ include("remark"), (r"\\\\", LexBase.op_fixed(Text, "\\")), (r"\\", LexBase.op_fixed(Text, "\\")), - (r".", Generic.Error), # tolerance for errors + (r".", Error), ], "text-in-expr": [ (r"[^\\}\n]+", Text), @@ -425,7 +426,7 @@ include("remark"), (r"\\\\", LexBase.op_fixed(Text, "\\")), (r"\\", LexBase.op_fixed(Text, "\\")), - (r".", Generic.Error), # tolerance for errors + (r".", Error), ], "math-builtins": [ (words(("sqrt", "pow", "cos", "sin", "tan", "arcos", "arcsin", @@ -525,6 +526,22 @@ if self.symbol_remark is None: self.symbol_remark = self.SYMBOLS["REM"] # Default: "▷" # U+25B7 LexBase.__init__(self, **options) + # + # Do this after calling the base because a "filters" option should be + # allowed to set **any** filter. + # + self.prohibit_raiseonerror_filter = pygments.util.get_bool_opt( + options, "prohibit_raiseonerror_filter", default=False) + + def add_filter(self, filter_, **options): + # + # May be called by Lexer.__init__ when self.prohibit_raiseonerror_filter + # is not yet set. This is intentionally so. + # + if getattr(self, "prohibit_raiseonerror_filter", False): + if filter_ in ("raiseonerror",): + return + LexBase.add_filter(self, filter_, **options) class AlgPseudocodeLexer_DE(AlgPseudocodeLexer):