Metadata-Version: 2.5
Name: pseudocode-i18n
Version: 0.9.0
Summary: Multilingual educational pseudocode with native type system, semantic linter, Python transpilation and flowcharts
Project-URL: Documentation, https://rod2ik.gitlab.io/pseudocode-i18n/
Project-URL: Repository, https://gitlab.com/rod2ik/pseudocode-i18n
Project-URL: Issues, https://gitlab.com/rod2ik/pseudocode-i18n/-/issues
Author: Rod2ik
License: GPL-3.0-or-later
License-File: LICENSE
Keywords: education,i18n,pseudocode,python,transpiler
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Education
Classifier: Topic :: Software Development :: Compilers
Requires-Python: >=3.11
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: mkdocs-material>=9.6; extra == 'dev'
Requires-Dist: mkdocs<2,>=1.6; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.12; extra == 'dev'
Description-Content-Type: text/markdown

# pseudocode-i18n

| Resource | Link | Purpose |
| --- | --- | --- |
| **pseudocode-i18n — repository** | [gitlab.com/rod2ik/pseudocode-i18n](https://gitlab.com/rod2ik/pseudocode-i18n) | Multilingual parser, formatter, native type system, semantic linter, Python transpiler and execution core |
| **pseudocode-i18n — documentation** | [rod2ik.gitlab.io/pseudocode-i18n](https://rod2ik.gitlab.io/pseudocode-i18n/) | Complete user and developer documentation |
| **pygments-lexer-pseudocode-i18n** | [gitlab.com/rod2ik/pygments-lexer-pseudocode-i18n](https://gitlab.com/rod2ik/pygments-lexer-pseudocode-i18n) | Pygments syntax highlighting based on the same multilingual vocabulary |
| **mkdocs-pseudocode-i18n** | [gitlab.com/rod2ik/mkdocs-pseudocode-i18n](https://gitlab.com/rod2ik/mkdocs-pseudocode-i18n) | MkDocs integration for pseudocode blocks, rendering and teaching material |
| **vscode-pseudocode-i18n** | [gitlab.com/rod2ik/vscode-pseudocode-i18n](https://gitlab.com/rod2ik/vscode-pseudocode-i18n) | VS Code editing experience for `.pseudo` and `.algo` files, published on Open VSX and Visual Studio Marketplace |
| **pseudocode-i18n-languageserver** | [gitlab.com/rod2ik/pseudocode-i18n-languageserver](https://gitlab.com/rod2ik/pseudocode-i18n-languageserver) | Shared LSP intelligence for Kate, Neovim, Spyder and other editor integrations |
| **thonny-pseudocode-i18n** | [gitlab.com/rod2ik/thonny-pseudocode-i18n](https://gitlab.com/rod2ik/thonny-pseudocode-i18n) | Thonny 5 adapter using the same LSP intelligence, snippets, navigation and flowcharts |

**Current version: 0.9.0.**
**License:** GNU GPL-3.0-or-later.

`pseudocode-i18n` lets students, teachers and developers write the **same pseudocode language in several natural languages**, while keeping one common semantic model underneath.

Write a normal `.pseudo` or `.algo` file, in French, Spanish, Italian, Portuguese, German, Dutch, Danish, Swedish, Norwegian, Finnish, Greek, Ukrainian, Russian or English. The language can be detected automatically. The same source can then be **checked, semantically linted, formatted, executed, transpiled bidirectionally with Python, or exported/rendered as a Mermaid flowchart/algorigram**.

```text
# language: fr

age est un entier
age = 17

Si age >= 18 Alors:
    Afficher "Majeur"
Sinon:
    Afficher "Mineur"
Fin
```

Transpiles to:

```python
age: int
age = 17

if age >= 18:
    print("Majeur")
else:
    print("Mineur")
```

## Why this project?

Pseudocode used in classrooms is rarely standardized. The same ideas are written as `Afficher`, `Écrire`, `Mostrar`, `Escribir`, `Print`, `Display`, `Si ... Alors`, `If ... Then`, `FinSi`, `Fin`, or with indentation only.

`pseudocode-i18n` deliberately accepts these common teaching variants, maps them to one AST, and provides one predictable canonical formatter.

Main goals:

- two equivalent source extensions for every language: **`.pseudo`** and **`.algo`**;
- automatic language detection with an explicit override when needed;
- tolerant input, but deterministic canonical formatting;
- indentation-based block semantics, like Python;
- optional `FinSi` / `FinPour` / `FinFonction`-style terminators for constructs that need a separate closer;
- a generic optional terminator (`Fin`, `Fim`, `Fine`, `Ende`, `End`);
- localized types, constants, operators, input/output verbs and control flow;
- bidirectional Python transpilation for the supported subset, without losing useful type information;
- a shared language definition for CLI, Pygments, MkDocs and VS Code integrations.

## 0.9 language-server, editor-help and runtime foundations

Version 0.9 adds an editor-neutral semantic index with exact source ranges, definitions, references, signatures and symbol metadata. The shared [`pseudocode-i18n-languageserver`](https://gitlab.com/rod2ik/pseudocode-i18n-languageserver) consumes this API to provide diagnostics, **snippets plus semantic completion**, pedagogical hover help, signature help, document symbols, navigation, rename and formatting without duplicating the language grammar. VS Code and Thonny both consume this same intelligence.

The core also owns the editor-help catalogue and localized runtime-error catalogue so future IDEs receive the same explanations. Editor help is fully localized (for example **Syntaxe** in French and **Sintaxis** in Spanish) and deliberately lists every accepted spelling for a construct, including imperative/infinitive synonyms and automatically accepted accentless variants. Runtime error mapping is designed for execution performance: generated Python contains comment-only source markers, normal execution has no per-statement tracing overhead, and source-line localization is performed only when an exception occurs. Syntax and runtime failures are rendered in the Pseudocode language with the original Pseudocode line number and source line; Python backend exception class names are not exposed in the normal learner-facing message.

Object-oriented access modifiers are language-neutral concepts. Every one of the 14 languages accepts its localized spellings **and** the universal English spellings `public`, `private` and `protected`; accentless variants supplied by the language packs remain accepted as well.

The 0.9 linter also recovers after independent malformed lines instead of stopping at the first one. A counted loop missing its localized “times” word, an incomplete input statement and a bad module name can therefore all receive squiggles in the same document. Known-bad lines are neutralized only inside the static-analysis pass; the user's source is never rewritten and invalid code is never made executable.

Imports are now resolved through a deliberately small Pseudocode module model. `math` and `random` are standard modules; sibling/project `.algo` and `.pseudo` files are local Pseudocode modules. Arbitrary Python packages are not exposed implicitly. Standard module names keep priority, while the localized `local` keyword explicitly forces a same-named local module. For example in French:

```text
importe sqrt depuis math en tant que rac
importer sqrt depuis math en tant que rac
importe geometrie
importe aire depuis geometrie
importe aire depuis local geometrie en tant que aire_locale
```

Unknown modules (`PSE113`) and unknown imported members (`PSE114`) are reported on the offending token. Local modules are transpiled only when imported and cached afterwards, so this support adds no per-statement execution overhead.

Two universal pedagogical random helpers are available in all 14 languages, alongside the existing localized aliases:

```text
alea()          -> real in [0, 1[
entalea(a, b)   -> integer in [a, b] (both bounds included)
```

In French, the existing `hasard(n)` remains the integer helper for `[0, n[`, and `aleatoire(a, b)` remains an alias of the inclusive integer range helper.

## 0.8 Unicode and 14-language expansion

Version 0.8 expands the data-driven language registry from 6 to **14 languages**: French, Spanish, Italian, Portuguese, German, Dutch, Danish, Swedish, Norwegian, Finnish, Greek, Ukrainian, Russian and English. Identifiers are Unicode-aware across parsing, semantic analysis and highlighting, so Greek and Cyrillic variable/function names are first-class identifiers.

Automatic detection is exercised against all bundled language examples, while `# language: xx` remains the explicit override for short or deliberately ambiguous snippets. The Usage documentation is now generated as a complete per-language tree with real variables, conditions, loops, functions, classes, tools, flowcharts and exhaustive vocabulary tables.

## 0.7 typed signatures, object model and data-driven languages

Version 0.7 turns the semantic foundations into a structured teaching-language model while keeping all annotations optional.

```text
Classe Personne:
    private nom: chaîne
    protected age: entier

    Constructeur(nom: chaîne, age: entier):
        this.nom = nom
        self.age = age
    Fin

    public Fonction anniversaire() -> entier:
        self.age = self.age + 1
        Renvoyer self.age
    Fin
Fin
```

The 0.7 core adds:

- untyped, partially typed and fully typed function/method parameters and return values;
- structured class bases, typed members and native instance/class/function types;
- localized constructors (`Constructeur`, `Constructor`, `Costruttore`, `Construtor`, `Konstruktor`, `Constructor`);
- strict `self == this` semantics for the current instance;
- single/multiple inheritance, inherited-member resolution, `super`, `override`, static/class methods and native `public` / `protected` / `private` checks;
- stronger semantic checks for annotated calls/returns, inheritance, overrides and member access;
- a fully data-driven language registry: the core discovers `languages/*.yml`, while Pygments, MkDocs and VS Code regenerate their language-facing artifacts from that shared data.

Python remains the execution backend; it does not define the Pseudocode type system or access-control semantics.

## 0.6 native type system, linter and structured diagnostics

Version 0.6 adds a language-native semantic layer **without making Python the definition of Pseudocode semantics**. The existing Python transpiler remains the execution backend used by `pseudo file.pseudo`; linting is a separate static-analysis capability.

The core now provides:

- an internal type system (`integer`, `float`, `string`, `boolean`, collections, functions/classes/modules, `null`, `void`, `unknown` and `any`);
- native expression analysis over a Pseudocode expression AST, rather than Python's `ast`;
- `NullType` semantics for localized null literals such as French `Vide` (which still transpiles to Python `None` for execution);
- symbol/scope tracking and type inference for assignments, collections, calls, indexing and common operators;
- semantic diagnostics for undefined or unassigned variables, unused variables, wrong argument counts, unreachable statements, incompatible declared/actual types, invalid operations and control-flow misuse;
- structured diagnostics with stable codes, severity, source ranges and optional expected/actual types;
- diagnostics localized to the language resolved from the `.pseudo` file;
- a tolerant line-local preflight pass for incomplete compound statements and invalid type annotations, so editors underline the actual faulty line instead of a downstream indentation consequence;
- multiple independent line-local syntax/type errors can be reported in one lint pass;
- structural keywords remain part of the highlighting vocabulary even while their statement is incomplete; syntax validity is communicated by diagnostics/squiggles rather than by removing keyword highlighting;
- a new `pseudo lint file.pseudo` command with text, JSON and JSONL output.

For example:

```bash
pseudo lint exercice.pseudo
pseudo lint exercice.pseudo --format json
```

Running remains unchanged:

```bash
pseudo exercice.pseudo
```

A file is **not required to pass the linter before execution**. This deliberate separation keeps the teaching runtime compatible while allowing editors and CI to consume richer static diagnostics.

For example, an incomplete counted repetition is diagnosed on its own line:

```text
Répéter 5:
    Afficher "bonjour"
```

The French diagnostic points to line 1 and proposes `Répéter … fois`; it does not blame the indented `Afficher` line. Likewise, `x: produit` is reported as an unknown type (`PSE112`) when French is active. IDE clients receive the same localized ranges and messages through the language server.

## 0.5 language and visualization foundations

Version 0.5 includes a larger Python-like teaching surface while keeping one multilingual AST:

- explicit algorithm boundaries (`Début ... Fin` and translated long/named forms);
- processes and subprocesses;
- no-fall-through `Selon / Cas / Autrement` (`switch`/`case`) in all supported languages;
- `ÉcrireSansSaut` and `EffacerÉcran` families;
- Python-like `//`, `%`, `**`, slices and negative indices, plus pedagogical `^`, `<>`, localized logical/MOD words;
- project-wide `index_base: 0|1`, applied coherently to strings, lists, tuples, slices and substring helpers;
- localized imports with aliases in both traditional and natural word orders (`De math Importer sqrt En tant que rac` and `Importe sqrt depuis math en tant que rac`) plus universal Python `import/from/as`;
- localized math/string/conversion/random helpers plus universal Python spellings such as `sqrt()`, `abs()`, `len()`, `pow()`, `log()` and `pi`;
- named flowchart symbols and execution-aware flowchart highlighting;
- `pseudo trace` JSON/JSONL execution traces for synchronized source/flowchart/variable visualizers.

The VS Code integration consumes these core capabilities for a live flowchart and step-by-step execution view; editor integrations do not reimplement language semantics.

## Install

```bash
python -m pip install pseudocode-i18n
```

On a system-managed Python installation where you deliberately use system packages:

```bash
python -m pip install --break-system-packages pseudocode-i18n
```

The package installs two equivalent commands:

```bash
pseudo
pseudocode
```

## Two equivalent source extensions, automatic language detection

Every pseudocode source file uses either of the two canonical extensions, regardless of language:

```text
algo.pseudo
algo.algo
```

`.pseudo` and `.algo` are strictly equivalent; neither extension carries language information.

In the normal case, the language is detected from the source:

```bash
pseudo algo.pseudo
```

If detection needs to be overridden, put a universal metadata directive at the beginning of the file:

```text
# language: es
```

or force it from the CLI:

```bash
pseudo --lang es algo.pseudo
```

Resolution order is:

```text
CLI/API > # language: xx > project configuration > automatic detection > fallback
```

The canonical form is `# language: fr`. The aliases `# language fr`, `# lang: fr` and `# lang fr` are also accepted; `language` and `lang` are synonyms and the colon is optional. `#` is the only comment/directive marker; `//` is integer division.

## Pseudocode in several languages

The bundled language order is **French, Spanish, Italian, Portuguese, German, Dutch, Danish, Swedish, Norwegian, Finnish, Greek, Ukrainian, Russian, then English**. Every Usage topic is generated separately for all 14 languages.

### Français

```text
Si note >= 10 Alors:
    Afficher "Admis"
Sinon:
    Afficher "Ajourné"
Fin
```

### Español

```text
Si nota >= 10 Entonces:
    Mostrar "Aprobado"
Sino:
    Mostrar "No aprobado"
Fin
```

### Italiano

```text
Se voto >= 10 Allora:
    Mostra "Promosso"
Altrimenti:
    Mostra "Non promosso"
Fine
```

### Português

```text
Se nota >= 10 Então:
    Mostrar "Aprovado"
Senão:
    Mostrar "Reprovado"
Fim
```

### Deutsch

```text
Wenn note >= 10 Dann:
    Ausgeben "Bestanden"
Sonst:
    Ausgeben "Nicht bestanden"
Ende
```

### English

```text
If grade >= 10 Then:
    Display "Passed"
Else:
    Display "Failed"
End
```

## Flexible conditionals, canonical formatting

French conditionals accept, among others:

```text
Si condition:
Si condition
Si condition Alors:
Si condition Alors
```

`Sinon`, `Sinon Si`, optional `Alors`, optional colons, specific terminators and generic `Fin` are also accepted.

For example, all these tolerant variants converge with `pseudo format` toward:

```text
Si condition Alors:
    Afficher "oui"
Sinon Si autre_condition Alors:
    Afficher "peut-être"
Sinon:
    Afficher "non"
Fin
```

Indentation determines the actual block structure. End markers are always optional.

## Input and output synonyms

Vocabulary is language data rather than parser code.

French examples:

```text
Afficher "Bonjour"
Écrire "Bonjour"
Ecrire "Bonjour"

Saisir n
Lire n
Lis "Ton nom", nom
```

A prompt-only input statement such as `Lis "Allo"` is incomplete because the entered value has nowhere to be stored. The linter reports this before execution and points to the original source line.

Spanish examples:

```text
Mostrar "Hola"
Escribir "Hola"

Leer n
Introducir n
Lee "Tu nombre", nombre
```

Natural localized imports are accepted in the same data-driven way. For example:

```text
Importe sqrt depuis math en tant que rac
Importa sqrt desde math como raiz
```

Both transpile to a Python `from ... import ... as ...` statement. Matching is case-insensitive, and accentless equivalents of declared accented spellings are generated automatically.

## Variables and optional types

Type declarations are **never mandatory**. You can write ordinary Python-like assignments:

```text
a = 2
a = a + 2
```

or add pedagogical type declarations. The compact `name: type` notation is accepted in every source language as well as the localized natural forms:

```text
i: chaîne
a est un entier
a, b sont des flottants
nom est une chaîne
notes est un tableau
d est un dictionnaire
vus est un ensemble
coordonnees est un tuple
```

An explicit annotation is a contract: after `i: chaîne`, assigning `i = 0` is a localized `PSE105` type error. Binary operations are also checked when both operand types are known. Numeric arithmetic is allowed between numeric types, strings/lists/tuples concatenate only with compatible families, and string/list repetition by an integer remains valid (`3 * "ha"`), while combinations such as `3 + " pommes"` or `Vrai + 1` are rejected. Untyped variables remain gradual/dynamic; add an annotation when a stable pedagogical type is required.

They are preserved in Python as annotations:

```python
a: int
a: float
b: float
nom: str
notes: list
d: dict
vus: set
coordonnees: tuple
```

Bundled semantic type families:

| Semantic type | Python | French examples | English examples |
| --- | --- | --- | --- |
| integer | `int` | `entier`, `int` | `integer`, `int` |
| float | `float` | `flottant`, `réel` | `float`, `real` |
| string | `str` | `chaîne`, `str` | `string`, `str` |
| boolean | `bool` | `booléen`, `bool` | `boolean`, `bool` |
| array/list | `list` | `tableau`, `liste` | `array`, `list` |
| dictionary | `dict` | `dictionnaire`, `dict` | `dictionary`, `dict` |
| set | `set` | `ensemble`, `set` | `set` |
| tuple | `tuple` | `tuple`, `n-uplet` | `tuple` |

The same model is localized in all 14 bundled languages.

## `Vide` / null values are not empty collections

A localized null constant has the same semantic role as Python `None`:

```text
x = Vide
```

becomes:

```python
x = None
```

Spanish accepts `Vacío` and its automatically generated accentless form `Vacio`; the other languages provide their own localized vocabulary.

This is distinct from empty collections:

```text
[]              # empty list
{}              # empty dictionary, exactly like Python
Ensemble()      # empty set -> set()
Tuple()         # empty tuple -> tuple()
Dictionnaire()  # empty dictionary -> dict()
```

## Assignment forms

All of these are accepted as assignments:

```text
a = 2
a := 2
a <- 2
a ← 2
2 -> a
2 → a
```

The canonical formatter emits `=`.

## Membership and mathematical notation

Localized word operators and mathematical symbols are equivalent.

French examples:

```text
x Dans E
x Inclus Dans E
x ∈ E

x Pas Dans E
x Non Dans E
x Non Inclus Dans E
x ∉ E
```

They transpile to Python `in` / `not in`.

## Repeat loops

Repeat a fixed number of times:

```text
Répéter 5 fois:
    Afficher "Bonjour"
Fin
```

All 14 bundled languages accept the infinitive and the natural second-person imperative for action verbs whenever those forms are distinct, not only for repeat. For example, French accepts `Afficher` / `Affiche`, `Lire` / `Lis`, `Retourner` / `Retourne`, `Importer` / `Importe` and `Répéter` / `Répète`; Spanish accepts `Importar` / `Importa`; German accepts `Importieren` / `Importiere` and natural multi-word imperatives such as `Ausgeben` / `Gib aus`. Languages where both grammatical forms have the same spelling naturally expose only that spelling. Localized collection methods follow the same principle where a verb has distinct forms.

becomes:

```python
for _ in range(5):
    print("Bonjour")
```

Post-test repeat-until loop:

```text
n = 0
Répéter:
    n = n + 1
Jusqu'à ce que n >= 5
```

`Jusqu'à n >= 5` is equivalent. The `Jusqu'à ...` line closes the post-test loop, so no `Fin` follows it.

becomes:

```python
n = 0
while True:
    n = n + 1
    if n >= 5:
        break
```

The body therefore executes at least once.

## Fast direct execution

`pseudo file.pseudo` still transpiles to Python, but the CLI executes the generated Python inside its own short-lived process instead of starting a second Python interpreter. Language definitions and compiled grammar templates are cached per process, and the C-backed safe YAML loader is used when available. These changes reduce startup overhead substantially for the tiny programs used in introductory teaching while keeping Python strictly as the execution backend.

## Run, check, transpile and format

Run directly:

```bash
pseudo programme.pseudo
```

Check syntax:

```bash
pseudo check programme.pseudo
```

Transpile pseudocode → Python:

```bash
pseudo transpile programme.pseudo -o programme.py
pseudo transpile -i programme.pseudo -o programme.py
pseudo transpile -input programme.pseudo -output programme.py
```

Transpile Python → pseudocode:

```bash
pseudo transpile programme.py -o programme.pseudo --lang fr
pseudo transpile -i programme.py -o programme.pseudo --lang fr
pseudo transpile -input programme.py -output programme.pseudo --lang fr
```

The direction is inferred from `.pseudo`/`.algo` versus `.py`. Unsupported Python statements fail explicitly rather than being approximated silently.

Canonical formatting in place:

```bash
pseudo format programme.pseudo
pseudo format programme.pseudo --check
```

## Flowchart / algorigram export and rendering

Export Mermaid source:

```bash
pseudo flowchart programme.pseudo -o programme.mmd
```

Render directly to SVG or PNG:

```bash
pseudo render programme.pseudo -o programme.svg
pseudo render programme.pseudo -o programme.png
pseudo render programme.mmd -o programme.svg
pseudo render programme.mmd -o programme.png
```

`pseudo svg` is an SVG-only alias. Rendering uses Mermaid CLI, auto-detects Chromium/Chrome when possible, and uses a transparent background by default.

## Python API

Automatic language resolution is the default:

```python
from pseudocode_i18n import (
    SUPPORTED_EXTENSIONS, detect_language, format_pseudocode, parse,
    render_mermaid, resolve_snippets, snippets_for_language,
    to_mermaid, transpile, transpile_python,
)

source = '''
Si x > 0 Alors:
    Afficher x
Fin
'''

detection = detect_language(source)
tree = parse(source)
python_source = transpile(source)
canonical_source = format_pseudocode(source)
mermaid = to_mermaid(source)
pseudo_again = transpile_python(python_source, language="fr")
render_mermaid(mermaid, "programme.svg")

assert SUPPORTED_EXTENSIONS == (".pseudo", ".algo")
french_snippets = snippets_for_language("fr")
resolved_snippets = resolve_snippets(source, fallback="fr")
```

Force a language when needed:

```python
python_source = transpile(source, language="fr")
```

`detect_language()` returns the selected ISO 639-1 code together with confidence/scores through a `LanguageDetection` object. `snippets_for_language()` exposes the canonical localized editor/LSP snippets, while `resolve_snippets()` applies the same language precedence as normal source processing.

## Project configuration and custom synonyms

Canonical project file:

```text
pseudocode.config.yml
```

Example:

```yaml
language: auto
fallback_language: fr
index_base: 0

format:
  colons: true
  indent: 4
  end_markers: true

render:
  browser: auto
  background: transparent
  mermaid_cli: auto

languages:
  fr:
    keywords:
      display:
        add:
          - Montrer
```

`lang:` is a supported alias for the project-level `language:` key. The canonical spelling in documentation remains `language:`:

```yaml
lang: es
fallback_language: fr
```

This makes `Montrer` an additional French display synonym **without modifying the parser**.

Bundled language data live in:

```text
pseudocode_i18n/languages/fr.yml
pseudocode_i18n/languages/es.yml
pseudocode_i18n/languages/it.yml
pseudocode_i18n/languages/pt.yml
pseudocode_i18n/languages/de.yml
pseudocode_i18n/languages/nl.yml
pseudocode_i18n/languages/da.yml
pseudocode_i18n/languages/sv.yml
pseudocode_i18n/languages/no.yml
pseudocode_i18n/languages/fi.yml
pseudocode_i18n/languages/el.yml
pseudocode_i18n/languages/uk.yml
pseudocode_i18n/languages/ru.yml
pseudocode_i18n/languages/en.yml
```

They define vocabulary, patterns, end forms, type names, method/function aliases and flowchart labels. This is the preferred place for language-specific evolution.

## Add another language

Languages use ISO 639-1 two-letter codes.

For example:

```bash
yarn generate nl
```

creates a Dutch language scaffold containing the full vocabulary, diagnostics, editor text and Usage-documentation contract, then regenerates documentation. Fill the translations and choose `language.order`, then run the same command again to validate/regenerate it. No parser, linter, lexer, MkDocs or VS Code source registry needs to be edited.

## Development

Bootstrap:

```bash
corepack enable
yarn setup
```

Run tests:

```bash
yarn test
```

Run the documentation locally:

```bash
yarn dev
```

LAN/mobile documentation server:

```bash
yarn dev:lan
```

Full validation before committing/releasing:

```bash
yarn bfc
```

`yarn bfc` synchronizes the project version from `package.json`, validates version consistency, lints, runs tests, regenerates/checks/builds the documentation, and builds the Python package.

### Version source of truth

`package.json` is the **single source of truth** for the project version.

```bash
yarn version:sync
```

synchronizes derived Python metadata and the version displayed in this README. MkDocs narrative pages can use:

```text
__PSEUDOCODE_I18N_VERSION__
```

and `site/hooks/version.py` replaces that placeholder from `package.json` during the documentation build.

### Documentation policy

Documentation is part of every change. Grammar, CLI, configuration, formatting, transpilation, flowcharts, language data, highlighting vocabulary and development workflow changes must update their corresponding documentation in the same revision.

The MkDocs home page is generated from this README, so the repository landing page and documentation landing page cannot silently drift apart.

## License

GNU General Public License version 3 or later (**GPL-3.0-or-later**). See [`LICENSE`](https://gitlab.com/rod2ik/pseudocode-i18n/-/blob/main/LICENSE).

## AUTRES PROJETS de ce développeur

The Pseudocode ecosystem is split into small reusable projects so that each integration can share the same grammar instead of reimplementing it:

- **[pygments-lexer-pseudocode-i18n](https://gitlab.com/rod2ik/pygments-lexer-pseudocode-i18n)** — Pygments lexer using the common multilingual semantic vocabulary and Python-like token categories.
- **[mkdocs-pseudocode-i18n](https://gitlab.com/rod2ik/mkdocs-pseudocode-i18n)** — MkDocs integration for pseudocode in teaching/documentation sites.
- **[vscode-pseudocode-i18n](https://gitlab.com/rod2ik/vscode-pseudocode-i18n)** — editor integration for `.pseudo`/`.algo` files, formatting and language-aware authoring.

The core project is **[pseudocode-i18n](https://gitlab.com/rod2ik/pseudocode-i18n)** and its documentation is published at **[rod2ik.gitlab.io/pseudocode-i18n](https://rod2ik.gitlab.io/pseudocode-i18n/)**.
