$Syntax10.Scn.FntSyntax10i.Scn.Fnt09 StampElemsAlloc2003-Mar-25ApVersionElemsAllocBeg#Syntax10.Scn.FntWindows PowerMac LinuxLinuxWindows$Syntax10i.Scn.Fnt (* Windows *)PowerMac$Syntax10i.Scn.Fnt(* PowerMac *)Linux  pVersionElemsAllocEndOp#Syntax10.Scn.FntWindows PowerMac LinuxLinuxWindows#Syntax10.Scn.Fnt , RegistryPowerMac#Syntax10.Scn.Fnt, SysLinux p 8FoldElemsNew#Syntax10.Scn.Fnt Constants"Syntax10b.Scn.Fnt 188#Syntax10.Scn.FntTypes88#Syntax10.Scn.FntGlobal variablesD- j8 MarkElemsAllocP1<88'888H8 m8V8 {'88+8`8A88 c%8l8;88 /!8B8 -8488#Syntax10.Scn.Fnt Compiler.Panel )8y88V8 8.888#Syntax10.Scn.Fnt Parc.Panel 8888B88 8N8E8$8W8<"88 8888#Syntax10.Scn.Fnt** insert a style elem a the caret position d88#Syntax10.Scn.Fnt%% replace selected parc or style elem 88  8D88 8  8E 8F)88  K8L888#Syntax10.Scn.Fnt Print.Panel  Cl88 B8Q8 b8888#Syntax10.Scn.Fnt Calc.Panel L $688 2!CV9(8S8  N8Q8 .8O8 eT8l8 N888 S=8AQ8W8j8 3>>688 3>>888 =58>8 2!58l8 5Z88  8j88 8"8 8$8 888 88888J8e888888 @ 84 E8 8888#Syntax10.Scn.Fnt Files.Panel p8'8  84ep#Syntax10.Scn.FntWindows PowerMac LinuxLinuxWindowsCSyntax10.Scn.FntSyntax10i.Scn.Fnt 5C (* Windows *) mod, len : LONGINT; drives : ARRAY 52 OF S.BYTE; PowerMacSyntax10i.Scn.FntSyntax10.Scn.Fnt      (* PowerMac *) GetVInfo: PROCEDURE (num: INTEGER; name: LONGINT; VAR refNum: INTEGER; VAR freeBytes: LONGINT) : INTEGER; name: ARRAY 256 OF CHAR; ref, num, res, len : INTEGER; free : LONGINT; Linux  pp#Syntax10.Scn.FntWindows PowerMac LinuxLinuxWindowsCSyntax10.Scn.FntSyntax10i.Scn.Fnt O] (* Windows *) mod := Kernel.LoadLibrary("KERNEL32"); Kernel.GetAdr(mod, "GetLogicalDriveStringsA", S.VAL(LONGINT, GetLogicalDriveStrings)); len := GetLogicalDriveStrings (52, S.ADR (drives)); i := 0; WHILE i < len DO Texts.Write(W, "/"); Texts.Write(W, CHR(drives[i])); Texts.WriteString(W, ":/"); Texts.WriteLn(W); INC(i, 4) END; PowerMacSyntax10i.Scn.FntSyntax10.Scn.Fnt  Q  &.8(* PowerMac *) Sys.Assign("GetVInfo", S.ADR (GetVInfo)); num := -1; res := GetVInfo(num, S.ADR(name), ref, free); WHILE res = 0 DO len := ORD(name[0]); FOR i := 1 TO len DO name[i-1] := name[i] END; name[len] := 0X; Texts.Write(W, '/'); Texts.WriteString(W, name); Texts.Write(W, '/'); Texts.WriteLn(W); DEC(num); res := GetVInfo(num, S.ADR(name), ref, free); END; Linux  Sp8 88 Հ188 6#88 ۷88 G8+p#Syntax10.Scn.FntWindows PowerMac LinuxLinuxWindows<Syntax10i.Scn.Fnt Syntax10.Scn.Fnt(* Windows *) ct := Elems.CmdContext; In.Open; In.String(pattern); Registry.Get("System", "WorkingDirectory", workingDir); IF In.Done THEN ChangeTo(workingDir) END PowerMac$Syntax10i.Scn.Fnt(* PowerMac *)Linux  p8 > 88 ;,88 \88 8?888#Syntax10.Scn.Fnt Calender.Panel   f8bg 8# 8 bg88!6Q#888#Syntax10.Scn.Fnt Font.Panel  (8 8  8 8888#Syntax10.Scn.Fnt Help.Panel   88s8:aMODULE ElemsUI; (* CE  portions by CS *) (* Linux *) IMPORT Dates, Oberon, Texts, TextFrames, In, Out, Viewers, StyleElems, MathL, MoreMathL, Display, ParcElems, Documents, XIn, Elems, Strings, Panel, PanelElems, Directories, Kernel, Fonts, S := SYSTEM , Types; CONST OptionChar = "\"; eps = 1.0D-8; eps0 = 0.5D-9; (* Files.Panel *) files = 1; paths = 2; (* errorcodes for calculator *) noErr = 0; synErr = 1; div0 = 2; noFunc = 3;  TYPE StyleElem = POINTER TO StyleElemDesc; StyleElemDesc = RECORD styleElem: StyleElems.Parc; next: StyleElem END;  VAR t : Texts.Text; vwr: Viewers.Viewer; selbeg, selend: LONGINT; (* for StoreSelection and RestoreSelection *) ct : Texts.Text; (* Context *) parText : Texts.Text; par: Oberon.ParList; orgLog, newLog: Texts.Text; W, W1 : Texts.Writer; (* Parc.Panel *) styleElems: StyleElem; (* Files.Panel *) pattern : ARRAY 10 OF CHAR; GetLogicalDriveStrings: PROCEDURE (size, heap: LONGINT): LONGINT; enumMode : SET; filesPar : Oberon.ParList; (* Calc.Panel *) invert, rad : BOOLEAN; base, err : INTEGER; value : LONGREAL; errmsg : ARRAY 30 OF CHAR; res : ARRAY 64 OF CHAR; e : Elems.Elem;  PROCEDURE NoNotify (t : Texts.Text; op : INTEGER; beg, end : LONGINT); END NoNotify; PROCEDURE Call (cmd : ARRAY OF CHAR); BEGIN Texts.Delete(parText, 0, parText.len); Texts.Append (parText, W.buf); Elems.DoCall(cmd, Oberon.Par.vwr, Oberon.Par.frame, parText, 0, FALSE); END Call;  PROCEDURE StoreLog(); BEGIN newLog := TextFrames.Text(""); Oberon.Log := newLog END StoreLog; PROCEDURE Opt(s : ARRAY OF CHAR); BEGIN IF s # "" THEN Texts.Write(W, OptionChar); Texts.WriteString(W, s) END END Opt; PROCEDURE WriteString(name, opt : ARRAY OF CHAR); VAR e : Elems.Elem; s : ARRAY 256 OF CHAR; BEGIN e := Elems.NamedElem(name, ct); Elems.GetString(e, "Value", s); IF s # "" THEN Opt(opt); Texts.WriteString(W, s); Texts.Write(W, " ") END END WriteString; PROCEDURE On (s: ARRAY OF CHAR): BOOLEAN; VAR b : BOOLEAN; BEGIN Elems.GetBoolean(Elems.NamedElem(s, ct), "Value", b); RETURN b END On; PROCEDURE SetCheckBox (s: ARRAY OF CHAR; on, update : BOOLEAN); VAR e : Elems.Elem; BEGIN e := Elems.NamedElem(s, ct); Elems.SetBoolean(e, "Value", on); IF update THEN Elems.UpdateElem(e) END END SetCheckBox; PROCEDURE SetRadio (name, val : ARRAY OF CHAR); VAR e : Elems.Elem; BEGIN e := Elems.NamedElem(name, ct); Elems.SetString(e, "Value", val); END SetRadio; PROCEDURE Scan (VAR s: Texts.Scanner; st: ARRAY OF CHAR); BEGIN Texts.OpenScanner (s, newLog, 0); Texts.Scan (s); IF st = "int" THEN s.i := 0; WHILE ~s.eot & (s.class # Texts.Int) DO Texts.Scan (s) END ELSE s.s := ""; WHILE ~ s.eot & (s.s # st) DO Texts.Scan (s) END; Texts.Scan(s) END END Scan;  PROCEDURE IsCharacter(ch : CHAR) : BOOLEAN; BEGIN RETURN (CAP(ch) >= 'A') & (CAP(ch) <= 'Z') END IsCharacter; PROCEDURE IsDigit(ch : CHAR) : BOOLEAN; BEGIN RETURN (ch >= '0') & (ch <= '9') END IsDigit;  PROCEDURE Comp(command : ARRAY OF CHAR); VAR t: Texts.Text; opt, s : ARRAY 20 OF CHAR; res: INTEGER; beg, end, time: LONGINT; i, j: INTEGER; PROCEDURE Do;  VAR ch: CHAR; error: BOOLEAN; scanner : Texts.Scanner; line: INTEGER; BEGIN error := FALSE; Texts.OpenScanner(scanner, t, beg); Texts.Scan(scanner); WHILE (scanner.class IN {Texts.Name, Texts.String}) & (Texts.Pos(scanner) - scanner.len <= end) & ~error DO Texts.OpenWriter(W); Texts.WriteString(W, scanner.s); line := scanner.line; opt[j] := 0X; i := j; Texts.Scan(scanner); IF (scanner.line = line) & (scanner.class = Texts.Char) & (scanner.c = OptionChar) THEN ch := scanner.nextCh; WHILE ((ch >= "0") & (ch <= "9") OR (ch >= "a") & (ch <= "z")) & (i < LEN(opt) - 1) DO opt[i] := ch; INC(i); Texts.Read(scanner, ch) END ; scanner.nextCh := ch; Texts.Scan(scanner) END; opt[i] := 0X; END END Do;  BEGIN ct := Elems.CmdContext; NEW (par); par.text := TextFrames.Text(""); i := 0; IF On ("idx") THEN opt[i] := "x"; INC(i) END; IF On ("type") THEN opt[i] := "t"; INC(i) END; IF On ("nil") THEN opt[i] := "n"; INC(i) END; IF On ("init") THEN opt[i] := "p"; INC(i) END; IF On ("assert") THEN opt[i] := "s"; INC(i) END; IF On ("pc") THEN opt[i] := "f"; INC(i) END; opt[i] := 0X; j := i; Elems.GetString(Elems.NamedElem("source", ct), "Value", s); IF s = "sel" THEN Oberon.GetSelection(t, beg, end, time); IF time >= 0 THEN Do END ELSIF s = "viewer" THEN Texts.Write(W, "*"); Texts.Write(W, OptionChar); Texts.WriteString(W, opt); Texts.Append(par.text, W.buf); par.vwr := Oberon.MarkedViewer(); IF (par.vwr # NIL) & (par.vwr.dsc # NIL) & (par.vwr.dsc.next IS TextFrames.Frame) THEN par.frame := par.vwr.dsc.next(TextFrames.Frame) ELSE par.frame := NIL END; Oberon.Call(command, par, FALSE, res); Call("Folds.ShowError") ELSIF s = "list" THEN Elems.GetText(Elems.NamedElem("files", ct), "ValueT", t); IF t.len > 0 THEN beg := 0; end := t.len; Do END END END Comp; PROCEDURE FoldsCompile*; BEGIN Comp("Folds.Compile") END FoldsCompile;   PROCEDURE StoreSelection (); VAR beg, end, time: LONGINT; BEGIN XIn.GetSelectionViewer(vwr, t, time, beg, end); IF (t # NIL) & (vwr.dsc # NIL) & (vwr.dsc.next # NIL) & (vwr.dsc.next IS TextFrames.Frame) THEN selbeg := beg; selend := end; ELSE selbeg := -1; selend := -1 END END StoreSelection; PROCEDURE RestoreSelection (); BEGIN IF (vwr.dsc # NIL) & (vwr.dsc.next # NIL) & (vwr.dsc.next IS TextFrames.Frame) THEN TextFrames.SetSelection(vwr.dsc.next(TextFrames.Frame), selbeg, selend) END END RestoreSelection; PROCEDURE ThisStyleElem (VAR n : ARRAY OF CHAR): StyleElems.Parc; VAR next: StyleElem; new: StyleElems.Parc; BEGIN next := styleElems; WHILE (next # NIL) & (next.styleElem.name # n) DO next := next.next END; IF next # NIL THEN NEW(new); StyleElems.Copy(next.styleElem, new); END; RETURN new END ThisStyleElem; PROCEDURE WriteStyles(); VAR help : StyleElem; t : Texts.Text; BEGIN Texts.WriteLn(W); help := styleElems; WHILE help # NIL DO Texts.WriteString(W, help.styleElem.name); Texts.WriteLn(W); help := help.next END; Elems.GetText(Elems.NamedElem("styles", ct), "ValueT", t); Texts.Delete(t, 0, t.len); Texts.Append(t, W.buf) END WriteStyles; PROCEDURE GetStyles(all : BOOLEAN); VAR t : Texts.Text; beg, end, time : LONGINT; PROCEDURE AddStyles (t: Texts.Text); VAR elem, next: StyleElem; r : Texts.Reader; BEGIN Texts.OpenReader(r, t, 0); Texts.ReadElem(r); WHILE ~r.eot DO IF r.elem IS StyleElems.Parc THEN next := styleElems; WHILE (next # NIL) & (next.styleElem.name # r.elem(StyleElems.Parc).name) DO next := next.next END; IF next = NIL THEN (* not yet contained => insert *) NEW(elem); elem.styleElem := r.elem(StyleElems.Parc); elem.next := styleElems; styleElems := elem END END; Texts.ReadElem(r) END END AddStyles; BEGIN IF all THEN styleElems := NIL; t := TextFrames.Text(""); Texts.Open(t, "Styles.Text"); AddStyles(t); END; Oberon.GetSelection(t, beg, end, time); IF time >= 0 THEN AddStyles(t) END; IF ~all THEN WriteStyles() END; END GetStyles;  PROCEDURE Style*; VAR name : ARRAY 64 OF CHAR; VAR t : Texts.Text; beg, end, time : LONGINT; r : Texts.Reader; elem : Texts.Elem; styleElem, newElem: StyleElems.Parc; f: TextFrames.Frame; PROCEDURE Replace (VAR t: Texts.Text; VAR r: Texts.Reader; styleElem: StyleElems.Parc); BEGIN Texts.Delete(t, Texts.Pos(r) - 1, Texts.Pos(r)); Texts.WriteElem(W, styleElem); Texts.Insert(t, Texts.Pos(r) - 1, W.buf); END Replace; BEGIN ct := Elems.CmdContext; Oberon.GetSelection(t, beg, end, time); Elems.GetString(Elems.NamedElem("styles", ct), "Value", name); IF name = "" THEN RETURN END; f := XIn.FocusFrame(TRUE); IF f # NIL THEN IF name # "" THEN styleElem := ThisStyleElem(name); NEW(newElem); IF styleElem # NIL THEN StyleElems.Copy(styleElem, newElem); Texts.WriteElem(W, newElem); Texts.Insert(f.text, f.carloc.pos, W.buf) ELSE Out.String("-- unknown style name: "); Out.String(name); Out.Ln END ELSE Out.String("-- no stylename given$"); END ELSE  Oberon.GetSelection(t, beg, end, time); IF time >= 0 THEN Texts.OpenReader(r, t, beg); Texts.ReadElem(r); IF name # "" THEN elem := r.elem; WITH elem: StyleElems.Parc DO styleElem := ThisStyleElem(name); IF styleElem = NIL THEN Texts.WriteString(W, name); Call("StyleElems.Rename") ELSE Replace(t, r, styleElem) END; | elem: TextFrames.Parc DO styleElem := ThisStyleElem(name); IF styleElem = NIL THEN NEW(styleElem); ParcElems.CopyParc(elem, styleElem); styleElem.handle := StyleElems.Handle; COPY(name, styleElem.name); END; Replace(t, r, styleElem) ELSE END ELSE Out.String("-- no style elem given$") END END END END Style;  PROCEDURE InspectParc*; VAR e : Elems.Elem; s : Texts.Scanner; t : Texts.Text; PROCEDURE Set(name : ARRAY OF CHAR); BEGIN StoreLog(); Texts.WriteString(W, name); Call("Edit.Get"); Scan(s, "int"); Elems.SetInteger(Elems.NamedElem(name, ct), "Value", s.i) END Set; BEGIN ct := Elems.CmdContext; orgLog := Oberon.Log; GetStyles(FALSE); s.s := ""; StoreLog(); Texts.WriteString(W, "adjust"); Call ("Edit.Get"); Scan(s, "adjust"); IF s.eot THEN Texts.WriteString(W, "-- no parc selected"); Texts.WriteLn(W); Texts.Append(orgLog, W.buf) END; SetRadio("adjust", s.s); StoreLog(); Texts.WriteString(W, "columns"); Call("Edit.Get"); Scan(s, "int"); IF s.i = 1 THEN SetRadio("columns", "1") ELSIF s.i = 2 THEN SetRadio("columns", "2") ELSE SetRadio("columns", "noset") END; StoreLog; Texts.WriteString(W, "break"); Call ("Edit.Get"); Scan (s, "break"); e := Elems.NamedElem("break", ct); Elems.SetBoolean(e, "Value", s.s = "before"); Elems.UpdateElem(e); StoreLog; Texts.WriteString(W, "grid"); Call ("Edit.Get"); Scan(s, "grid"); e := Elems.NamedElem("grid", ct); Elems.SetBoolean(e, "Value", s.s = "on"); Elems.UpdateElem(e); Set("first"); Set("left"); Set("width"); Set("lead"); Set("line"); StoreLog; Texts.WriteString(W, "tabs"); Call ("Edit.Get"); Scan(s, "tabs"); IF (s.class = Texts.Char) & (s.c = "*") THEN Texts.Scan(s); SetRadio("tab", "every"); Elems.SetString(Elems.NamedElem("enumt", ct), "Value", ""); Elems.SetInteger(Elems.NamedElem("everyt", ct), "Value", s.i); ELSIF s.class = Texts.Int THEN REPEAT Texts.WriteInt(W, s.i, 0); Texts.Write(W, " "); Texts.Scan(s); UNTIL s.eot OR (s.class # Texts.Int); SetRadio("tab", "enum"); Elems.SetString(Elems.NamedElem("everyt", ct), "Value", ""); Elems.GetText(Elems.NamedElem("enumt", ct), "ValueT", t); Texts.Delete(t, 0, t.len); Texts.Append(t, W.buf) ELSE Elems.SetString(Elems.NamedElem("everyt", ct), "Value", ""); Elems.SetString(Elems.NamedElem("enumt", ct), "Value", ""); SetRadio("tab", "noset"); END; Oberon.Log := orgLog END InspectParc;  PROCEDURE ApplyParc*; VAR str : ARRAY 256 OF CHAR; notifier : Texts.Notifier; PROCEDURE GetString(name : ARRAY OF CHAR); BEGIN Elems.GetString(Elems.NamedElem(name, ct), "Value", str); (*IF str = "" THEN str := "default" END*) END GetString; BEGIN ct := Elems.CmdContext; orgLog := Oberon.Log; StoreSelection(); IF (selbeg = -1) & (selend = -1) THEN Out.String("-- no parc selected$"); RETURN END; notifier := t.notify; t.notify := NoNotify; GetString("adjust"); StoreLog(); Texts.WriteString(W, "adjust "); Texts.WriteString(W, str); Call("Edit.Set"); GetString("columns"); StoreLog(); Texts.WriteString(W, "columns "); Texts.WriteString(W, str); Call("Edit.Set"); StoreLog(); Texts.WriteString(W, "break "); IF On("break") THEN Texts.WriteString(W, "before") ELSE Texts.WriteString(W, "normal") END; Call("Edit.Set"); StoreLog(); Texts.WriteString(W, "grid "); IF On("grid") THEN Texts.WriteString(W, "on") ELSE Texts.WriteString(W, "off") END; Call("Edit.Set"); GetString("first"); StoreLog(); Texts.WriteString(W, "first "); Texts.WriteString(W, str); Call("Edit.Set"); GetString("left"); StoreLog(); Texts.WriteString(W, "left "); Texts.WriteString(W, str); Call("Edit.Set"); GetString("width"); StoreLog(); Texts.WriteString(W, "width "); Texts.WriteString(W, str); Call("Edit.Set"); GetString("lead"); StoreLog(); Texts.WriteString(W, "lead "); Texts.WriteString(W, str); Call("Edit.Set"); GetString("tab"); IF str = "every" THEN StoreLog(); Texts.WriteString(W, "tabs * "); GetString("everyt"); Texts.WriteString(W, str); Call("Edit.Set") ELSIF str = "enum" THEN StoreLog(); Texts.WriteString(W, "tabs "); GetString("enumt"); Texts.WriteString(W, str); Texts.WriteString(W, " ~"); Call("Edit.Set") END; GetString("line"); StoreLog(); Texts.WriteString(W, "line "); Texts.WriteString(W, str); Call("Edit.Set"); t.notify := notifier; t.notify(t, Texts.replace, 0, t.len); RestoreSelection(); Oberon.Log := orgLog END ApplyParc;  PROCEDURE InitParcPanel*; BEGIN ct := Elems.CmdContext; WriteStyles(); InspectParc END InitParcPanel;   PROCEDURE GenPrintParams(); VAR e : Elems.Elem; s : ARRAY 256 OF CHAR; BEGIN Texts.WriteString(W, "none * "); IF On ("draft") THEN Texts.WriteString(W, "% ") END; IF On ("alternate") THEN Opt("a ") END; IF On ("nopagenr") THEN Opt("p n ") END; IF On ("nofirstnr") THEN Opt("p f ") END; IF On ("roman") THEN Opt("p r ") END; WriteString("firstpage", "p "); e := Elems.NamedElem("font", ct); Elems.GetString(e, "Value", s); IF s # "" THEN Opt("f "); Texts.WriteString(W, s); e := Elems.NamedElem("fnts", ct); Elems.GetString(e, "Value", s); Texts.WriteString(W, s); e := Elems.NamedElem("fntt", ct); Elems.GetString(e, "Value", s); IF s[0] # "p" THEN Texts.Write(W, s[0]) END; Texts.WriteString(W, ".Scn.Fnt ") END; WriteString("copies", "c "); e := Elems.NamedElem("header", ct); Elems.GetString(e, "Value", s); IF s = "default" THEN Opt("h ") ELSIF s = "special" THEN Opt("h "); Texts.Write(W, '"'); WriteString("headertext", ""); Texts.Write(W, '"') END; e := Elems.NamedElem("bodypos", ct); Elems.GetString(e, "Value", s); IF s = "custom" THEN Opt("m b "); WriteString("bleft", ""); WriteString("bbot", ""); WriteString("bwidth", ""); WriteString("bheight", "") END; e := Elems.NamedElem("headerpos", ct); Elems.GetString(e, "Value", s); IF s = "custom" THEN Opt("m h "); WriteString("hleft", ""); WriteString("hbot", ""); WriteString("hwidth", ""); END; e := Elems.NamedElem("pages", ct); Elems.GetString(e, "Value", s); IF s = "fromto" THEN Opt("s "); WriteString("from", ""); WriteString("to", "") END END GenPrintParams; PROCEDURE Print*; BEGIN ct := Elems.CmdContext; GenPrintParams(); Call("Edit.Print") END Print; PROCEDURE ShowPrintString*; BEGIN ct := Elems.CmdContext; GenPrintParams(); Out.String("Edit.Print "); Texts.Append(Oberon.Log, W.buf); Out.Ln END ShowPrintString;   (** Calc = Expr "=". Expr = Term {AddOp Term}. Term = Factor {MulOp Factor}. Factor = Atom {"^" Atom}. Atom = number | FuncOrConst | "(" Expr ")". AddOp = "+" | "-". MulOp = " * " | "/". FuncOrConst = name ["(" Expr ")"]. Number = digit {hexDigit | digit} [("." | ",") {hexDigit | digit}] | ("." | ",") {hexDigit | digit}. *) PROCEDURE EvalFunc (f : ARRAY OF CHAR; v : LONGREAL) : LONGREAL; VAR v2 : LONGREAL; BEGIN IF rad THEN v2 := v ELSE v2 := v * MathL.pi / 180 END; IF f = "SIN" THEN IF invert THEN v := MoreMathL.arcsin(v) ELSE v := MathL.sin(v2) END ELSIF f = "ASIN" THEN IF invert THEN v := MathL.sin(v2) ELSE v := MoreMathL.arcsin(v) END ELSIF f = "COS" THEN IF invert THEN v := MoreMathL.arccos(v) ELSE v := MathL.cos(v2) END ELSIF f = "ACOS" THEN IF invert THEN v := MathL.cos(v2) ELSE v := MoreMathL.arccos(v) END ELSIF f = "TAN" THEN IF invert THEN v := MathL.arctan(v) ELSE v := MoreMathL.tan(v2) END ELSIF f = "ATAN" THEN IF invert THEN v := MoreMathL.tan(v2) ELSE v := MathL.arctan(v) END ELSIF f = "LN" THEN IF invert THEN v := MathL.exp(v) ELSE v := MathL.ln(v) END ELSIF f = "EXP" THEN IF invert THEN v := MathL.ln(v) ELSE v := MathL.exp(v) END ELSIF f = "LOG" THEN v := MathL.ln(v) / MathL.ln(10); ELSIF f = "SQRT" THEN IF invert THEN v := v * v ELSE v := MathL.sqrt(v) END ELSE err := noFunc END; RETURN v END EvalFunc; PROCEDURE ^Expr (VAR r : Texts.Reader; VAR ch : CHAR) : LONGREAL; PROCEDURE N (VAR r : Texts.Reader; VAR ch : CHAR); BEGIN Texts.Read(r, ch); WHILE (ch = " ") & ~r.eot DO Texts.Read(r, ch) END END N; PROCEDURE IsNumber (ch : CHAR) : BOOLEAN; BEGIN RETURN (ch >= '0') & (ch <= '9') OR (ch = '.') OR (ch = ",") END IsNumber; PROCEDURE IsHex (ch : CHAR) : BOOLEAN; BEGIN RETURN (ch >= 'A') & (ch <= 'F') OR (ch >= 'a') & (ch <= 'z') END IsHex; PROCEDURE IsChar (ch : CHAR) : BOOLEAN; BEGIN RETURN (ch >= 'a') & (ch <= 'z') OR (ch >= 'A') & (ch <= 'Z') OR (ch = '') OR (ch = '') END IsChar; PROCEDURE Number (VAR r : Texts.Reader; VAR ch : CHAR) : LONGREAL; VAR v, c : LONGREAL; val : INTEGER; BEGIN v := 0; c := 10; WHILE IsNumber(ch) OR IsHex(ch) DO IF IsChar(ch) THEN val := ORD(ch) - ORD('A') + 10 ELSE val := ORD(ch) - ORD('0') END; IF (ch = ".") OR (ch = ",") THEN IF c = 10 THEN c := 1 END ELSIF c = 10 THEN v := v * base + val ELSE c := c / base; v := v + val * c END; N(r, ch) END; RETURN v END Number; PROCEDURE FuncOrConst (VAR r : Texts.Reader; VAR ch : CHAR) : LONGREAL; VAR f : ARRAY 5 OF CHAR; i : INTEGER; v : LONGREAL; PROCEDURE Cap(VAR ch : CHAR) : CHAR; BEGIN IF (ch = "") OR (ch = "") THEN RETURN "" ELSE RETURN CAP(ch) END END Cap; BEGIN i := 0; WHILE IsChar(ch) & (i < 4) DO f[i] := Cap(ch); INC(i); N(r, ch) END; f[i] := 0X; IF ch = "(" THEN N(r, ch); v := Expr(r, ch); IF ch = ")" THEN N(r, ch); v := EvalFunc(f, v) ELSE err := synErr END ELSIF f = "PI" THEN v := MathL.pi ELSIF f = "E" THEN v := MathL.e ELSE err := noFunc END; RETURN v END FuncOrConst; PROCEDURE Atom (VAR r : Texts.Reader; VAR ch : CHAR) : LONGREAL; VAR v : LONGREAL; BEGIN IF IsNumber(ch) THEN v := Number(r, ch) ELSIF ch = "(" THEN N(r, ch); v := Expr(r, ch); IF ch = ")" THEN N(r, ch) ELSE err := synErr END ELSIF IsChar(ch) THEN v := FuncOrConst(r, ch) ELSE err := synErr END; RETURN v END Atom; PROCEDURE Factor (VAR r : Texts.Reader; VAR ch : CHAR) : LONGREAL; VAR v : LONGREAL; BEGIN v := Atom(r, ch); IF ch = "^" THEN N(r, ch); v := MathL.exp(Factor(r, ch) * MathL.ln(v)) END; RETURN v END Factor; PROCEDURE Term(VAR r : Texts.Reader; VAR ch : CHAR) : LONGREAL; VAR v, v2 : LONGREAL; BEGIN v := Factor(r, ch); WHILE (err = noErr) & ((ch = "*") OR (ch = "/")) DO IF ch = "*" THEN N(r, ch); v := v * Factor(r, ch); ELSIF ch = "/" THEN N(r, ch); v2 := Factor(r, ch); IF v2 # 0 THEN v := v / v2 ELSE err := div0 END END; END; RETURN v END Term; PROCEDURE Expr(VAR r : Texts.Reader; VAR ch : CHAR) : LONGREAL; VAR v : LONGREAL; sgn : INTEGER; BEGIN sgn := 1; IF (ch = "-") OR (ch = "+") THEN IF ch = "-" THEN sgn := -1 END; N(r, ch) END; v := sgn * Term(r, ch); WHILE (err = noErr) & ((ch = "-") OR (ch = "+")) DO IF ch = "+" THEN N(r, ch); v := v + Term(r, ch); ELSIF ch = "-" THEN N(r, ch); v := v - Term(r, ch) END; END; RETURN v END Expr; PROCEDURE GetCalcSettings(); VAR s : ARRAY 5 OF CHAR; BEGIN invert := On("invert"); e := Elems.NamedElem("result", ct); e := Elems.NamedElem("result", e(PanelElems.Panel).elemTxt); Elems.GetString(e, "Value", res); Elems.GetLReal(e, "val", value); Elems.GetString(e, "err", errmsg); Elems.GetString(Elems.NamedElem("base", ct), "Value", s); IF s = "hex" THEN base := 16 ELSIF s = "bin" THEN base := 2 ELSIF s = "oct" THEN base := 8 ELSE base := 10 END; Elems.GetString(Elems.NamedElem("gm", ct), "Value", s); rad := s = "rad"; END GetCalcSettings; PROCEDURE ShowResult*; VAR r: Texts.Reader; txt: Texts.Text; i: INTEGER; str: ARRAY 32 OF CHAR; PROCEDURE WrHex (n: LONGREAL); VAR x, y: LONGINT; i: INTEGER; a: ARRAY 10 OF CHAR; BEGIN x := ENTIER(n + eps0); i := 0; REPEAT y := x MOD 10H; IF y < 10 THEN a[i] := CHR(y + 30H) ELSE a[i] := CHR(y + 37H) END; x := x DIV 10H; INC(i) UNTIL i = 8; REPEAT DEC(i) UNTIL (i = 0) OR (a[i] # "0"); IF a[i] >= "A" THEN Texts.Write(W, "0") END; WHILE i >= 0 DO Texts.Write(W, a[i]); DEC(i) END END WrHex;  PROCEDURE WrBin (n: LONGREAL); VAR x: LONGINT; i: INTEGER; a: ARRAY 30 OF CHAR; BEGIN x := ENTIER(n + eps0); i := 0; REPEAT a[i] := CHR(ORD("0") + (x MOD 2)); x := x DIV 2; INC(i) UNTIL i = 28; REPEAT DEC(i) UNTIL (i = 0) OR (a[i] # "0"); WHILE i >= 0 DO Texts.Write(W, a[i]); DEC(i) END END WrBin; PROCEDURE WrOct (n: LONGREAL); VAR x, y: LONGINT; i: INTEGER; a: ARRAY 16 OF CHAR; BEGIN x := ENTIER(n + eps0); i := 0; REPEAT y := x MOD 8; a[i] := CHR(y + 30H); x := x DIV 8; INC(i) UNTIL i = 14; REPEAT DEC(i) UNTIL (i = 0) OR (a[i] # "0"); WHILE i >= 0 DO Texts.Write(W, a[i]); DEC(i) END END WrOct;  PROCEDURE WrDec (n: LONGREAL); VAR x: LONGREAL; y : REAL; BEGIN IF (MIN(LONGINT) <= n) & (n <= MAX(LONGINT)) THEN x := ABS(n - ENTIER(SHORT(n))); IF x < eps THEN Texts.WriteInt(W, ENTIER(n + eps0), 0); RETURN END END; IF (MIN(REAL) <= n) & (n <= MAX(REAL)) THEN y := SHORT(x); x := ABS(n - y); IF x < eps THEN IF (-10000 < n) & (n < 10000) THEN Texts.WriteRealFix(W, SHORT(n + eps0), 0, 6) ELSE Texts.WriteReal(W, SHORT(n + eps0), 14) END; RETURN END END; Texts.WriteLongReal(W, n, 14) END WrDec;  BEGIN ct := Elems.CmdContext; GetCalcSettings(); IF errmsg # "" THEN COPY(errmsg, str) ELSE IF base = 16 THEN WrHex(value) ELSIF base = 2 THEN WrBin(value) ELSIF base = 8 THEN WrOct(value) ELSE WrDec(value) END; txt := TextFrames.Text(""); Texts.Append(txt, W.buf); Texts.OpenReader(r, txt, 0); i := 0; REPEAT Texts.Read(r, str[i]); INC(i) UNTIL r.eot; str[i - 1] := 0X; END; Elems.SetString(Elems.NamedElem("result", ct), "Value", str); Elems.SetString(e, "Value", str); Elems.UpdateElem(e) END ShowResult; PROCEDURE CalcIn*; VAR s : ARRAY 64 OF CHAR; t : Texts.Text; r : Texts.Reader; ch : CHAR; hasCar : BOOLEAN; f : Display.Frame; BEGIN ct := Elems.CmdContext; f := Elems.CmdFrame; WITH f : TextFrames.Frame DO hasCar := f.hasCar ELSE hasCar := FALSE END; GetCalcSettings(); Elems.GetText(Elems.NamedElem("input", ct), "ValueT", t); In.Open; In.String(s); IF (s = "sin") OR (s = "cos") OR (s = "tan") OR (s = "exp") OR (s = "ln") OR (s = "log") THEN IF invert THEN IF (s = "sin") OR (s = "cos") OR (s = "tan") THEN Texts.Write(W, "a") ELSIF s = "exp" THEN s := "ln" ELSIF s = "ln" THEN s := "exp" ELSIF s = "log" THEN s := "10^" END END; Texts.WriteString(W, s); Texts.Write(W, "("); IF t.len = 0 THEN Texts.WriteString(W, res) ELSE Texts.Insert(t, 0, W.buf) END; Texts.Write(W, ")"); Texts.Append(t, W.buf); SetCheckBox("invert", FALSE, TRUE) ELSIF s = "sqrt" THEN IF invert THEN Texts.Write(W, "("); IF t.len = 0 THEN Texts.WriteString(W, res) ELSE Texts.Insert(t, 0, W.buf) END; Texts.WriteString(W, ")^2"); Texts.Append(t, W.buf) ELSE Texts.WriteString(W, s); Texts.Write(W, "("); IF t.len = 0 THEN Texts.WriteString(W, res) ELSE Texts.Insert(t, 0, W.buf) END; Texts.Write(W, ")"); Texts.Append(t, W.buf) END; SetCheckBox("invert", FALSE, TRUE) ELSIF (s = "+") OR (s = "-") OR (s = "*") OR (s = "/") OR (s = "^") THEN IF t.len = 0 THEN Texts.WriteString(W, res) END; Texts.WriteString(W, s); Texts.Append(t, W.buf) ELSIF s = "x" THEN Texts.WriteString(W, "1/("); IF t.len = 0 THEN Texts.WriteString(W, res) ELSE Texts.Insert(t, 0, W.buf) END; Texts.Write(W, ")"); Texts.Append(t, W.buf) ELSIF s = "ce" THEN IF t.len > 0 THEN Texts.Delete(t, t.len - 1, t.len) END ELSIF s = "cl" THEN Texts.Delete(t, 0, t.len) ELSIF s = "=" THEN IF t.len > 0 THEN err := noErr; Texts.OpenReader(r, t, 0); N(r, ch); IF (ch = "+") OR (ch = "-") OR (ch = "*") OR (ch = "/") OR (ch = "^") THEN Texts.WriteString(W, res); Texts.Insert(t, 0, W.buf); Texts.OpenReader(r, t, 0); N(r, ch) END; value := Expr(r, ch); IF (err = 0) & ~r.eot THEN err := synErr END; IF err # 0 THEN Texts.ChangeLooks(t, Texts.Pos(r) - 1, t.len, {1}, NIL, 1, 0); IF err = synErr THEN errmsg := "wrong input" ELSIF err = div0 THEN errmsg := "DIV0" ELSIF err = noFunc THEN errmsg := "unknown Function" END; Elems.SetString(e, "err", errmsg) ELSE Elems.SetLReal(e, "val", value); Elems.SetString(e, "err", ""); Texts.Delete(t, 0, t.len) END; ShowResult() END ELSE Texts.WriteString(W, s); Texts.Append(t, W.buf) END; IF hasCar THEN TextFrames.SetCaret(f(TextFrames.Frame), t.len) END END CalcIn; PROCEDURE SetCalcType*; VAR type : ARRAY 3 OF CHAR; e : Elems.Elem; control : Oberon.ControlMsg; BEGIN control.id := Oberon.neutralize; Elems.CmdFrame.handle(Elems.CmdFrame, control); ct := Elems.CmdContext; Elems.GetString(Elems.NamedElem("type", ct), "Caption", type); e := Elems.NamedElem("input", ct); IF type = ">>" THEN (* expand *) ct(PanelElems.Text).base.W := 3900000; e.W := 3800000; type := "<<" ELSE ct(PanelElems.Text).base.W := 1310000; e.W := 1210000; type := ">>" END; ct(PanelElems.Text).base.H := 1670000; Elems.SetString(Elems.NamedElem("type", ct), "Caption", type); Elems.UpdateElem(ct(PanelElems.Text).base) END SetCalcType; PROCEDURE InitCalcPanel*;  VAR result, e : Elems.Elem; BEGIN ct := Elems.CmdContext; result := Elems.NamedElem("result", ct); Elems.SetString(result, "Value", "0"); result := Elems.NamedElem("result", result(PanelElems.Panel).elemTxt); Elems.SetLReal(result, "val", 0.0); Elems.SetString(result, "Value", "0"); Elems.SetString(result, "err", ""); e := Elems.NamedElem("input", ct); Elems.SetString(e, "Value", ""); END InitCalcPanel;   PROCEDURE EnumFiles (d : Directories.Directory; name : ARRAY OF CHAR; isDir : BOOLEAN; VAR continue : BOOLEAN); BEGIN IF isDir OR Strings.Match(name, pattern) THEN IF isDir & (paths IN enumMode) & ((name[0] # '.') OR (name[1] # 0X)) THEN Texts.WriteString(W, name); Texts.WriteLn(W) ELSIF ~isDir & (files IN enumMode) THEN Texts.WriteString(W1, name); Texts.WriteLn(W1) END END END EnumFiles; PROCEDURE CreateDriveList(); VAR e : Elems.Elem; t : Texts.Text; i : INTEGER; (* Linux *) BEGIN (* Linux *) Texts.WriteString(W, "/"); Texts.WriteLn(W); (* no drive drive letters in linux *) e := Elems.NamedElem("drives", Elems.CmdContext); Elems.SetString(e, "ComboV", ""); Elems.GetText(e, "ValueT", t); Texts.Delete(t, 0, t.len); Texts.Append(t, W.buf); END CreateDriveList; PROCEDURE CreatePatternList(); VAR o : Documents.Opener; e : Elems.Elem; t : Texts.Text; BEGIN Texts.WriteString(W, "*"); Texts.WriteLn(W); Texts.WriteString(W, "*.Mod"); Texts.WriteLn(W); Texts.WriteString(W, "*.Text"); Texts.WriteLn(W); Texts.WriteString(W, "*.Cod"); Texts.WriteLn(W); Texts.WriteString(W, "*.Bak"); Texts.WriteLn(W); o := Documents.openers; WHILE o # NIL DO IF (o.pattern[0] = '*') & (o.pattern[1] # 0X) THEN Texts.WriteString(W, o.pattern); Texts.WriteLn(W) END; o := o.next END; e := Elems.NamedElem("pattern", ct); Elems.GetText(e, "ValueT", t); Texts.Delete(t, 0, t.len); Texts.Append(t, W.buf); Elems.SetString(e, "Value", "*"); END CreatePatternList; PROCEDURE CreateFileList(path : ARRAY OF CHAR; mode : SET); VAR e : Elems.Elem; t : Texts.Text; dir : Directories.Directory; BEGIN IF path = "." THEN dir := Directories.Current() ELSE dir := Directories.This(path) END; IF dir # NIL THEN IF (Elems.NamedElem("paths", ct) = NIL) & (Elems.NamedElem("files", ct) = NIL) THEN RETURN END; enumMode := mode; Directories.Enumerate(dir, EnumFiles); IF paths IN mode THEN e := Elems.NamedElem("paths", ct); Elems.GetText(e, "ValueT", t); Texts.Delete(t, 0, t.len); Texts.Append(t, W.buf) END; IF files IN mode THEN e := Elems.NamedElem("files", ct); Elems.GetText(e, "ValueT", t); Texts.Delete(t, 0, t.len); Texts.Append(t, W1.buf) END END END CreateFileList; PROCEDURE SetPathValue(path : ARRAY OF CHAR); VAR dir : Directories.Directory; BEGIN dir := Directories.This(path); IF dir # NIL THEN Elems.SetString(Elems.NamedElem("path", ct), "Value", dir.path); END END SetPathValue; PROCEDURE ChangeTo(path : ARRAY OF CHAR); BEGIN IF On("change") THEN Directories.Change(path) END; CreateFileList(path, {files, paths}); SetPathValue(path) END ChangeTo; PROCEDURE UpdateWorkPath*; VAR workingDir : ARRAY 256 OF CHAR; BEGIN (* Linux *) END UpdateWorkPath; PROCEDURE UpdatePath*; VAR s : ARRAY 256 OF CHAR; BEGIN ct := Elems.CmdContext; In.Open; In.String(s); In.String(pattern); IF In.Done THEN ChangeTo(s) END END UpdatePath; PROCEDURE InitFilesPanel*; VAR dir : Directories.Directory; s : Texts.Scanner; path : ARRAY 64 OF CHAR; t : Texts.Text; beg, end, time : LONGINT; BEGIN path := ""; ct := Elems.CmdContext; IF filesPar # NIL THEN Texts.OpenScanner(s, filesPar.text, filesPar.pos); Texts.Scan(s); filesPar := NIL ELSE Oberon.GetSelection(t, beg, end, time); IF time >= 0 THEN Texts.OpenScanner(s, t, beg); Texts.Scan(s) END; END; IF s.class IN {Texts.Name, Texts.String} THEN COPY(s.s, path) END; IF path = "" THEN dir := Directories.Current(); COPY(dir.path, path) END; Elems.SetString(Elems.NamedElem("path", ct), "Value", path); Elems.SetString(Elems.NamedElem("pattern", ct), "ComboV", "*"); CreatePatternList(); CreateDriveList(); pattern := "*"; CreateFileList(path, {files, paths}); END InitFilesPanel; PROCEDURE OpenFilesPanel*; VAR p : PanelElems.Panel; fnt : Fonts.Font; col : SHORTINT; BEGIN filesPar := Oberon.Par; Panel.LoadPanel("Files.Panel", p, fnt, col); Panel.OpenPanel(p, "Files.Panel", fnt, col) END OpenFilesPanel; PROCEDURE SearchPattern*; VAR s : ARRAY 128 OF CHAR; t : Texts.Text; BEGIN In.Open; In.String(s); Elems.GetText(Elems.NamedElem("files", Elems.CmdContext), "ValueT", t); Texts.Save(t, 0, t.len, W.buf); Call("Find.Domain"); Texts.WriteString(W, '"'); Texts.WriteString(W, s); Texts.WriteString(W, '"'); Call("Find.All"); END SearchPattern;   PROCEDURE UpdateCalender*; VAR e : Elems.Elem; today, cal : Dates.Date; cw, x, y, day, year, month, daysOfMonth : INTEGER; s : ARRAY 10 OF CHAR; PROCEDURE SetDay(); BEGIN Elems.IntToString(y * 10 + x, s); e := Elems.NamedElem(s, Elems.CmdContext); IF (day < 1) OR (day > daysOfMonth) THEN s := "" ELSE Elems.IntToString(day, s) END; Elems.SetString(e, "Value", s); IF (cal.year = today.year) & (cal.month = today.month) & (day = today.day) THEN (* today *) Elems.SetBoolean(e, "Border", TRUE); Elems.SetBoolean(e, "3D", TRUE) ELSE Elems.SetBoolean(e, "Border", FALSE) END; Elems.UpdateElem(e) END SetDay; PROCEDURE SetCW(); BEGIN Elems.IntToString(y, s); Strings.Insert("cw", 0, s); e := Elems.NamedElem(s, Elems.CmdContext); IF day > daysOfMonth THEN s := "" ELSE Elems.IntToString(cw, s) END; Elems.SetString(e, "Value", s); Elems.UpdateElem(e) END SetCW; BEGIN NEW(today); today.Init(); today.SetToday(); NEW(cal); cal.Init(); In.Open; In.Int(month); In.Int(year); IF In.Done THEN cal.Set(1, month, year); ELSE (* use current month and year *) cal.SetToday(); cal.AddDays(-cal.day + 1); END; (* apply input fields *) cal.MonthName(FALSE, s); Elems.SetString(Elems.NamedElem("month", Elems.CmdContext), "Value", s); Elems.UpdateElem(Elems.NamedElem("month", Elems.CmdContext)); Elems.IntToString(cal.year, s); Elems.SetString( Elems.NamedElem("year", Elems.CmdContext), "ComboV", s); Elems.UpdateElem(Elems.NamedElem("year", Elems.CmdContext)); (* apply days and calender weeks *) daysOfMonth := cal.DaysOfMonth(); day := -(cal.DayOfWeek() - 1); FOR y := 0 TO 5 DO cw := cal.WeekOfYear(); SetCW(); (* cal.AddDays(7); moved below - G. Haynes March 25, 2003 *) FOR x := 0 TO 6 DO cal.AddDays(1); SetDay(); INC(day) END END END UpdateCalender;   PROCEDURE InspectCharacter*; VAR r : Texts.Reader; ct : Texts.Text; ch : CHAR; msg : Oberon.SelectionMsg; str : ARRAY 32 OF CHAR; e : Elems.Elem; i, j : INTEGER; type : Types.Type; BEGIN ct := Elems.CmdContext; IF ct = NIL THEN RETURN END; msg.time := 0; msg.text := NIL; Viewers.Broadcast(msg); IF msg.text # NIL THEN Texts.OpenReader(r, msg.text, msg.beg); Texts.Read(r, ch); e := Elems.NamedElem("ascii", ct); Elems.IntToString(ORD(ch), str); Elems.SetString(e, "Value", str); Elems.UpdateElem(e); e := Elems.NamedElem("col", ct); Elems.SetInteger(e, "Value", r.col); Elems.UpdateElem(e); e := Elems.NamedElem("voff", ct); Elems.IntToString(r.voff, str); Elems.SetString(e, "ComboV", str); Elems.UpdateElem(e); i := 0; j := 0; WHILE (r.fnt.name[i] # 0X) & IsCharacter(r.fnt.name[i]) DO str[j] := r.fnt.name[i]; INC(i); INC(j) END; str[j] := 0X; e := Elems.NamedElem("fnt", ct); Elems.SetString(e, "ComboV", str); Elems.UpdateElem(e); j := 0; WHILE (r.fnt.name[i] # 0X) & IsDigit(r.fnt.name[i]) DO str[j] := r.fnt.name[i]; INC(i); INC(j) END; str[j] := 0X; e := Elems.NamedElem("h", ct); Elems.SetString(e, "ComboV", str); Elems.UpdateElem(e); IF CAP(r.fnt.name[i]) = 'B' THEN str := "bold" ELSIF CAP(r.fnt.name[i]) = 'I' THEN str := "italic" ELSIF CAP(r.fnt.name[i]) = 'M' THEN str := "mark" ELSE str := "plain" END; e := Elems.NamedElem("attr", ct); Elems.SetString(e, "Value", str); Elems.UpdateElem(e); IF ch = Texts.ElemChar THEN type := Types.TypeOf(r.elem); COPY(type.module.name, str); Strings.Append(".", str); Strings.Append(type.name, str) ELSE str := ""; END; e := Elems.NamedElem("elemtype", ct); Elems.SetString(e, "Value", str); Elems.UpdateElem(e) END END InspectCharacter; PROCEDURE ApplyFont*; VAR str : ARRAY 32 OF CHAR; fntName : ARRAY 64 OF CHAR; voff, col : INTEGER; fnt : Fonts.Font; msg : Oberon.SelectionMsg; BEGIN IF Elems.CmdContext = NIL THEN RETURN END; msg.text := NIL; msg.time := 0; Viewers.Broadcast(msg); IF msg.text # NIL THEN In.Open; In.String(str); COPY(str, fntName); In.String(str); Strings.Append(str, fntName); In.String(str); IF CAP(str[0]) = 'I' THEN Strings.Append("i", fntName) ELSIF CAP(str[0]) = 'B' THEN Strings.Append("b", fntName) ELSIF CAP(str[0]) = 'M' THEN Strings.Append("m", fntName) END; Strings.Append(".Scn.Fnt", fntName); fnt := Fonts.This(fntName); IF fnt = NIL THEN Out.String("-- font "); Out.String(fntName); Out.String(" not found$"); RETURN END; In.Int(voff); In.Int(col); StoreSelection(); Texts.ChangeLooks(msg.text, msg.beg, msg.end, {0,1,2}, fnt, SHORT(col), SHORT(voff)); RestoreSelection() END END ApplyFont;   PROCEDURE HelpSearch*; VAR str : ARRAY 250 OF CHAR; BEGIN ct := Elems.CmdContext; IF ~On("source") OR On("def") OR ~On("balloon") OR ~On("text") OR ~On("html") OR ~On("case") OR ~On("modIdx") THEN Texts.Write(W, "\"); IF ~On("source") THEN Texts.Write(W,"m") END; IF On("def") THEN Texts.Write(W, "d") END; IF ~On("balloon") THEN Texts.Write(W, "b") END; IF ~On("text") THEN Texts.Write(W, "t") END; IF ~On("html") THEN Texts.Write(W, "h") END; IF ~On("case") THEN Texts.Write(W, "c") END; IF ~On("modIdx") THEN Texts.Write(W, "f") END; Texts.Write(W, " ") END; Texts.Write(W, '"'); Elems.GetString(Elems.NamedElem("pattern", ct), "Value", str); Texts.WriteString(W, str); Texts.Write(W, '"'); Call("Help.Search") END HelpSearch;  BEGIN parText := TextFrames.Text(""); Texts.OpenWriter (W); Texts.OpenWriter(W1); GetStyles(TRUE); filesPar := NIL;  END ElemsUI. System.Free ElemsUI ~ System.Free Dates ~