Mercurial > hgrepos > Python > libs > pygments-lexer-pseudocode2
view pygments_lexer_pseudocode2/algpseudocode.py @ 160:b4028838e0c8
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".
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Fri, 08 May 2026 17:46:28 +0200 |
| parents | 4ee0b1536ea6 |
| children | 00a432d14508 |
line wrap: on
line source
# -*- coding: utf-8 -*- # :- # SPDX-FileCopyrightText: © 2026 Franz Glasner # SPDX-License-Identifier: MIT # :- r"""A pseudocode lexer along the lines of CTAN's algpseudocode or algpseudocodex. """ __all__ = ["AlgPseudocodeLexer", "AlgPseudocodeLexer_DE", "AlgPseudocodeLexer_FR"] import logging import re import pygments.util from pygments.lexer import bygroups, include, words from pygments.token import (Comment, Error, Generic, Keyword, Name, Operator, Punctuation, Text, Whitespace) # # Relative imports do not work with pygments.lexers.load_lexer_from_file() # in all of our supported Python releases. # from pygments_lexer_pseudocode2.bases import LexBase from pygments_lexer_pseudocode2.utils import REVERSED_STANDARD_TYPES from pygments_lexer_pseudocode2 import uniprops # # As in the local imports: use an explicit name because __name__ is # __builtins__ # _logger = logging.getLogger("pygments_lexer_pseudocode2.algpseudocode") class AlgPseudocodeLexer(LexBase): """A pseudocode lexer along the lines of CTAN's algpseudocode or algpseudocodex. Some ideas (e.g. strings) are borrowed from Pygment's Python lexer. """ name = "AlgPseudocode" aliases = ["algpseudocode", "algpseudo"] filenames = ["*.algpseudo", "*.algpseudocode"] mimetypes = [] flags = re.MULTILINE LANG = "en" TRANSLATIONS = { "PROG": "PROGRAM", "PROGRAM": "PROGRAM", "ALGO": "ALGORITHM", "ALGORITHM": "ALGORITHM", "PROC": "PROCEDURE", "PROCEDURE": "PROCEDURE", "FUNC": "FUNCTION", "FUNCTION": "FUNCTION", "FN": "FUNCTION", "CLASS": "CLASS", "INPUT": "Input:", "INPUTS": "Inputs:", "OUTPUT": "Output:", "OUTPUTS": "Outputs:", "RETURNS": "Returns:", "ENSURE": "Ensure:", "REQUIRE": "Require:", "IS": "IS", "WITH": "WITH", "IF": "IF", "THEN": "THEN", "ELSE": "ELSE", "ELSEIF": "ELSE IF", "ELSIF": "ELSE IF", "ELIF": "ELSE IF", "DO": "DO", # in WHILE ... DO "WHILE": "WHILE", "FOR": "FOR", "FORALL": "FOR ALL", "FROM": "FROM", "TO": "TO", "IN": "IN", # as in FOR ... IN "STEP": "STEP", "LOOP": "LOOP", "REPEAT": "REPEAT", "UNTIL": "UNTIL", "RETURN": "RETURN", "BEGIN": "BEGIN", "END": "END", # not in END_TRANSLATIONS } END_TRANSLATIONS = { "PROG": "END OF PROGRAM", "PROGRAM": "END OF PROGRAM", "ALGO": "END OF ALGORITHM", "ALGORITHM": "END OF ALGORITHM", "PROC": "END OF PROCEDURE", "PROCEDURE": "END OF PROCEDURE", "FUNC": "END OF FUNCTION", "FUNCTION": "END OF FUNCTION", "FN": "END OF FUNCTION", "CLASS": "END OF CLASS", "IF": "END IF", "WHILE": "END WHILE", "FOR": "END FOR", "FORALL": "END FOR ALL", "LOOP": "END LOOP", } DEFAULT_END_PREFIX = "END OF " SYMBOL_REMARK = u"▷" # U+25B7: Unicode 1.0 (Geometric Shapes) # SYMBOL_REMARK = u"▻" # U+25BB: Unicode 1.0 (Geometric Shapes) # SYMBOL_REMARK = u"⍝" # U+235D: Unicode 1.1 (Misc. Technical, APL) SYMBOL_BLOCK = u"◆" # U+25C6: Unicode 1.0 (Geometric Shapes) # SYMBOL_BLOCK = u"┃" # U+2503: Unicode 1.0 (Bow Drawing) # SYMBOL_BLOCK = u"●" # U+25CF: Unicode 1.0 (Geometric Shapes) SYMBOL_TEXTSTATEMENT = u"▪" # U+25AA: Unicode 1.0 (Geometric Shapes) # SYMBOL_TEXTSTATEMENT = u"■" # U+25A0: Unicode 1.0 (Geometric Shapes) SYMBOLS = { # Group REMARK "REMARK": SYMBOL_REMARK, "REM": SYMBOL_REMARK, # Group STATEMENT "STATEMENT": SYMBOL_BLOCK, "STATE": SYMBOL_BLOCK, "BLOCK": SYMBOL_BLOCK, # Group TEXTSTATEMENT "TEXTSTATEMENT": SYMBOL_TEXTSTATEMENT, "TEXTSTATE": SYMBOL_TEXTSTATEMENT, "TSTATEMENT": SYMBOL_TEXTSTATEMENT, "TSTATE": SYMBOL_TEXTSTATEMENT, "TEXTBLOCK": SYMBOL_TEXTSTATEMENT, "TBLOCK": SYMBOL_TEXTSTATEMENT, "<-": u"⟵", # U+27F5: Unicode 3.2 (Supplemental Arrows-A) "->": u"⟶", # U+27F6: Unicode 3.2 (Supplemental Arrows-A) "<->": u"⟷", # U+27F7: Unicode 3.2 (Supplemental Arrows-A) # "=>": u"⟹", # U+27F9: Unicode 3.2 (Supplemental Arrows-A) # "<=>": u"⟺", # U+27FA: Unicode 3.2 (Supplemental Arrows-A) # "<-": u"←", # U+2190: Unicode 1.0 (Arrows) # "->": u"→", # U+2192: Unicode 1.0 (Arrows) # "<->": u"↔", # U+2194: Unicode 1.0 (Arrows) "=>": u"⇒", # U+21D2: Unicode 1.0 (Arrows) "<=>": u"⇔", # U+21D4: Unicode 1.0 (Arrows) "<=": u"≤", # U+2264: Unicode 1.0 (Mathematical Operators) ">=": u"≥", # U+2265: Unicode 1.0 (Mathematical Operators) "<>": u"≠", # U+2260: Unicode 1.0 (Mathematical Operators) "!=": u"≠", # U+2260: Unicode 1.0 (Mathematical Operators) ":=": u"∶=", # "≔" U+2254 not recognizable in my (small) mono font "=:": u"=∶", # "≕" U+2255 not recognizable in my (small) mono font "?=": u"≟", # U+225F: Unicode 1.0 (Mathematical Operators) } def op_translate(toktype): def _op_translate(lexer, match, ctx=None): kw = match.group().upper() yield match.start(), toktype, lexer.TRANSLATIONS.get(kw, kw) if ctx: ctx.pos = match.end() return _op_translate def op_opt_end_translate(toktype): def _op_end_translate(lexer, match, ctx=None): if not lexer.no_end: kw = match.group().upper() yield (match.start(), toktype, lexer.END_TRANSLATIONS.get( kw, lexer.DEFAULT_END_PREFIX + kw)) if ctx: ctx.pos = match.end() return _op_end_translate def op_opt_ignore(toktype): def _op_opt_ignore(lexer, match, ctx=None): if not lexer.no_end: yield match.start(), toktype, match.group() if ctx: ctx.pos = match.end() return _op_opt_ignore def op_opt_ignore_or_fixed(toktype, value): """Yield a fixed given token type and value or -- if the lexer's `no_end` setting evals to ``True`` nothing. """ def _op_opt_ignore_or_fixed(lexer, match, ctx=None): if not lexer.no_end: yield match.start(), toktype, value if ctx: ctx.pos = match.end() return _op_opt_ignore_or_fixed def op_gets(lexer, match, ctx=None): yield match.start(), Operator, lexer.symbol_gets def op_remark(lexer, match, ctx=None): yield match.start(), Comment.Single, lexer.symbol_remark def op_symbol(toktype): def _op_symbol(lexer, match, ctx=None): kw = match.group().upper() yield match.start(), toktype, lexer.SYMBOLS.get(kw, kw) if ctx: ctx.pos = match.end() return _op_symbol def op_explicit_tokentype(lexer, match, ctx=None): needed_css = match.group("type") toktype = REVERSED_STANDARD_TYPES.get(needed_css, None) if toktype is None: # Be more error friendly toktype = Generic.Error val = match.group() _logger.warning("Unhandled explicit token type: %s", val) else: val = match.group("character") yield match.start(), toktype, val if ctx: ctx.pos = match.end() tokens = { "root": [ (r"\n", Whitespace), (r"/\*", Comment.Multiline, "multiline-nested-comment"), (r"\(\*", Comment.Multiline, "multiline-nested-comment-alt"), (r"(//|#).*$", Comment.Single), include("remark"), (r"(?i)\\(block|state(?:ment)?)[ \t]*(\{)", bygroups(op_symbol(Text), LexBase.op_fixed(Whitespace, " ")), "block-expr"), (r"(?i)\\(" r"(?:textstate(?:ment)?)" r"|(?:tstate(?:ment)?)" r"|(?:textblock)" r"|(?:tblock)" r")[ \t]*(\{)", bygroups(op_symbol(Text), LexBase.op_fixed(Whitespace, " ")), "text-statement"), (r"(?i)\\(" r"(?:input(?:s)?)" r"|(?:output(?:s)?)" r"|(?:ensure)" r"|(?:require)" r"|(?:returns)" r")[ \t]*(\{)", bygroups(op_translate(Keyword), LexBase.op_fixed(Whitespace, " ")), "text-statement"), (r"(?i)\\(" r"(?:if)" r"|(?:then)" r"|(?:else)" r"|(?:el(?:s(?:e)?)?if)" r"|(?:do)" # as in WHILE ... DO not DO ... UNTIL r"|(?:while)" r"|(?:forall)" r"|(?:for)" r"|(?:from)" r"|(?:to)" r"|(?:step)" r"|(?:in)" r"|(?:loop)" r"|(?:repeat)" r"|(?:until)" r"|(?:return)" r")\b", bygroups(op_translate(Keyword))), (r"\\\n", Text), (r"(?i)\\(" r"(?:prog(?:ram)?)" r"|(?:algo(?:rithm)?)" r"|(?:proc(?:edure)?)" r"|(?:func(?:tion)?|(?:fn))" r"|(?:class)" r")[ \t]*(\{)", bygroups(op_translate(Keyword), LexBase.op_fixed(Whitespace, " ")), "entity-name"), # ENDxxx keywords with optional entity name in two parts: # 1. with name (r"(?i)\\end(?:[_\-]|(?:[ \t]+))?(" r"(?:prog(?:ram)?)" r"|(?:algo(?:rithm)?)" r"|(?:proc(?:edure)?)" r"|(?:func(?:tion)?)" r"|(?:fn)" r"|(?:class)" r")(?:[_\-]|(?:[\t ]+))?(\{)", bygroups(op_opt_end_translate(Keyword), op_opt_ignore_or_fixed(Whitespace, " ")), "entity-name-end"), # 2. without name # 3. AND keywords that do not allow a param (e.g. endif) (r"(?i)\\end(?:[_\-]|(?:[ \t]+))?(" r"(?:prog(?:ram)?)" r"|(?:algo(?:rithm)?)" r"|(?:proc(?:edure)?)" r"|(?:func(?:tion)?)" r"|(?:fn)" r"|(?:class)" r"|(?:if)" r"|(?:while)" r"|(?:for)" r"|(?:forall)" r"|(?:loop)" r")\b", bygroups(op_opt_end_translate(Keyword))), # # A single begin or end that is never suppressed because # it is supposed to be paired with begin # (r"(?i)\\(begin|end)\b", bygroups(op_translate(Keyword))), # Keywords (r"(?i)\\(" r"(?:is)" r"|(?:with)" r")\b", bygroups(op_translate(Keyword))), include("expr"), include("unicode-separators"), include("unicode-other"), (r"[^\S\n]+", Text), # (r".", Generic.Error), # tolerance for errors (r".", Error), ], "remark": [ (r"(?i)\\(remark|rem)\b(.*)$", bygroups(op_remark, Comment.Single)), ], "entity-name": [ # may be multiline (r"[^\\}]+", Name.Entity), (r"\}", LexBase.op_ignore, "#pop"), (r"\\\}", LexBase.op_fixed(Name.Entity, "}")), (r"\\\\", LexBase.op_fixed(Name.Entity, "\\")), (r"\\", LexBase.op_fixed(Name.Entity, "\\")), ], "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, "\\")), ], "expr": [ include("math-symbols"), # must be before punctuation include("ascii-punctuation"), include("unicode-punctuation"), include("escaped-string-start"), include("py-strings"), include("py-numbers"), (r"(?i)\\(call|name)[ \t]*(\{)", LexBase.op_ignore, "entity-name"), (r"(?i)\\gets\b", op_gets), (r"(?i)\\text[ \t]*\{", LexBase.op_ignore, "text-in-expr"), include("explicit-tokentype"), include("remark"), include("keyword-constants"), include("word-operators"), include("math-builtins"), include("py-name"), ], "expr-in-braces": [ include("math-symbols"), # must be before punctuation include("ascii-punctuation-in-braces"), include("unicode-punctuation"), include("escaped-string-start"), include("py-strings"), include("py-numbers"), (r"(?i)\\(call|name)[ \t]*(\{)", LexBase.op_ignore, "entity-name"), (r"(?i)\\gets\b", op_gets), (r"(?i)\\text[ \t]*\{", LexBase.op_ignore, "text-in-expr"), include("explicit-tokentype"), include("remark"), include("keyword-constants"), include("word-operators"), include("math-builtins"), include("py-name"), ], "block-expr": [ # somewhat similar to "root" (r"\}", LexBase.op_ignore, "#pop"), (r"\n", Whitespace), include("expr-in-braces"), (r"\\\\", LexBase.op_fixed(Text, "\\")), (r"\\", LexBase.op_fixed(Text, "\\")), include("unicode-separators"), include("unicode-other"), (r"[^\S\n]+", Text), (r".", Error), ], "text-statement": [ # like block but default to text-mode (r"[^\\}\n]+", Text), (r"\}", LexBase.op_ignore, "#pop"), (r"\n", Whitespace), (r"\\\}", LexBase.op_fixed(Text, "}")), (r"(?i)\\expr(?:ession)?[ \t]*\{", LexBase.op_ignore, "block-expr"), include("explicit-tokentype"), include("remark"), (r"\\\\", LexBase.op_fixed(Text, "\\")), (r"\\", LexBase.op_fixed(Text, "\\")), (r".", Error), ], "text-in-expr": [ (r"[^\\}\n]+", Text), (r"\}", LexBase.op_ignore, "#pop"), (r"\n", Whitespace), (r"\\\}", LexBase.op_fixed(Text, "}")), (r"(?i)\\expr(?:ession)?[ \t]*\{", LexBase.op_ignore, "block-expr"), include("explicit-tokentype"), include("remark"), (r"\\\\", LexBase.op_fixed(Text, "\\")), (r"\\", LexBase.op_fixed(Text, "\\")), (r".", Error), ], "math-builtins": [ (words(("sqrt", "pow", "cos", "sin", "tan", "arcos", "arcsin", "arctan", "arctan2", "mod", "exp", "ln", "log", "min", "max"), prefix=r"(?<!\.)", suffix=r"\b"), Name.Builtin), ], "math-symbols": [ (r"<=>|<->|<-|->|=>|<=|>=|<>|!=|:=|=:|\?=", op_symbol(Operator)), (r"[!&<>=+\-*/%|~]", Operator), # ASCII (u"[%s]" % (uniprops.Sm,), Operator), # other Unicode ], "word-operators": [ (words(("IN", "In", "in", "IS", "Is", "is", "AND", "And", "and", "OR", "Or", "or", "XOR", "Xor", "xor", "NOT", "Not", "not"), prefix=r"(?<!\.)", suffix=r"\b"), Operator.Word), ], "keyword-constants": [ (words(("True", "TRUE", "true", "False", "FALSE", "false", "None", "NONE", "none", "Nil", "NIL", "nil", "Null", "NULL", "null", "Empty", "EMPTY", "empty"), prefix=r"(?<!\.)", suffix=r"\b"), Keyword.Constant), ], "ascii-punctuation": [ (r"\.+", Punctuation), (r"[{}:(),;[\]?@]", Punctuation), ], "ascii-punctuation-in-braces": [ # # Like "punctuation" but needs an escaped curly brace for } because # a single closing curly brace pops the current state here. # (r"\\\}", LexBase.op_fixed(Punctuation, "}")), (r"[{:(),;[\]?@]", Punctuation), ], "unicode-separators": [ (u"[%s]" % (uniprops.Zl,), Whitespace), (u"[%s]" % (uniprops.Zp,), Whitespace), (u"[%s]" % (uniprops.Zs,), Whitespace), ], "unicode-punctuation": [ (u"[%s]" % (uniprops.Pc,), Punctuation), (u"[%s]" % (uniprops.Pd,), Punctuation), (u"[%s]" % (uniprops.Ps,), Punctuation), (u"[%s]" % (uniprops.Pe,), Punctuation), (u"[%s]" % (uniprops.Pi,), Punctuation), (u"[%s]" % (uniprops.Pf,), Punctuation), (u"[%s]" % (uniprops.Po,), Punctuation), ], "unicode-other": [ (u"[%s]" % (uniprops.Sc,), Text), # Currency (u"[%s]" % (uniprops.So,), Text), # Other symbols ], "escaped-string-start": [ (r"""\\(['"])""", bygroups(Punctuation)), ], "explicit-tokentype": [ # All these REs are CASE-SENSITIVE! # Multiple characters possible, but no escaping! (r"\\ttx\-(?P<type>[a-zA-Z0-9_-]+?)(?P<sep>[/:|=*+!\$~])" r"(?P<character>(.|\n)+?)(?P=sep)", op_explicit_tokentype), (r"\\ttx\-(?P<type>[a-zA-Z0-9_-]+?)\{(?P<character>[^}]+?)\}", op_explicit_tokentype), (r"\\ttx\-(?P<type>[a-zA-Z0-9_-]+?)\((?P<character>[^)]+?)\)", op_explicit_tokentype), (r"\\ttx\-(?P<type>[a-zA-Z0-9_-]+?)<(?P<character>[^>]+?)>", op_explicit_tokentype), (r"\\ttx\-(?P<type>[a-zA-Z0-9_-]+?)\[(?P<character>[^\]]+?)\]", op_explicit_tokentype), # Every character is possible: no escaping needed! (r"\\tt-(?P<type>[^/]+?)/(?P<character>(?:.|\n))", op_explicit_tokentype), ], } def __init__(self, **options): self.no_end = pygments.util.get_bool_opt( options, "no_end", default=False) self.symbol_gets = options.get("gets", None) if self.symbol_gets is None: self.symbol_gets = self.SYMBOLS["<-"] # Default: "⟵" # U+27F5 self.symbol_remark = options.get("remark", None) 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): """ .. seealso:: - https://de.wikipedia.org/wiki/Pseudocode .. todo:: Complete german translations """ name = "AlgPseudocodeDE" aliases = ["algpseudocode-de", "algpseudo-de"] filenames = ["*.algpseudo-de", "*.algpseudocode-de"] LANG = "de" TRANSLATIONS = AlgPseudocodeLexer.TRANSLATIONS.copy() TRANSLATIONS.update({ "PROG": "PROGRAMM", "PROGRAM": "PROGRAMM", "ALGO": "ALGORITHMUS", "ALGORITHM": "ALGORITHMUS", "PROC": "PROZEDUR", "PROCEDURE": "PROZEDUR", "FUNC": "FUNKTION", "FUNCTION": "FUNKTION", "FN": "FUNKTION", "CLASS": "KLASSE", "IS": "IST", "WITH": "MIT", "IF": "WENN", "THEN": "DANN", "ELSE": "ANDERNFALLS", "ELSEIF": "ANDERNFALLS WENN", "ELSIF": "ANDERNFALLS WENN", "ELIF": "ANDERNFALLS WENN", # "DO": # XXX TBD # in WHILE WHILE ... DO # noqa # in WHILE ... DO "WHILE": "SOLANGE", "FOR": "FÜR", "FORALL": "FÜR ALLE", "FROM": "VON", "TO": "BIS", "IN": "IN", "STEP": "SCHRITTWEITE", # "LOOP": XXX TBD # noqa "REPEAT": "WIEDERHOLE", "UNTIL": "BIS", # "RETURN": XXX TBD # noqa "BEGIN": "START", "END": "ENDE", }) END_TRANSLATIONS = AlgPseudocodeLexer.END_TRANSLATIONS.copy() END_TRANSLATIONS.update({ "PROG": "ENDE DES PROGRAMMS", "PROGRAM": "ENDE DES PROGRAMMS", "ALGO": "ENDE DES ALGORITHMUS", "ALGORITHM": "ENDE DES ALGORITHMUS", "PROC": "ENDE DER PROZEDUR", "PROCEDURE": "ENDE DER PROZEDUR", "FUNC": "ENDE DER FUNKTION", "FUNCTION": "ENDE DER FUNKTION", "FN": "ENDE DER FUNKTION", "CLASS": "ENDE DER KLASSE", "IF": "ENDE WENN", "WHILE": "ENDE SOLANGE", "FOR": "ENDE FÜR", "FORALL": "ENDE FÜR ALLE", # "LOOP": "ENDE XXX", # XXX TBD # noqa }) DEFAULT_END_PREFIX = "ENDE VON " class AlgPseudocodeLexer_FR(AlgPseudocodeLexer): """ .. seealso:: - https://info.blaisepascal.fr/pseudo-code/ - https://fr.wikipedia.org/wiki/Pseudo-code - https://fr.wikipedia.org/wiki/Structure_de_contr%C3%B4le .. todo:: Complete french translations """ name = "AlgPseudocodeFR" aliases = ["algpseudocode-fr", "algpseudo-fr"] filenames = ["*.algpseudo-fr", "*.algpseudocode-fr"] LANG = "fr" TRANSLATIONS = AlgPseudocodeLexer.TRANSLATIONS.copy() TRANSLATIONS.update({ "PROG": "PROGRAMME", "PROGRAM": "PROGRAMME", "ALGO": "ALGORITHME", "ALGORITHM": "ALGORITHME", "PROC": "PROCÉDURE", "PROCEDURE": "PROCÉDURE", "FUNC": "FONCTION", "FUNCTION": "FOUNCTION", "FN": "FONCTION", "CLASS": "CLASSE", "IS": "EST", "WITH": "AVEC", "IF": "SI", "THEN": "ALORS", "ELSE": "SINON", "ELSEIF": "SINONSI", "ELSIF": "SINONSI", "ELIF": "SINONSI", "DO": "FAIRE", # as in in WHILE ... DO (not DO ... UNTIL) "WHILE": "TANTQUE", "FOR": "POUR", "FORALL": "POUR CHAQUE", "FROM": "DE", "TO": "JUSQU'À", # or just "À", "IN": "DANS", # as in FOR ... IN "STEP": "PAR PAS DE", "LOOP": "BOUCLE", # XXX FIXME??? "REPEAT": "RÉPÉTER", "UNTIL": "JUSQUACEQUE", "RETURN": "RENVOYER", "BEGIN": "DÉBUT", "END": "FIN", }) END_TRANSLATIONS = AlgPseudocodeLexer.END_TRANSLATIONS.copy() END_TRANSLATIONS.update({ "PROG": "FIN DE PROGRAMME", "PROGRAM": "FIN DE PROGRAMME", "ALGO": "FIN D'ALGORITHME", "ALGORITHM": "FIN D'ALGORITHME", "PROC": "FIN DE PROCÉDURE", "PROCEDURE": "FIN DE PROCÉDURE", "FUNC": "FIN DE FONCTION", "FUNCTION": "FIN DE FOUNCTION", "FN": "FIN DE FONCTION", "CLASS": "FIN DE CLASSE", "SI": "FIN SI", "FOR": "FIN POUR", "FORALL": "FIN POUR CHAQUE", "WHILE": "FIN TANTQUE", "LOOP": "FIN BOUCLE", }) DEFAULT_END_PREFIX = "FIN DE "
