Skip to content
This repository was archived by the owner on Nov 7, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format is loosely inspired by Keep a Changelog.

### Added

- **Web 0.13.7, statements without class are coloured too:** when Programmieren shows the code without `class` and `main` (e.g. „Aufstehen;“, „Zähne putzen;“ in lesson 1), the statements now sit in a yellow block like a method, matching the yellow statements in the Struktogramm; loops and branches inside keep their own colours. Statements are now always yellow, also inside a loop or branch (own yellow stripe in the code, yellow box in the Struktogramm and in lesson 1); only the empty ø takes the colour of its block. A loop with pseudocode condition (`while (Tee noch zu heiß) {`) is coloured up to its closing brace.
- **Web 0.13.6, lesson header pinned at the top:** in a lesson step the header (← Alle Lektionen, lesson title, step numbers, step title) stays at the top of the lesson column with its own ← Zurück / Weiter → buttons next to „Alle Lektionen“; only the step content below scrolls. The buttons at the end of the step stay as well.
- **Web 0.13.4, Pseudocode switch in the toolbar and simulation of pseudocode:** the checkbox „Pseudocode“ now sits in the toolbar left of ⇄ (before it was only in the code window). For a diagram marked as pseudocode (e.g. „Tee kochen“ in Lektion 1) the simulation no longer runs the boxes as Java: it only highlights them one after another, and for a condition („Regnet es?“), a loop or a Fallauswahl it asks for the answer (true/false or ja/nein, case name). Programmieren shows no Java errors for pseudocode. Lektion 1 now mentions spaghetti code right where it says a Struktogramm has no jumps.
- **Web 0.13.3, Struktogramm and Elemente in the code block colours:** the Struktogramm uses the same soft colours as the blocks in Programmieren: statements yellow like the method, loops (for, while, do-until, endless) pink, Verzweigung and Fallauswahl blue; elements inside a loop or branch take its colour, so code and diagram side by side show the matching blocks at a glance. The boxes in „Elemente“ get the same colours. The setting is now called „Blöcke farbig“ and switches code, diagram and Elemente together; a colour stored in the file still wins, and exports stay white. Lesson 1 uses the same colours (statements yellow, branch blue, loop pink; the sequence itself has no colour, it is the row of statements).
Expand Down
2 changes: 1 addition & 1 deletion web/lessons/de/01-was-ist-ein-struktogramm.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Solange der Teller nicht leer ist, wird ein Bissen gegessen. Danach wird der Tel

## Alle drei zusammen

Richtig nützlich werden die Bausteine, wenn man sie kombiniert. Das Diagramm enthält alle drei: eine Sequenz von oben nach unten, eine [Verzweigung]{.blau} und eine [Schleife]{.rosa}. Gelb sind die einfachen [Anweisungen]{.gelb}. Was in einer Verzweigung oder Schleife steht, bekommt deren Farbe. Genau genommen ist das ganze Diagramm eine Sequenz, denn auch Verzweigung und Schleife stehen in der Reihe von oben nach unten.
Richtig nützlich werden die Bausteine, wenn man sie kombiniert. Das Diagramm enthält alle drei: eine Sequenz von oben nach unten, eine [Verzweigung]{.blau} und eine [Schleife]{.rosa}. Gelb sind die einfachen [Anweisungen]{.gelb}. Auch die Anweisungen in einer Verzweigung oder Schleife sind gelb. Genau genommen ist das ganze Diagramm eine Sequenz, denn auch Verzweigung und Schleife stehen in der Reihe von oben nach unten.

::: diagramm l1-grundbausteine.visustruct
Die Verzweigung erkennst du am Dreieck, die Schleife an der Klammer links. Alles zusammen steht in einer Sequenz.
Expand Down
4 changes: 2 additions & 2 deletions web/lessons/diagramme/en/l1-grundbausteine.visustruct
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<strelem typ="1" zx="0" zy="0" bgcolor="-1773059">
<text>83;117;103;97;114;32;119;97;110;116;101;100;63;</text>
<fall fallname="116;114;117;101;">
<strelem typ="0" zx="0" zy="0" bgcolor="-1773059">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>65;100;100;32;115;117;103;97;114;</text>
</strelem>
</fall>
Expand All @@ -19,7 +19,7 @@
<strelem typ="4" zx="0" zy="0" bgcolor="-202254">
<text>84;101;97;32;115;116;105;108;108;32;116;111;111;32;104;111;116;</text>
<schleifeninhalt>
<strelem typ="0" zx="0" zy="0" bgcolor="-202254">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>87;97;105;116;32;49;32;109;105;110;117;116;101;</text>
</strelem>
</schleifeninhalt>
Expand Down
4 changes: 2 additions & 2 deletions web/lessons/diagramme/en/l1-verzweigung.visustruct
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<strelem typ="1" zx="0" zy="0" bgcolor="-1773059">
<text>73;115;32;105;116;32;114;97;105;110;105;110;103;63;</text>
<fall fallname="116;114;117;101;">
<strelem typ="0" zx="0" zy="0" bgcolor="-1773059">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>80;97;99;107;32;97;110;32;117;109;98;114;101;108;108;97;</text>
</strelem>
</fall>
<fall fallname="102;97;108;115;101;">
<strelem typ="0" zx="0" zy="0" bgcolor="-1773059">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>80;97;99;107;32;115;117;110;103;108;97;115;115;101;115;</text>
</strelem>
</fall>
Expand Down
2 changes: 1 addition & 1 deletion web/lessons/diagramme/en/l1-wiederholung.visustruct
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<strelem typ="4" zx="0" zy="0" bgcolor="-202254">
<text>80;108;97;116;101;32;110;111;116;32;101;109;112;116;121;</text>
<schleifeninhalt>
<strelem typ="0" zx="0" zy="0" bgcolor="-202254">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>84;97;107;101;32;97;32;98;105;116;101;</text>
</strelem>
</schleifeninhalt>
Expand Down
4 changes: 2 additions & 2 deletions web/lessons/diagramme/l1-grundbausteine.visustruct
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<strelem typ="1" zx="0" zy="0" bgcolor="-1773059">
<text>90;117;99;107;101;114;32;103;101;119;252;110;115;99;104;116;63;</text>
<fall fallname="116;114;117;101;">
<strelem typ="0" zx="0" zy="0" bgcolor="-1773059">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>90;117;99;107;101;114;32;104;105;110;101;105;110;103;101;98;101;110;</text>
</strelem>
</fall>
Expand All @@ -19,7 +19,7 @@
<strelem typ="4" zx="0" zy="0" bgcolor="-202254">
<text>84;101;101;32;110;111;99;104;32;122;117;32;104;101;105;223;</text>
<schleifeninhalt>
<strelem typ="0" zx="0" zy="0" bgcolor="-202254">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>49;32;77;105;110;117;116;101;32;119;97;114;116;101;110;</text>
</strelem>
</schleifeninhalt>
Expand Down
4 changes: 2 additions & 2 deletions web/lessons/diagramme/l1-verzweigung.visustruct
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<strelem typ="1" zx="0" zy="0" bgcolor="-1773059">
<text>82;101;103;110;101;116;32;101;115;63;</text>
<fall fallname="116;114;117;101;">
<strelem typ="0" zx="0" zy="0" bgcolor="-1773059">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>82;101;103;101;110;115;99;104;105;114;109;32;101;105;110;112;97;99;107;101;110;</text>
</strelem>
</fall>
<fall fallname="102;97;108;115;101;">
<strelem typ="0" zx="0" zy="0" bgcolor="-1773059">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>83;111;110;110;101;110;98;114;105;108;108;101;32;101;105;110;112;97;99;107;101;110;</text>
</strelem>
</fall>
Expand Down
2 changes: 1 addition & 1 deletion web/lessons/diagramme/l1-wiederholung.visustruct
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<strelem typ="4" zx="0" zy="0" bgcolor="-202254">
<text>84;101;108;108;101;114;32;110;105;99;104;116;32;108;101;101;114;</text>
<schleifeninhalt>
<strelem typ="0" zx="0" zy="0" bgcolor="-202254">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>69;105;110;101;110;32;66;105;115;115;101;110;32;101;115;115;101;110;</text>
</strelem>
</schleifeninhalt>
Expand Down
4 changes: 2 additions & 2 deletions web/lessons/diagramme/pt/l1-grundbausteine.visustruct
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<strelem typ="1" zx="0" zy="0" bgcolor="-1773059">
<text>81;117;101;114;32;97;231;250;99;97;114;63;</text>
<fall fallname="116;114;117;101;">
<strelem typ="0" zx="0" zy="0" bgcolor="-1773059">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>74;117;110;116;97;114;32;97;231;250;99;97;114;</text>
</strelem>
</fall>
Expand All @@ -19,7 +19,7 @@
<strelem typ="4" zx="0" zy="0" bgcolor="-202254">
<text>67;104;225;32;97;105;110;100;97;32;100;101;109;97;115;105;97;100;111;32;113;117;101;110;116;101;</text>
<schleifeninhalt>
<strelem typ="0" zx="0" zy="0" bgcolor="-202254">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>69;115;112;101;114;97;114;32;49;32;109;105;110;117;116;111;</text>
</strelem>
</schleifeninhalt>
Expand Down
4 changes: 2 additions & 2 deletions web/lessons/diagramme/pt/l1-verzweigung.visustruct
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<strelem typ="1" zx="0" zy="0" bgcolor="-1773059">
<text>69;115;116;225;32;97;32;99;104;111;118;101;114;63;</text>
<fall fallname="116;114;117;101;">
<strelem typ="0" zx="0" zy="0" bgcolor="-1773059">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>76;101;118;97;114;32;103;117;97;114;100;97;45;99;104;117;118;97;</text>
</strelem>
</fall>
<fall fallname="102;97;108;115;101;">
<strelem typ="0" zx="0" zy="0" bgcolor="-1773059">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>76;101;118;97;114;32;243;99;117;108;111;115;32;100;101;32;115;111;108;</text>
</strelem>
</fall>
Expand Down
2 changes: 1 addition & 1 deletion web/lessons/diagramme/pt/l1-wiederholung.visustruct
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<strelem typ="4" zx="0" zy="0" bgcolor="-202254">
<text>80;114;97;116;111;32;110;227;111;32;118;97;122;105;111;</text>
<schleifeninhalt>
<strelem typ="0" zx="0" zy="0" bgcolor="-202254">
<strelem typ="0" zx="0" zy="0" bgcolor="-133925">
<text>68;97;114;32;117;109;97;32;103;97;114;102;97;100;97;</text>
</strelem>
</schleifeninhalt>
Expand Down
2 changes: 1 addition & 1 deletion web/lessons/en/01-was-ist-ein-struktogramm.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ As long as the plate is not empty, you take a bite. After that, the plate is cle

## All three together

The building blocks become really useful when you combine them. This diagram contains all three: a sequence from top to bottom, a [branch]{.blau} and a [loop]{.rosa}. The yellow boxes are simple [statements]{.gelb}. Whatever stands inside a branch or a loop takes its colour. Strictly speaking, the whole diagram is a sequence, because the branch and the loop also stand in the row from top to bottom.
The building blocks become really useful when you combine them. This diagram contains all three: a sequence from top to bottom, a [branch]{.blau} and a [loop]{.rosa}. The yellow boxes are simple [statements]{.gelb}. The statements inside a branch or a loop are yellow too. Strictly speaking, the whole diagram is a sequence, because the branch and the loop also stand in the row from top to bottom.

::: diagramm l1-grundbausteine.visustruct
You recognise the branch by its triangle and the loop by the bracket on the left. Everything together sits in a sequence.
Expand Down
2 changes: 1 addition & 1 deletion web/lessons/pt/01-was-ist-ein-struktogramm.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Enquanto o prato não estiver vazio, dás uma garfada. Depois, o prato é levant

## Os três juntos

Os blocos básicos tornam-se realmente úteis quando os combinas. Este diagrama contém os três: uma sequência de cima para baixo, uma [decisão]{.blau} e um [ciclo]{.rosa}. As caixas amarelas são [instruções]{.gelb} simples. O que está dentro de uma decisão ou de um ciclo fica com a cor dela. Em rigor, o diagrama todo é uma sequência, porque a decisão e o ciclo também estão na fila de cima para baixo.
Os blocos básicos tornam-se realmente úteis quando os combinas. Este diagrama contém os três: uma sequência de cima para baixo, uma [decisão]{.blau} e um [ciclo]{.rosa}. As caixas amarelas são [instruções]{.gelb} simples. As instruções dentro de uma decisão ou de um ciclo também são amarelas. Em rigor, o diagrama todo é uma sequência, porque a decisão e o ciclo também estão na fila de cima para baixo.

::: diagramm l1-grundbausteine.visustruct
Reconheces a decisão pelo triângulo e o ciclo pelo parêntese à esquerda. Tudo junto forma uma sequência.
Expand Down
4 changes: 2 additions & 2 deletions web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "visustruct-web",
"private": true,
"version": "0.13.6",
"version": "0.13.7",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
Binary file added web/prog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 45 additions & 2 deletions web/src/ui/javaEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { autocompletion, closeBrackets, closeBracketsKeymap, completionKeymap, s
import { defaultKeymap, indentWithTab } from '@codemirror/commands'
import { java } from '@codemirror/lang-java'
import { bracketMatching, HighlightStyle, indentOnInput, indentUnit, syntaxHighlighting, syntaxTree } from '@codemirror/language'
import { Annotation, type ChangeSpec, Compartment, countColumn, EditorSelection, EditorState, Prec, RangeSet, RangeSetBuilder, StateEffect, StateField, type Extension } from '@codemirror/state'
import { Annotation, type ChangeSpec, Compartment, countColumn, EditorSelection, EditorState, Prec, RangeSet, RangeSetBuilder, StateEffect, StateField, type Extension, type Text } from '@codemirror/state'
import { Decoration, EditorView, gutter, GutterMarker, highlightActiveLineGutter, keymap, layer, lineNumbers, RectangleMarker, type BlockInfo, type DecorationSet } from '@codemirror/view'
import { tags } from '@lezer/highlight'
import { indentJava } from '../core/javaIndent'
Expand Down Expand Up @@ -123,6 +123,24 @@ const scopeKinds: Record<string, string> = {
TryStatement: 'try',
}

/**
* Zeile der `}`, die den Block schließt, der in der Zeile von `pos` mit `{` beginnt. Bei Pseudocode
* (`while (Tee noch zu heiß) {`) bricht der Java-Parser den Block nach der ersten Zeile ab; so reicht der Kasten
* trotzdem bis zur schließenden Klammer wie im Struktogramm.
*/
function closingLine(doc: Text, pos: number): number {
const first = doc.lineAt(pos)
if (!first.text.trimEnd().endsWith('{')) return first.number
let depth = 0
for (let n = first.number; n <= doc.lines; n++) {
for (const ch of doc.line(n).text.replace(/"(?:[^"\\]|\\.)*"|\/\/.*$/g, '')) {
if (ch === '{') depth++
else if (ch === '}' && --depth === 0) return n
}
}
return first.number
}

/**
* Jeder Block (Klasse, Methode, Schleife, Verzweigung …) bekommt einen eigenen Kasten, der bei seiner
* Einrückung beginnt; die Kästen liegen ineinander. Das ausgewählte Element bekommt einen Rahmen darüber.
Expand Down Expand Up @@ -151,7 +169,20 @@ function scopeMarkers(view: EditorView): RectangleMarker[] {
return new RectangleMarker(className, left, top, Math.max(right - left, 20), Math.max(bottom - top, 4))
}
const markers: RectangleMarker[] = []
// Anweisungen ohne Klasse und Methode (Einstellung ohne `class`/`main`): ein gelber Kasten wie die Methode,
// damit sie wie die Anweisungen im Struktogramm aussehen.
const top = syntaxTree(state).topNode
const loose: { from: number; to: number }[] = []
for (let c = top.firstChild; c; c = c.nextSibling) {
if (scopeKinds[c.name] === 'class' || c.name === 'MethodDeclaration') {
loose.length = 0
break
}
if (c.name !== 'ImportDeclaration' && c.name !== 'PackageDeclaration' && !c.name.includes('Comment')) loose.push(c)
}
if (loose.length) markers.push(box('cm-scope cm-scope-method', doc.lineAt(loose[0].from).number, doc.lineAt(loose[loose.length - 1].to).number, 1))
// Äußere Blöcke zuerst: Die inneren liegen darüber.
const blocks: { kind: string; from: number; to: number }[] = []
syntaxTree(state).iterate({
from: view.viewport.from,
to: view.viewport.to,
Expand All @@ -160,9 +191,21 @@ function scopeMarkers(view: EditorView): RectangleMarker[] {
if (!kind) return
// `else if` gehört zum Kasten des ersten `if`.
if (node.name === 'IfStatement' && node.node.parent?.name === 'IfStatement') return
markers.push(box(`cm-scope cm-scope-${kind}`, doc.lineAt(node.from).number, doc.lineAt(node.to).number, 1))
const from = doc.lineAt(node.from).number
const to = Math.max(doc.lineAt(node.to).number, closingLine(doc, node.from))
blocks.push({ kind, from, to })
markers.push(box(`cm-scope cm-scope-${kind}`, from, to, 1))
},
})
// Anweisungen in Schleifen und Verzweigungen bekommen wie im Struktogramm einen eigenen gelben Streifen.
for (let n = 1; n <= doc.lines; n++) {
let inner: { kind: string; from: number; to: number } | undefined
for (const b of blocks) if (b.from <= n && n <= b.to && (!inner || b.from >= inner.from)) inner = b
if (!inner || (inner.kind !== 'loop' && inner.kind !== 'if') || n === inner.from) continue
const text = doc.line(n).text.trim()
if (!text || text.startsWith('}') || text.endsWith('{') || text.startsWith('//') || text.startsWith('case ') || text.startsWith('default')) continue
markers.push(box('cm-scope cm-scope-method cm-scope-stmt', n, n, 2))
}
const sel = state.field(marksField).marks.lines
if (sel && sel.from < doc.lines) markers.push(box('cm-scope cm-scope-sel', sel.from + 1, Math.min(sel.to + 1, doc.lines), 0))
return markers
Expand Down
5 changes: 3 additions & 2 deletions web/src/ui/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const Ink = {

type Omission = { top?: boolean; left?: boolean; bottom?: boolean; right?: boolean }

/** Farbe wie bei den Codeblöcken (`cm-scope-…`): Schleife rosa, Verzweigung blau, alles andere erbt die Farbe des Blocks, in dem es steht; ganz außen gelb wie die Methode `main` im Code. */
/** Farbe wie bei den Codeblöcken (`cm-scope-…`): Schleife rosa, Verzweigung blau, Anweisungen gelb wie die Methode im Code. */
export function scopeKind(type: ElementType): string | undefined {
switch (type) {
case ElementType.forSchleife:
Expand Down Expand Up @@ -213,7 +213,8 @@ export class DiagramRenderer {
const bg = e.backgroundColor
const own = bg && bg.a > 0 ? `rgba(${bg.r}, ${bg.g}, ${bg.b}, ${bg.a / 255})` : 'white'
const fill = isSelected && (sim || this.fillsSelection) ? 'rgba(199, 230, 255, 0.55)' : own
const scope = scopeKind(e.type) ?? parentScope
// Anweisung, Aufruf, Aussprung immer gelb; nur der leere Platzhalter ø nimmt die Farbe des Blocks.
const scope = scopeKind(e.type) ?? (e.type === ElementType.leerElement ? parentScope : 'method')
// Fläche in der Farbe des Blocks per CSS (Einstellung „Blöcke farbig“); im Export bleibt sie weiß.
const area = el('rect', { x: r.x, y: r.y, width: r.width, height: r.height, fill })
if (fill === 'white' && scope) area.setAttribute('class', `ns-scope ns-scope-${scope}`)
Expand Down
2,504 changes: 1,252 additions & 1,252 deletions website/app/assets/index-C0CXDsrV.js → website/app/assets/index-FLiLJX9D.js

Large diffs are not rendered by default.

Loading
Loading