Mercurial > hgrepos > Python > libs > pygments-lexer-pseudocode2
comparison pygments_lexer_pseudocode2/algpseudocode.py @ 53:39151225fb84
Rename the new pseudocode implementation to AlgPseudocode.
Because it is modelled after CTAN's algpseudocode(x).
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sun, 26 Apr 2026 19:16:23 +0200 |
| parents | pygments_lexer_pseudocode2/pseudocode.py@5bfa9113d3c4 |
| children | e8f4af9e20a8 |
comparison
equal
deleted
inserted
replaced
| 52:5bfa9113d3c4 | 53:39151225fb84 |
|---|---|
| 1 | |
| 2 # -*- coding: utf-8 -*- | |
| 3 # :- | |
| 4 # SPDX-FileCopyrightText: © 2026 Franz Glasner | |
| 5 # SPDX-License-Identifier: MIT | |
| 6 # :- | |
| 7 r"""A pseudocode lexer along the lines of CTAN's algpseudocode or | |
| 8 algpseudocodex. | |
| 9 | |
| 10 """ | |
| 11 | |
| 12 __all__ = ["AlgPseudocodeLexer", | |
| 13 "AlgPseudocodeLexer_DE", "AlgPseudocodeLexer_FR"] | |
| 14 | |
| 15 | |
| 16 import re | |
| 17 | |
| 18 from pygments.lexer import include, bygroups | |
| 19 from pygments.token import (Comment, Keyword, Name, Text, Whitespace) | |
| 20 | |
| 21 # | |
| 22 # Relative imports do not work with pygments.lexers.load_lexer_from_file() | |
| 23 # in all of our supported Python releases. | |
| 24 # | |
| 25 from pygments_lexer_pseudocode2.bases import LexBase | |
| 26 | |
| 27 | |
| 28 class AlgPseudocodeLexer(LexBase): | |
| 29 | |
| 30 """A pseudocode lexer along the lines of CTAN's algpseudocode or | |
| 31 algpseudocodex. | |
| 32 | |
| 33 Some ideas (e.g. strings) are borrowed from Pygment's Python lexer. | |
| 34 | |
| 35 """ | |
| 36 | |
| 37 name = "AlgPseudocode" | |
| 38 aliases = ["algpseudocode", "algpseudo"] | |
| 39 filenames = ["*.algpseudo", "*.algpseudocode"] | |
| 40 mimetypes = [] | |
| 41 flags = re.MULTILINE | |
| 42 | |
| 43 LANG = "en" | |
| 44 TRANSLATIONS = { | |
| 45 "PROG": "PROGRAM", | |
| 46 "PROGRAM": "PROGRAM", | |
| 47 "ALGO": "ALGORITHM", | |
| 48 "ALGORITHM": "ALGORITHM", | |
| 49 "PROC": "PROCEDURE", | |
| 50 "PROCEDURE": "PROCEDURE", | |
| 51 "FUNC": "FUNCTION", | |
| 52 "FUNCTION": "FUNCTION", | |
| 53 "FN": "FUNCTION", | |
| 54 "CLASS": "CLASS", | |
| 55 } | |
| 56 SYMBOLS = { | |
| 57 "REMARK": "▷", # U+25B7: Unicode 1.0 (Arrows) | |
| 58 "Remark": "▷", | |
| 59 "remark": "▷", | |
| 60 "REM": "▷", | |
| 61 "Rem": "▷", | |
| 62 "rem": "▷", | |
| 63 "R": "▷", | |
| 64 "r": "▷", | |
| 65 "BLOCK": "┃", # U+2503: Unicode 1.0 (Bow Drawing) | |
| 66 "Block": "┃", | |
| 67 "block": "┃", | |
| 68 } | |
| 69 | |
| 70 def op_translate(toktype): | |
| 71 | |
| 72 def _op_translate(lexer, match, ctx=None): | |
| 73 kw = match.group().upper() | |
| 74 yield match.start(), toktype, lexer.TRANSLATIONS.get(kw, kw) | |
| 75 | |
| 76 return _op_translate | |
| 77 | |
| 78 def op_symbol(toktype): | |
| 79 | |
| 80 def _op_symbol(lexer, match, ctx=None): | |
| 81 kw = match.group() | |
| 82 yield match.start(), toktype, lexer.SYMBOLS.get(kw, kw) | |
| 83 | |
| 84 return _op_symbol | |
| 85 | |
| 86 tokens = { | |
| 87 "root": [ | |
| 88 (r"\n", Whitespace), | |
| 89 (r"/\*", Comment.Multiline, "multiline-nested-comment"), | |
| 90 (r"//.*$", Comment.Single), | |
| 91 (r"(?:\\)(REMARK|Remark|remark|REM|Rem|rem|R|r)\b(.*)$", | |
| 92 bygroups(op_symbol(Comment.Single), Comment.Single)), | |
| 93 (r"(?:\\)(BLOCK|Block|block)\b(.*)$", | |
| 94 bygroups(op_symbol(Text), Text)), | |
| 95 (r"\\\n", Text), | |
| 96 (r"(?i)\\(" | |
| 97 r"(?:prog(?:ram)?)" | |
| 98 r"|(?:algo(?:rithm)?)" | |
| 99 r"|(?:proc(?:edure)?)" | |
| 100 r"|(?:func(?:tion)?|(?:fn))" | |
| 101 r"|(?:class)" | |
| 102 r")(\s*)(\{)", | |
| 103 bygroups(op_translate(Keyword), Whitespace, Name.Entity), | |
| 104 "entity-name"), | |
| 105 include("expr"), | |
| 106 (r"\s+", Text), | |
| 107 ], | |
| 108 "entity-name": [ # may be multiline | |
| 109 (r"[^\\}]+", Name.Entity), | |
| 110 (r"\\\}", Name.Entity), | |
| 111 (r"\\", Name.Entity), | |
| 112 (r"\}", Name.Entity, "#pop"), | |
| 113 ], | |
| 114 "expr": [ | |
| 115 include("py-strings"), | |
| 116 include("py-numbers"), | |
| 117 include("py-name"), | |
| 118 ] | |
| 119 } | |
| 120 | |
| 121 | |
| 122 class AlgPseudocodeLexer_DE(AlgPseudocodeLexer): | |
| 123 | |
| 124 name = "AlgPseudocodeDE" | |
| 125 aliases = ["algpseudocode-de", "algpseudo-de"] | |
| 126 filenames = ["*.algpseudo-de", "*.algpseudocode-de"] | |
| 127 | |
| 128 LANG = "de" | |
| 129 TRANSLATIONS = AlgPseudocodeLexer.TRANSLATIONS.copy() | |
| 130 TRANSLATIONS.update({ | |
| 131 "PROG": "PROGRAMM", | |
| 132 "PROGRAM": "PROGRAMM", | |
| 133 "ALGO": "ALGORITHMUS", | |
| 134 "ALGORITHM": "ALGORITHMUS", | |
| 135 "PROC": "PROZEDUR", | |
| 136 "PROCEDURE": "PROZEDUR", | |
| 137 "FUNC": "FUNKTION", | |
| 138 "FUNCTION": "FUNKTION", | |
| 139 "FN": "FUNKTION", | |
| 140 "CLASS": "KLASSE", | |
| 141 }) | |
| 142 | |
| 143 | |
| 144 class AlgPseudocodeLexer_FR(AlgPseudocodeLexer): | |
| 145 | |
| 146 name = "AlgPseudocodeFR" | |
| 147 aliases = ["algpseudocode-fr", "algpseudo-fr"] | |
| 148 filenames = ["*.algpseudo-fr", "*.algpseudocode-fr"] | |
| 149 | |
| 150 LANG = "de" | |
| 151 TRANSLATIONS = AlgPseudocodeLexer.TRANSLATIONS.copy() | |
| 152 TRANSLATIONS.update({ | |
| 153 "PROG": "PROGRAMME", | |
| 154 "PROGRAM": "PROGRAMME", | |
| 155 "ALGO": "ALGORITHME", | |
| 156 "ALGORITHM": "ALGORITHME", | |
| 157 "PROC": "PROCÉDURE", | |
| 158 "PROCEDURE": "PROCÉDURE", | |
| 159 "FUNC": "FONCTION", | |
| 160 "FUNCTION": "FOUNCTION", | |
| 161 "FN": "FONCTION", | |
| 162 "CLASS": "CLASSE", | |
| 163 }) |
