Syntax10.Scn.FntSyntax10b.Scn.Fnt Syntax10i.Scn.Fnt`=IStampElemsAlloc11 Mar 984K x8FoldElemsNew#Syntax10.Scn.Fnt END NoNotify; 8 88 )  c;8#Syntax10.Scn.Fnt VAR opener: Opener; BEGIN NEW(opener); COPY(pattern, opener.pattern); COPY(command, opener.cmd); opener.next := openers; openers := opener END RegisterOpener; 8 x68#Syntax10.Scn.Fnt VAR s: Texts.Scanner; text: Texts.Text; beg, end, time: LONGINT; openers, opener: Opener; BEGIN Texts.OpenScanner(s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(s); IF (s.class = Texts.Char) & (s.c = "^") THEN Oberon.GetSelection(text, beg, end, time); IF time >= 0 THEN Texts.OpenScanner(s, text, beg); Texts.Scan(s) END END ; IF s.class IN {Texts.Name, Texts.String} THEN NEW(text); Texts.Open(text, s.s); IF text.len # 0 THEN Texts.OpenScanner(s, text, 0); Texts.Scan(s); openers := NIL; WHILE s.class IN {Texts.Name, Texts.String} DO NEW(opener); COPY(s.s, opener.pattern); Texts.Scan(s); COPY(s.s, opener.cmd); Texts.Scan(s); IF (opener.pattern # "") & (opener.cmd # "") THEN opener.next := openers; openers := opener END END ; opener := openers; WHILE opener # NIL DO RegisterOpener(opener.pattern, opener.cmd); opener := opener.next END END END END RegisterOpeners; 898#Syntax10.Scn.Fnt VAR par: Oberon.ParList; res: INTEGER; BEGIN Texts.OpenWriter(w); NEW(scratch); Texts.Open(scratch, ""); scratch.notify := NoNotify; openers := NIL; RegisterOpener("*", "Edit.Open"); NEW(par); par.text := scratch; par.pos := 0; par.vwr := Viewers.This(0, 0); par.frame := par.vwr; Texts.WriteString(w, profile); Texts.Append(scratch, w.buf); Oberon.Call("Documents.RegisterOpeners", par, FALSE, res) END Init; 8pMODULE Documents; (* CS, 12 Aug 97 -  *) IMPORT Viewers, Texts, Oberon, Strings; CONST profile* = "Documents.Profile"; (** on startup all openers contained in this file are registered automatically *) optionChar = "\"; TYPE Opener* = POINTER TO RECORD pattern-, cmd-: ARRAY 32 OF CHAR; next-: Opener END ; VAR openers-: Opener; scratch: Texts.Text; w: Texts.Writer; PROCEDURE NoNotify (t: Texts.Text; op: INTEGER; beg, end: LONGINT);  PROCEDURE Open*; (** ^ | name Opens the specified file with the registered opener, if no specific opener is found for the extension of the file, Edit.Open is used. *) CONST TAB = 9X; CR = 0DX; VAR s: Texts.Scanner; r: Texts.Reader; o: Opener; i: INTEGER; res: INTEGER; pos, end, time: LONGINT; text: Texts.Text; str: ARRAY 256 OF CHAR; ch, quote: CHAR; BEGIN str := ""; text := Oberon.Par.text; pos := Oberon.Par.pos; Texts.OpenScanner(s, text, pos); Texts.Scan(s); IF (s.class = Texts.Char) & (s.c = "^") THEN Oberon.GetSelection(text, pos, end, time); IF time < 0 THEN RETURN END END ; Texts.OpenReader(r, text, pos); i := 0; Texts.Read(r, ch); WHILE ~r.eot & ((ch = " ") OR (ch = TAB) OR (ch = CR)) DO Texts.Read(r, ch) END ; (* skip white spaces *) IF (ch = "'") OR (ch = '"') THEN quote := ch; REPEAT Texts.Read(r, ch); str[i] := ch; INC(i) UNTIL r.eot OR (ch = quote) OR (ch = " ") OR (i = LEN(str)); str[i - 1] := 0X ELSE WHILE ~r.eot & ~((ch = " ") OR (ch = TAB) OR (ch = CR) OR (ch = optionChar) OR (i = LEN(str))) DO str[i] := ch; Texts.Read(r, ch); INC(i) END ; str[i] := 0X END ; o := openers; WHILE ~Strings.Match(str, o.pattern) DO o := o.next END ; Oberon.Call(o.cmd, Oberon.Par, FALSE, res) END Open;  PROCEDURE RegisterOpener* (pattern, command: ARRAY OF CHAR); (** Registers the opener command for the pattern. Openers that are registered earlier can be overwritten by (more specific) openers registered later. *) PROCEDURE RegisterOpeners*; (** ^ | filename Registers all the openers contained in the specified file. Their precedence is as they appear in the file. *)  PROCEDURE Init;  BEGIN Init END Documents. Documents.Open ^ Documents.Profile System.Free Documents ~ System.State Documents ~