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 "