Syntax10.Scn.Fnt FoldElems Syntax10.Scn.Fnt This is a short demo that shows the use of fold elements. a) Middle-click at a filled triangle (e.g. behind the procedure Insert). The procedure body is shown. Middle-click at the non-filled triangle. The procedure body is collapsed again. b) Expand procedure Insert and then its local procedure Ins. You find two pseudocode actions that can also be expanded. c) Make a new fold element by selecting some text and executing FoldElems.Insert d) Compile this file with FoldComp.Compile */s A (deliberate) error is reported. Set the caret at the beginning of the text and execute FoldComp.ShowError . The error location is revealed and marked with a small rectangle. middle-click at it to get the error message. e) FoldElems.Expand expands all elements. FoldElems.Collapse collapses them all. Syntax10i.Scn.Fnt Syntax10.Scn.Fnt VAR s: Texts.Scanner; BEGIN Texts.OpenScanner(s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(s); IF s.class = Texts.Name THEN COPY(s.s, n) ELSE n := "" END END GetName; Syntax10.Scn.Fnt FoldElems Syntax10.Scn.Fnt FoldElems Syntax10.Scn.Fnt FoldElems Syntax10.Scn.Fnt GraphicElems Alloc Rectangles Syntax10.Scn.Fnt father Syntax10i.Scn.Fnt p := tree; father := NIL; WHILE p # NIL DO IF elem.name = p.name THEN RETURN END; father := p; IF elem.name < p.name THEN p := p.left ELSE p := p.right END END; see picture Syntax10i.Scn.Fnt Syntax10.Scn.Fnt IF father = NIL THEN tree := elem ELSIF elem.name < father.name THEN father.left := elem ELSE father.right := elem END VAR p, father: Node; BEGIN elem.left := NIL; elem.right := NIL; find insertion place (father) insert elem under father END Ins; VAR x: Node; PROCEDURE Ins(elem: Node); BEGIN NEW(x); GetName(x.name); Ins(x) END Insert; Syntax10.Scn.Fnt FoldElems Syntax10.Scn.Fnt BEGIN IF x # NIL THEN P(x.left); Texts.WriteString(w, x.name); Texts.WriteLn(w); P(x.right) END END P; PROCEDURE P(x: Node); BEGIN P(tree); Texts.Append(Oberon.Log, w.buf) END Print; Syntax10.Scn.Fnt FoldElems Syntax10.Scn.Fnt VAR p, x, y, father: Node; BEGIN p := tree; father := NIL; WHILE (p # NIL) & (name # p.name) DO father := p; IF name < p.name THEN p := p.left ELSE p := p.right END END; IF p # NIL THEN IF p.right = NIL THEN x := p.left ELSIF p.right.left = NIL THEN x := p.right; x.left := p.left ELSE x := p.right; WHILE x.left # NIL DO y := x; x := x.left END; y.left := x.right; x.left := p.left; x.right := p.right END; IF father = NIL THEN tree := x ELSIF name < father.name THEN father.left := x ELSE father.right := x END END END Del; VAR name: Name; PROCEDURE Del(name: Name); BEGIN GetName(name); Del(name); END Delete; read me MODULE FoldDemo; IMPORT Oberon, Texts; Name = ARRAY 32 OF CHAR; Node = POINTER TO NodeDesc; NodeDesc = RECORD name: Name; left, right: Node END; VAR tree: Node; w: Texts.Writer; PROCEDURE GetName(VAR n: Name); PROCEDURE Insert*; PROCEDURE Print*; PROCEDURE Delete*; BEGIN tree := NIL; Texts.OpenWriter(w) END FoldDemo.