Mercurial > hgrepos > Python > libs > pygments-lexer-pseudocode2
diff pygments_lexer_pseudocode2/lexers/algpseudocode.py @ 164:a4317957148b
Move all lexers into a subpackage pygments_lexer_pseudocode2.lexers.
This is to prepare for a new subpackage with filters.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Fri, 08 May 2026 21:19:54 +0200 |
| parents | pygments_lexer_pseudocode2/algpseudocode.py@11ce0903ff8b |
| children | 33a722c8ae17 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pygments_lexer_pseudocode2/lexers/algpseudocode.py Fri May 08 21:19:54 2026 +0200 @@ -0,0 +1,691 @@ +# -*- 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.lexers.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(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(Generic.Error, "\\")), + ], + "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(Generic.Error, "\\")), + 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, "\\")), # in text-mode: leave 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, "\\")), # in text-mode: leave 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 "
