Mercurial > hgrepos > Python > libs > pygments-lexer-pseudocode2
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 163:315cfe0a836f | 164:a4317957148b |
|---|---|
| 1 # -*- coding: utf-8 -*- | |
| 2 # :- | |
| 3 # SPDX-FileCopyrightText: © 2026 Franz Glasner | |
| 4 # SPDX-License-Identifier: MIT | |
| 5 # :- | |
| 6 r"""A pseudocode lexer along the lines of CTAN's algpseudocode or | |
| 7 algpseudocodex. | |
| 8 | |
| 9 """ | |
| 10 | |
| 11 __all__ = ["AlgPseudocodeLexer", | |
| 12 "AlgPseudocodeLexer_DE", "AlgPseudocodeLexer_FR"] | |
| 13 | |
| 14 | |
| 15 import logging | |
| 16 import re | |
| 17 | |
| 18 import pygments.util | |
| 19 from pygments.lexer import bygroups, include, words | |
| 20 from pygments.token import (Comment, Error, Generic, Keyword, Name, Operator, | |
| 21 Punctuation, Text, Whitespace) | |
| 22 | |
| 23 # | |
| 24 # Relative imports do not work with pygments.lexers.load_lexer_from_file() | |
| 25 # in all of our supported Python releases. | |
| 26 # | |
| 27 from pygments_lexer_pseudocode2.lexers.bases import LexBase | |
| 28 from pygments_lexer_pseudocode2.utils import REVERSED_STANDARD_TYPES | |
| 29 from pygments_lexer_pseudocode2 import uniprops | |
| 30 | |
| 31 # | |
| 32 # As in the local imports: use an explicit name because __name__ is | |
| 33 # __builtins__ | |
| 34 # | |
| 35 _logger = logging.getLogger("pygments_lexer_pseudocode2.algpseudocode") | |
| 36 | |
| 37 | |
| 38 class AlgPseudocodeLexer(LexBase): | |
| 39 | |
| 40 """A pseudocode lexer along the lines of CTAN's algpseudocode or | |
| 41 algpseudocodex. | |
| 42 | |
| 43 Some ideas (e.g. strings) are borrowed from Pygment's Python lexer. | |
| 44 | |
| 45 """ | |
| 46 | |
| 47 name = "AlgPseudocode" | |
| 48 aliases = ["algpseudocode", "algpseudo"] | |
| 49 filenames = ["*.algpseudo", "*.algpseudocode"] | |
| 50 mimetypes = [] | |
| 51 flags = re.MULTILINE | |
| 52 | |
| 53 LANG = "en" | |
| 54 TRANSLATIONS = { | |
| 55 "PROG": "PROGRAM", | |
| 56 "PROGRAM": "PROGRAM", | |
| 57 "ALGO": "ALGORITHM", | |
| 58 "ALGORITHM": "ALGORITHM", | |
| 59 "PROC": "PROCEDURE", | |
| 60 "PROCEDURE": "PROCEDURE", | |
| 61 "FUNC": "FUNCTION", | |
| 62 "FUNCTION": "FUNCTION", | |
| 63 "FN": "FUNCTION", | |
| 64 "CLASS": "CLASS", | |
| 65 "INPUT": "Input:", | |
| 66 "INPUTS": "Inputs:", | |
| 67 "OUTPUT": "Output:", | |
| 68 "OUTPUTS": "Outputs:", | |
| 69 "RETURNS": "Returns:", | |
| 70 "ENSURE": "Ensure:", | |
| 71 "REQUIRE": "Require:", | |
| 72 "IS": "IS", | |
| 73 "WITH": "WITH", | |
| 74 "IF": "IF", | |
| 75 "THEN": "THEN", | |
| 76 "ELSE": "ELSE", | |
| 77 "ELSEIF": "ELSE IF", | |
| 78 "ELSIF": "ELSE IF", | |
| 79 "ELIF": "ELSE IF", | |
| 80 "DO": "DO", # in WHILE ... DO | |
| 81 "WHILE": "WHILE", | |
| 82 "FOR": "FOR", | |
| 83 "FORALL": "FOR ALL", | |
| 84 "FROM": "FROM", | |
| 85 "TO": "TO", | |
| 86 "IN": "IN", # as in FOR ... IN | |
| 87 "STEP": "STEP", | |
| 88 "LOOP": "LOOP", | |
| 89 "REPEAT": "REPEAT", | |
| 90 "UNTIL": "UNTIL", | |
| 91 "RETURN": "RETURN", | |
| 92 "BEGIN": "BEGIN", | |
| 93 "END": "END", # not in END_TRANSLATIONS | |
| 94 } | |
| 95 END_TRANSLATIONS = { | |
| 96 "PROG": "END OF PROGRAM", | |
| 97 "PROGRAM": "END OF PROGRAM", | |
| 98 "ALGO": "END OF ALGORITHM", | |
| 99 "ALGORITHM": "END OF ALGORITHM", | |
| 100 "PROC": "END OF PROCEDURE", | |
| 101 "PROCEDURE": "END OF PROCEDURE", | |
| 102 "FUNC": "END OF FUNCTION", | |
| 103 "FUNCTION": "END OF FUNCTION", | |
| 104 "FN": "END OF FUNCTION", | |
| 105 "CLASS": "END OF CLASS", | |
| 106 "IF": "END IF", | |
| 107 "WHILE": "END WHILE", | |
| 108 "FOR": "END FOR", | |
| 109 "FORALL": "END FOR ALL", | |
| 110 "LOOP": "END LOOP", | |
| 111 } | |
| 112 DEFAULT_END_PREFIX = "END OF " | |
| 113 SYMBOL_REMARK = u"▷" # U+25B7: Unicode 1.0 (Geometric Shapes) | |
| 114 # SYMBOL_REMARK = u"▻" # U+25BB: Unicode 1.0 (Geometric Shapes) | |
| 115 # SYMBOL_REMARK = u"⍝" # U+235D: Unicode 1.1 (Misc. Technical, APL) | |
| 116 SYMBOL_BLOCK = u"◆" # U+25C6: Unicode 1.0 (Geometric Shapes) | |
| 117 # SYMBOL_BLOCK = u"┃" # U+2503: Unicode 1.0 (Bow Drawing) | |
| 118 # SYMBOL_BLOCK = u"●" # U+25CF: Unicode 1.0 (Geometric Shapes) | |
| 119 SYMBOL_TEXTSTATEMENT = u"▪" # U+25AA: Unicode 1.0 (Geometric Shapes) | |
| 120 # SYMBOL_TEXTSTATEMENT = u"■" # U+25A0: Unicode 1.0 (Geometric Shapes) | |
| 121 SYMBOLS = { | |
| 122 # Group REMARK | |
| 123 "REMARK": SYMBOL_REMARK, | |
| 124 "REM": SYMBOL_REMARK, | |
| 125 # Group STATEMENT | |
| 126 "STATEMENT": SYMBOL_BLOCK, | |
| 127 "STATE": SYMBOL_BLOCK, | |
| 128 "BLOCK": SYMBOL_BLOCK, | |
| 129 # Group TEXTSTATEMENT | |
| 130 "TEXTSTATEMENT": SYMBOL_TEXTSTATEMENT, | |
| 131 "TEXTSTATE": SYMBOL_TEXTSTATEMENT, | |
| 132 "TSTATEMENT": SYMBOL_TEXTSTATEMENT, | |
| 133 "TSTATE": SYMBOL_TEXTSTATEMENT, | |
| 134 "TEXTBLOCK": SYMBOL_TEXTSTATEMENT, | |
| 135 "TBLOCK": SYMBOL_TEXTSTATEMENT, | |
| 136 "<-": u"⟵", # U+27F5: Unicode 3.2 (Supplemental Arrows-A) | |
| 137 "->": u"⟶", # U+27F6: Unicode 3.2 (Supplemental Arrows-A) | |
| 138 "<->": u"⟷", # U+27F7: Unicode 3.2 (Supplemental Arrows-A) | |
| 139 # "=>": u"⟹", # U+27F9: Unicode 3.2 (Supplemental Arrows-A) | |
| 140 # "<=>": u"⟺", # U+27FA: Unicode 3.2 (Supplemental Arrows-A) | |
| 141 # "<-": u"←", # U+2190: Unicode 1.0 (Arrows) | |
| 142 # "->": u"→", # U+2192: Unicode 1.0 (Arrows) | |
| 143 # "<->": u"↔", # U+2194: Unicode 1.0 (Arrows) | |
| 144 "=>": u"⇒", # U+21D2: Unicode 1.0 (Arrows) | |
| 145 "<=>": u"⇔", # U+21D4: Unicode 1.0 (Arrows) | |
| 146 "<=": u"≤", # U+2264: Unicode 1.0 (Mathematical Operators) | |
| 147 ">=": u"≥", # U+2265: Unicode 1.0 (Mathematical Operators) | |
| 148 "<>": u"≠", # U+2260: Unicode 1.0 (Mathematical Operators) | |
| 149 "!=": u"≠", # U+2260: Unicode 1.0 (Mathematical Operators) | |
| 150 ":=": u"∶=", # "≔" U+2254 not recognizable in my (small) mono font | |
| 151 "=:": u"=∶", # "≕" U+2255 not recognizable in my (small) mono font | |
| 152 "?=": u"≟", # U+225F: Unicode 1.0 (Mathematical Operators) | |
| 153 } | |
| 154 | |
| 155 def op_translate(toktype): | |
| 156 | |
| 157 def _op_translate(lexer, match, ctx=None): | |
| 158 kw = match.group().upper() | |
| 159 yield match.start(), toktype, lexer.TRANSLATIONS.get(kw, kw) | |
| 160 if ctx: | |
| 161 ctx.pos = match.end() | |
| 162 | |
| 163 return _op_translate | |
| 164 | |
| 165 def op_opt_end_translate(toktype): | |
| 166 | |
| 167 def _op_end_translate(lexer, match, ctx=None): | |
| 168 if not lexer.no_end: | |
| 169 kw = match.group().upper() | |
| 170 yield (match.start(), | |
| 171 toktype, | |
| 172 lexer.END_TRANSLATIONS.get( | |
| 173 kw, | |
| 174 lexer.DEFAULT_END_PREFIX + kw)) | |
| 175 if ctx: | |
| 176 ctx.pos = match.end() | |
| 177 | |
| 178 return _op_end_translate | |
| 179 | |
| 180 def op_opt_ignore(toktype): | |
| 181 | |
| 182 def _op_opt_ignore(lexer, match, ctx=None): | |
| 183 if not lexer.no_end: | |
| 184 yield match.start(), toktype, match.group() | |
| 185 if ctx: | |
| 186 ctx.pos = match.end() | |
| 187 | |
| 188 return _op_opt_ignore | |
| 189 | |
| 190 def op_opt_ignore_or_fixed(toktype, value): | |
| 191 """Yield a fixed given token type and value or -- if the lexer's | |
| 192 `no_end` setting evals to ``True`` nothing. | |
| 193 | |
| 194 """ | |
| 195 | |
| 196 def _op_opt_ignore_or_fixed(lexer, match, ctx=None): | |
| 197 if not lexer.no_end: | |
| 198 yield match.start(), toktype, value | |
| 199 if ctx: | |
| 200 ctx.pos = match.end() | |
| 201 | |
| 202 return _op_opt_ignore_or_fixed | |
| 203 | |
| 204 def op_gets(lexer, match, ctx=None): | |
| 205 yield match.start(), Operator, lexer.symbol_gets | |
| 206 | |
| 207 def op_remark(lexer, match, ctx=None): | |
| 208 yield match.start(), Comment.Single, lexer.symbol_remark | |
| 209 | |
| 210 def op_symbol(toktype): | |
| 211 | |
| 212 def _op_symbol(lexer, match, ctx=None): | |
| 213 kw = match.group().upper() | |
| 214 yield match.start(), toktype, lexer.SYMBOLS.get(kw, kw) | |
| 215 if ctx: | |
| 216 ctx.pos = match.end() | |
| 217 | |
| 218 return _op_symbol | |
| 219 | |
| 220 def op_explicit_tokentype(lexer, match, ctx=None): | |
| 221 needed_css = match.group("type") | |
| 222 toktype = REVERSED_STANDARD_TYPES.get(needed_css, None) | |
| 223 if toktype is None: | |
| 224 # Be more error friendly | |
| 225 toktype = Generic.Error | |
| 226 val = match.group() | |
| 227 _logger.warning("Unhandled explicit token type: %s", val) | |
| 228 else: | |
| 229 val = match.group("character") | |
| 230 yield match.start(), toktype, val | |
| 231 if ctx: | |
| 232 ctx.pos = match.end() | |
| 233 | |
| 234 tokens = { | |
| 235 "root": [ | |
| 236 (r"\n", Whitespace), | |
| 237 (r"/\*", Comment.Multiline, "multiline-nested-comment"), | |
| 238 (r"\(\*", Comment.Multiline, "multiline-nested-comment-alt"), | |
| 239 (r"(//|#).*$", Comment.Single), | |
| 240 include("remark"), | |
| 241 (r"(?i)\\(block|state(?:ment)?)[ \t]*(\{)", | |
| 242 bygroups(op_symbol(Text), LexBase.op_fixed(Whitespace, " ")), | |
| 243 "block-expr"), | |
| 244 (r"(?i)\\(" | |
| 245 r"(?:textstate(?:ment)?)" | |
| 246 r"|(?:tstate(?:ment)?)" | |
| 247 r"|(?:textblock)" | |
| 248 r"|(?:tblock)" | |
| 249 r")[ \t]*(\{)", | |
| 250 bygroups(op_symbol(Text), LexBase.op_fixed(Whitespace, " ")), | |
| 251 "text-statement"), | |
| 252 (r"(?i)\\(" | |
| 253 r"(?:input(?:s)?)" | |
| 254 r"|(?:output(?:s)?)" | |
| 255 r"|(?:ensure)" | |
| 256 r"|(?:require)" | |
| 257 r"|(?:returns)" | |
| 258 r")[ \t]*(\{)", | |
| 259 bygroups(op_translate(Keyword), | |
| 260 LexBase.op_fixed(Whitespace, " ")), | |
| 261 "text-statement"), | |
| 262 (r"(?i)\\(" | |
| 263 r"(?:if)" | |
| 264 r"|(?:then)" | |
| 265 r"|(?:else)" | |
| 266 r"|(?:el(?:s(?:e)?)?if)" | |
| 267 r"|(?:do)" # as in WHILE ... DO not DO ... UNTIL | |
| 268 r"|(?:while)" | |
| 269 r"|(?:forall)" | |
| 270 r"|(?:for)" | |
| 271 r"|(?:from)" | |
| 272 r"|(?:to)" | |
| 273 r"|(?:step)" | |
| 274 r"|(?:in)" | |
| 275 r"|(?:loop)" | |
| 276 r"|(?:repeat)" | |
| 277 r"|(?:until)" | |
| 278 r"|(?:return)" | |
| 279 r")\b", | |
| 280 bygroups(op_translate(Keyword))), | |
| 281 (r"\\\n", Text), | |
| 282 (r"(?i)\\(" | |
| 283 r"(?:prog(?:ram)?)" | |
| 284 r"|(?:algo(?:rithm)?)" | |
| 285 r"|(?:proc(?:edure)?)" | |
| 286 r"|(?:func(?:tion)?|(?:fn))" | |
| 287 r"|(?:class)" | |
| 288 r")[ \t]*(\{)", | |
| 289 bygroups(op_translate(Keyword), | |
| 290 LexBase.op_fixed(Whitespace, " ")), | |
| 291 "entity-name"), | |
| 292 # ENDxxx keywords with optional entity name in two parts: | |
| 293 # 1. with name | |
| 294 (r"(?i)\\end(?:[_\-]|(?:[ \t]+))?(" | |
| 295 r"(?:prog(?:ram)?)" | |
| 296 r"|(?:algo(?:rithm)?)" | |
| 297 r"|(?:proc(?:edure)?)" | |
| 298 r"|(?:func(?:tion)?)" | |
| 299 r"|(?:fn)" | |
| 300 r"|(?:class)" | |
| 301 r")(?:[_\-]|(?:[\t ]+))?(\{)", | |
| 302 bygroups(op_opt_end_translate(Keyword), | |
| 303 op_opt_ignore_or_fixed(Whitespace, " ")), | |
| 304 "entity-name-end"), | |
| 305 # 2. without name | |
| 306 # 3. AND keywords that do not allow a param (e.g. endif) | |
| 307 (r"(?i)\\end(?:[_\-]|(?:[ \t]+))?(" | |
| 308 r"(?:prog(?:ram)?)" | |
| 309 r"|(?:algo(?:rithm)?)" | |
| 310 r"|(?:proc(?:edure)?)" | |
| 311 r"|(?:func(?:tion)?)" | |
| 312 r"|(?:fn)" | |
| 313 r"|(?:class)" | |
| 314 r"|(?:if)" | |
| 315 r"|(?:while)" | |
| 316 r"|(?:for)" | |
| 317 r"|(?:forall)" | |
| 318 r"|(?:loop)" | |
| 319 r")\b", | |
| 320 bygroups(op_opt_end_translate(Keyword))), | |
| 321 # | |
| 322 # A single begin or end that is never suppressed because | |
| 323 # it is supposed to be paired with begin | |
| 324 # | |
| 325 (r"(?i)\\(begin|end)\b", | |
| 326 bygroups(op_translate(Keyword))), | |
| 327 # Keywords | |
| 328 (r"(?i)\\(" | |
| 329 r"(?:is)" | |
| 330 r"|(?:with)" | |
| 331 r")\b", | |
| 332 bygroups(op_translate(Keyword))), | |
| 333 include("expr"), | |
| 334 include("unicode-separators"), | |
| 335 include("unicode-other"), | |
| 336 (r"[^\S\n]+", Text), | |
| 337 # (r".", Generic.Error), # tolerance for errors | |
| 338 (r".", Error), | |
| 339 ], | |
| 340 "remark": [ | |
| 341 (r"(?i)\\(remark|rem)\b(.*)$", | |
| 342 bygroups(op_remark, Comment.Single)), | |
| 343 ], | |
| 344 "entity-name": [ # may be multiline | |
| 345 (r"[^\\}]+", Name.Entity), | |
| 346 (r"\}", LexBase.op_ignore, "#pop"), | |
| 347 (r"\\\}", LexBase.op_fixed(Name.Entity, "}")), | |
| 348 (r"\\\\", LexBase.op_fixed(Name.Entity, "\\")), | |
| 349 (r"\\", LexBase.op_fixed(Generic.Error, "\\")), | |
| 350 ], | |
| 351 "entity-name-end": [ # may be multiline -- suppressed if no_end | |
| 352 (r"[^\\}]+", op_opt_ignore(Name.Entity)), | |
| 353 (r"\}", LexBase.op_ignore, "#pop"), | |
| 354 (r"\\\}", op_opt_ignore_or_fixed(Name.Entity, "}")), | |
| 355 (r"\\\\", op_opt_ignore_or_fixed(Name.Entity, "\\")), | |
| 356 (r"\\", op_opt_ignore_or_fixed(Generic.Error, "\\")), | |
| 357 ], | |
| 358 "expr": [ | |
| 359 include("math-symbols"), # must be before punctuation | |
| 360 include("ascii-punctuation"), | |
| 361 include("unicode-punctuation"), | |
| 362 include("escaped-string-start"), | |
| 363 include("py-strings"), | |
| 364 include("py-numbers"), | |
| 365 (r"(?i)\\(call|name)[ \t]*(\{)", LexBase.op_ignore, "entity-name"), | |
| 366 (r"(?i)\\gets\b", op_gets), | |
| 367 (r"(?i)\\text[ \t]*\{", LexBase.op_ignore, "text-in-expr"), | |
| 368 include("explicit-tokentype"), | |
| 369 include("remark"), | |
| 370 include("keyword-constants"), | |
| 371 include("word-operators"), | |
| 372 include("math-builtins"), | |
| 373 include("py-name"), | |
| 374 ], | |
| 375 "expr-in-braces": [ | |
| 376 include("math-symbols"), # must be before punctuation | |
| 377 include("ascii-punctuation-in-braces"), | |
| 378 include("unicode-punctuation"), | |
| 379 include("escaped-string-start"), | |
| 380 include("py-strings"), | |
| 381 include("py-numbers"), | |
| 382 (r"(?i)\\(call|name)[ \t]*(\{)", LexBase.op_ignore, "entity-name"), | |
| 383 (r"(?i)\\gets\b", op_gets), | |
| 384 (r"(?i)\\text[ \t]*\{", LexBase.op_ignore, "text-in-expr"), | |
| 385 include("explicit-tokentype"), | |
| 386 include("remark"), | |
| 387 include("keyword-constants"), | |
| 388 include("word-operators"), | |
| 389 include("math-builtins"), | |
| 390 include("py-name"), | |
| 391 ], | |
| 392 "block-expr": [ # somewhat similar to "root" | |
| 393 (r"\}", LexBase.op_ignore, "#pop"), | |
| 394 (r"\n", Whitespace), | |
| 395 include("expr-in-braces"), | |
| 396 (r"\\\\", LexBase.op_fixed(Text, "\\")), | |
| 397 (r"\\", LexBase.op_fixed(Generic.Error, "\\")), | |
| 398 include("unicode-separators"), | |
| 399 include("unicode-other"), | |
| 400 (r"[^\S\n]+", Text), | |
| 401 (r".", Error), | |
| 402 ], | |
| 403 "text-statement": [ # like block but default to text-mode | |
| 404 (r"[^\\}\n]+", Text), | |
| 405 (r"\}", LexBase.op_ignore, "#pop"), | |
| 406 (r"\n", Whitespace), | |
| 407 (r"\\\}", LexBase.op_fixed(Text, "}")), | |
| 408 (r"(?i)\\expr(?:ession)?[ \t]*\{", | |
| 409 LexBase.op_ignore, | |
| 410 "block-expr"), | |
| 411 include("explicit-tokentype"), | |
| 412 include("remark"), | |
| 413 (r"\\\\", LexBase.op_fixed(Text, "\\")), | |
| 414 (r"\\", LexBase.op_fixed(Text, "\\")), # in text-mode: leave Text | |
| 415 (r".", Error), | |
| 416 ], | |
| 417 "text-in-expr": [ | |
| 418 (r"[^\\}\n]+", Text), | |
| 419 (r"\}", LexBase.op_ignore, "#pop"), | |
| 420 (r"\n", Whitespace), | |
| 421 (r"\\\}", LexBase.op_fixed(Text, "}")), | |
| 422 (r"(?i)\\expr(?:ession)?[ \t]*\{", | |
| 423 LexBase.op_ignore, | |
| 424 "block-expr"), | |
| 425 include("explicit-tokentype"), | |
| 426 include("remark"), | |
| 427 (r"\\\\", LexBase.op_fixed(Text, "\\")), | |
| 428 (r"\\", LexBase.op_fixed(Text, "\\")), # in text-mode: leave Text | |
| 429 (r".", Error), | |
| 430 ], | |
| 431 "math-builtins": [ | |
| 432 (words(("sqrt", "pow", "cos", "sin", "tan", "arcos", "arcsin", | |
| 433 "arctan", "arctan2", "mod", "exp", "ln", "log", | |
| 434 "min", "max"), | |
| 435 prefix=r"(?<!\.)", | |
| 436 suffix=r"\b"), | |
| 437 Name.Builtin), | |
| 438 ], | |
| 439 "math-symbols": [ | |
| 440 (r"<=>|<->|<-|->|=>|<=|>=|<>|!=|:=|=:|\?=", op_symbol(Operator)), | |
| 441 (r"[!&<>=+\-*/%|~]", Operator), # ASCII | |
| 442 (u"[%s]" % (uniprops.Sm,), Operator), # other Unicode | |
| 443 ], | |
| 444 "word-operators": [ | |
| 445 (words(("IN", "In", "in", | |
| 446 "IS", "Is", "is", | |
| 447 "AND", "And", "and", | |
| 448 "OR", "Or", "or", | |
| 449 "XOR", "Xor", "xor", | |
| 450 "NOT", "Not", "not"), | |
| 451 prefix=r"(?<!\.)", | |
| 452 suffix=r"\b"), | |
| 453 Operator.Word), | |
| 454 ], | |
| 455 "keyword-constants": [ | |
| 456 (words(("True", "TRUE", "true", "False", "FALSE", "false", | |
| 457 "None", "NONE", "none", "Nil", "NIL", "nil", | |
| 458 "Null", "NULL", "null", | |
| 459 "Empty", "EMPTY", "empty"), | |
| 460 prefix=r"(?<!\.)", | |
| 461 suffix=r"\b"), | |
| 462 Keyword.Constant), | |
| 463 ], | |
| 464 "ascii-punctuation": [ | |
| 465 (r"\.+", Punctuation), | |
| 466 (r"[{}:(),;[\]?@]", Punctuation), | |
| 467 ], | |
| 468 "ascii-punctuation-in-braces": [ | |
| 469 # | |
| 470 # Like "punctuation" but needs an escaped curly brace for } because | |
| 471 # a single closing curly brace pops the current state here. | |
| 472 # | |
| 473 (r"\\\}", LexBase.op_fixed(Punctuation, "}")), | |
| 474 (r"[{:(),;[\]?@]", Punctuation), | |
| 475 ], | |
| 476 "unicode-separators": [ | |
| 477 (u"[%s]" % (uniprops.Zl,), Whitespace), | |
| 478 (u"[%s]" % (uniprops.Zp,), Whitespace), | |
| 479 (u"[%s]" % (uniprops.Zs,), Whitespace), | |
| 480 ], | |
| 481 "unicode-punctuation": [ | |
| 482 (u"[%s]" % (uniprops.Pc,), Punctuation), | |
| 483 (u"[%s]" % (uniprops.Pd,), Punctuation), | |
| 484 (u"[%s]" % (uniprops.Ps,), Punctuation), | |
| 485 (u"[%s]" % (uniprops.Pe,), Punctuation), | |
| 486 (u"[%s]" % (uniprops.Pi,), Punctuation), | |
| 487 (u"[%s]" % (uniprops.Pf,), Punctuation), | |
| 488 (u"[%s]" % (uniprops.Po,), Punctuation), | |
| 489 ], | |
| 490 "unicode-other": [ | |
| 491 (u"[%s]" % (uniprops.Sc,), Text), # Currency | |
| 492 (u"[%s]" % (uniprops.So,), Text), # Other symbols | |
| 493 ], | |
| 494 "escaped-string-start": [ | |
| 495 (r"""\\(['"])""", bygroups(Punctuation)), | |
| 496 ], | |
| 497 "explicit-tokentype": [ | |
| 498 # All these REs are CASE-SENSITIVE! | |
| 499 | |
| 500 # Multiple characters possible, but no escaping! | |
| 501 (r"\\ttx\-(?P<type>[a-zA-Z0-9_-]+?)(?P<sep>[/:|=*+!\$~])" | |
| 502 r"(?P<character>(.|\n)+?)(?P=sep)", | |
| 503 op_explicit_tokentype), | |
| 504 (r"\\ttx\-(?P<type>[a-zA-Z0-9_-]+?)\{(?P<character>[^}]+?)\}", | |
| 505 op_explicit_tokentype), | |
| 506 (r"\\ttx\-(?P<type>[a-zA-Z0-9_-]+?)\((?P<character>[^)]+?)\)", | |
| 507 op_explicit_tokentype), | |
| 508 (r"\\ttx\-(?P<type>[a-zA-Z0-9_-]+?)<(?P<character>[^>]+?)>", | |
| 509 op_explicit_tokentype), | |
| 510 (r"\\ttx\-(?P<type>[a-zA-Z0-9_-]+?)\[(?P<character>[^\]]+?)\]", | |
| 511 op_explicit_tokentype), | |
| 512 | |
| 513 # Every character is possible: no escaping needed! | |
| 514 (r"\\tt-(?P<type>[^/]+?)/(?P<character>(?:.|\n))", | |
| 515 op_explicit_tokentype), | |
| 516 ], | |
| 517 } | |
| 518 | |
| 519 def __init__(self, **options): | |
| 520 self.no_end = pygments.util.get_bool_opt( | |
| 521 options, "no_end", default=False) | |
| 522 self.symbol_gets = options.get("gets", None) | |
| 523 if self.symbol_gets is None: | |
| 524 self.symbol_gets = self.SYMBOLS["<-"] # Default: "⟵" # U+27F5 | |
| 525 self.symbol_remark = options.get("remark", None) | |
| 526 if self.symbol_remark is None: | |
| 527 self.symbol_remark = self.SYMBOLS["REM"] # Default: "▷" # U+25B7 | |
| 528 LexBase.__init__(self, **options) | |
| 529 # | |
| 530 # Do this after calling the base because a "filters" option should be | |
| 531 # allowed to set **any** filter. | |
| 532 # | |
| 533 self.prohibit_raiseonerror_filter = pygments.util.get_bool_opt( | |
| 534 options, "prohibit_raiseonerror_filter", default=False) | |
| 535 | |
| 536 def add_filter(self, filter_, **options): | |
| 537 # | |
| 538 # May be called by Lexer.__init__ when | |
| 539 # self.prohibit_raiseonerror_filter is not yet set. | |
| 540 # This is intentionally so. | |
| 541 # | |
| 542 if getattr(self, "prohibit_raiseonerror_filter", False): | |
| 543 if filter_ in ("raiseonerror",): | |
| 544 return | |
| 545 LexBase.add_filter(self, filter_, **options) | |
| 546 | |
| 547 | |
| 548 class AlgPseudocodeLexer_DE(AlgPseudocodeLexer): | |
| 549 | |
| 550 """ | |
| 551 | |
| 552 .. seealso:: | |
| 553 - https://de.wikipedia.org/wiki/Pseudocode | |
| 554 | |
| 555 .. todo:: Complete german translations | |
| 556 | |
| 557 """ | |
| 558 | |
| 559 name = "AlgPseudocodeDE" | |
| 560 aliases = ["algpseudocode-de", "algpseudo-de"] | |
| 561 filenames = ["*.algpseudo-de", "*.algpseudocode-de"] | |
| 562 | |
| 563 LANG = "de" | |
| 564 TRANSLATIONS = AlgPseudocodeLexer.TRANSLATIONS.copy() | |
| 565 TRANSLATIONS.update({ | |
| 566 "PROG": "PROGRAMM", | |
| 567 "PROGRAM": "PROGRAMM", | |
| 568 "ALGO": "ALGORITHMUS", | |
| 569 "ALGORITHM": "ALGORITHMUS", | |
| 570 "PROC": "PROZEDUR", | |
| 571 "PROCEDURE": "PROZEDUR", | |
| 572 "FUNC": "FUNKTION", | |
| 573 "FUNCTION": "FUNKTION", | |
| 574 "FN": "FUNKTION", | |
| 575 "CLASS": "KLASSE", | |
| 576 "IS": "IST", | |
| 577 "WITH": "MIT", | |
| 578 "IF": "WENN", | |
| 579 "THEN": "DANN", | |
| 580 "ELSE": "ANDERNFALLS", | |
| 581 "ELSEIF": "ANDERNFALLS WENN", | |
| 582 "ELSIF": "ANDERNFALLS WENN", | |
| 583 "ELIF": "ANDERNFALLS WENN", | |
| 584 # "DO": # XXX TBD # in WHILE WHILE ... DO # noqa # in WHILE ... DO | |
| 585 "WHILE": "SOLANGE", | |
| 586 "FOR": "FÜR", | |
| 587 "FORALL": "FÜR ALLE", | |
| 588 "FROM": "VON", | |
| 589 "TO": "BIS", | |
| 590 "IN": "IN", | |
| 591 "STEP": "SCHRITTWEITE", | |
| 592 # "LOOP": XXX TBD # noqa | |
| 593 "REPEAT": "WIEDERHOLE", | |
| 594 "UNTIL": "BIS", | |
| 595 # "RETURN": XXX TBD # noqa | |
| 596 "BEGIN": "START", | |
| 597 "END": "ENDE", | |
| 598 }) | |
| 599 END_TRANSLATIONS = AlgPseudocodeLexer.END_TRANSLATIONS.copy() | |
| 600 END_TRANSLATIONS.update({ | |
| 601 "PROG": "ENDE DES PROGRAMMS", | |
| 602 "PROGRAM": "ENDE DES PROGRAMMS", | |
| 603 "ALGO": "ENDE DES ALGORITHMUS", | |
| 604 "ALGORITHM": "ENDE DES ALGORITHMUS", | |
| 605 "PROC": "ENDE DER PROZEDUR", | |
| 606 "PROCEDURE": "ENDE DER PROZEDUR", | |
| 607 "FUNC": "ENDE DER FUNKTION", | |
| 608 "FUNCTION": "ENDE DER FUNKTION", | |
| 609 "FN": "ENDE DER FUNKTION", | |
| 610 "CLASS": "ENDE DER KLASSE", | |
| 611 "IF": "ENDE WENN", | |
| 612 "WHILE": "ENDE SOLANGE", | |
| 613 "FOR": "ENDE FÜR", | |
| 614 "FORALL": "ENDE FÜR ALLE", | |
| 615 # "LOOP": "ENDE XXX", # XXX TBD # noqa | |
| 616 }) | |
| 617 DEFAULT_END_PREFIX = "ENDE VON " | |
| 618 | |
| 619 | |
| 620 class AlgPseudocodeLexer_FR(AlgPseudocodeLexer): | |
| 621 | |
| 622 """ | |
| 623 | |
| 624 .. seealso:: | |
| 625 - https://info.blaisepascal.fr/pseudo-code/ | |
| 626 - https://fr.wikipedia.org/wiki/Pseudo-code | |
| 627 - https://fr.wikipedia.org/wiki/Structure_de_contr%C3%B4le | |
| 628 | |
| 629 .. todo:: Complete french translations | |
| 630 | |
| 631 """ | |
| 632 | |
| 633 name = "AlgPseudocodeFR" | |
| 634 aliases = ["algpseudocode-fr", "algpseudo-fr"] | |
| 635 filenames = ["*.algpseudo-fr", "*.algpseudocode-fr"] | |
| 636 | |
| 637 LANG = "fr" | |
| 638 TRANSLATIONS = AlgPseudocodeLexer.TRANSLATIONS.copy() | |
| 639 TRANSLATIONS.update({ | |
| 640 "PROG": "PROGRAMME", | |
| 641 "PROGRAM": "PROGRAMME", | |
| 642 "ALGO": "ALGORITHME", | |
| 643 "ALGORITHM": "ALGORITHME", | |
| 644 "PROC": "PROCÉDURE", | |
| 645 "PROCEDURE": "PROCÉDURE", | |
| 646 "FUNC": "FONCTION", | |
| 647 "FUNCTION": "FOUNCTION", | |
| 648 "FN": "FONCTION", | |
| 649 "CLASS": "CLASSE", | |
| 650 "IS": "EST", | |
| 651 "WITH": "AVEC", | |
| 652 "IF": "SI", | |
| 653 "THEN": "ALORS", | |
| 654 "ELSE": "SINON", | |
| 655 "ELSEIF": "SINONSI", | |
| 656 "ELSIF": "SINONSI", | |
| 657 "ELIF": "SINONSI", | |
| 658 "DO": "FAIRE", # as in in WHILE ... DO (not DO ... UNTIL) | |
| 659 "WHILE": "TANTQUE", | |
| 660 "FOR": "POUR", | |
| 661 "FORALL": "POUR CHAQUE", | |
| 662 "FROM": "DE", | |
| 663 "TO": "JUSQU'À", # or just "À", | |
| 664 "IN": "DANS", # as in FOR ... IN | |
| 665 "STEP": "PAR PAS DE", | |
| 666 "LOOP": "BOUCLE", # XXX FIXME??? | |
| 667 "REPEAT": "RÉPÉTER", | |
| 668 "UNTIL": "JUSQUACEQUE", | |
| 669 "RETURN": "RENVOYER", | |
| 670 "BEGIN": "DÉBUT", | |
| 671 "END": "FIN", | |
| 672 }) | |
| 673 END_TRANSLATIONS = AlgPseudocodeLexer.END_TRANSLATIONS.copy() | |
| 674 END_TRANSLATIONS.update({ | |
| 675 "PROG": "FIN DE PROGRAMME", | |
| 676 "PROGRAM": "FIN DE PROGRAMME", | |
| 677 "ALGO": "FIN D'ALGORITHME", | |
| 678 "ALGORITHM": "FIN D'ALGORITHME", | |
| 679 "PROC": "FIN DE PROCÉDURE", | |
| 680 "PROCEDURE": "FIN DE PROCÉDURE", | |
| 681 "FUNC": "FIN DE FONCTION", | |
| 682 "FUNCTION": "FIN DE FOUNCTION", | |
| 683 "FN": "FIN DE FONCTION", | |
| 684 "CLASS": "FIN DE CLASSE", | |
| 685 "SI": "FIN SI", | |
| 686 "FOR": "FIN POUR", | |
| 687 "FORALL": "FIN POUR CHAQUE", | |
| 688 "WHILE": "FIN TANTQUE", | |
| 689 "LOOP": "FIN BOUCLE", | |
| 690 }) | |
| 691 DEFAULT_END_PREFIX = "FIN DE " |
