home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / jËzyki_programowania / oberon / system / indexelems.mod (.txt) < prev    next >
Oberon Text  |  1977-12-31  |  11KB  |  322 lines

  1. Syntax10.Scn.Fnt
  2. StampElems
  3. Alloc
  4. 14 Feb 96
  5. Syntax10b.Scn.Fnt
  6. MODULE IndexElems;    (* mah  
  7.     IMPORT
  8.         Display, Input, Files, Fonts, Printer, Oberon, Texts, Viewers, MenuViewers, TextFrames, TextPrinter, MarkElems, LinkElems;
  9.     CONST
  10.         middleKey = 1;
  11.         Height = 8*TextFrames.Unit;
  12.         Width = 13*TextFrames.Unit;
  13.     TYPE
  14.         Elem* = POINTER TO ElemDesc;
  15.         ElemDesc* = RECORD(MarkElems.ElemDesc)
  16.             text*: Texts.Text;
  17.             visible, empty: BOOLEAN;
  18.             pno-: INTEGER;
  19.             next: Elem;
  20.         END ;
  21.     EditFrame = POINTER TO EditFrameDesc;
  22.     EditFrameDesc = RECORD (TextFrames.FrameDesc)
  23.         elem: Elem
  24.     END ;
  25.         w: Texts.Writer;
  26.         elems: Elem;
  27.         icon, invIcon: Display.Pattern; (* x = 0, y = -curfnt.minY, w = 13, h = 8 *)
  28.     PROCEDURE GetDsr (f: Display.Frame; pos: LONGINT; fnt: Fonts.Font; VAR dsr: INTEGER);
  29.         VAR p: TextFrames.Parc; beg: LONGINT;
  30.     BEGIN
  31.         IF f = NIL THEN
  32.             IF fnt = NIL THEN dsr := 0 ELSE dsr := - fnt.minY END
  33.         ELSE
  34.             TextFrames.ParcBefore(f(TextFrames.Frame).text, pos, p, beg);
  35.             dsr := SHORT(p.dsr DIV TextFrames.Unit)
  36.         END
  37.     END GetDsr;
  38.     PROCEDURE CopyText (T: Texts.Text): Texts.Text;
  39.         VAR t: Texts.Text; buf: Texts.Buffer;
  40.     BEGIN
  41.         NEW(buf); Texts.OpenBuf(buf); Texts.Save(T, 0, T.len, buf);
  42.         t := TextFrames.Text(""); Texts.Append(t, buf); RETURN t
  43.     END CopyText;
  44.     PROCEDURE HandleEdit (F: Display.Frame; VAR M: Display.FrameMsg);
  45.         VAR F1: EditFrame;
  46.     BEGIN
  47.         TextFrames.Handle (F, M);
  48.         WITH F: EditFrame DO
  49.             IF M IS Oberon.CopyMsg THEN
  50.                 NEW(F1); TextFrames.Open(F1, F.text, F.org);
  51.                 F1.handle := F.handle; F1.elem := F.elem; M(Oberon.CopyMsg).F := F1
  52.             END
  53.         END
  54.     END HandleEdit;
  55.     PROCEDURE OpenEditor (E: Elem);
  56.         VAR V: Viewers.Viewer; F: EditFrame; x, y: INTEGER;
  57.     BEGIN
  58.         IF E.empty THEN E.text := TextFrames.Text ("") END ;
  59.         Oberon.AllocateUserViewer (Oberon.Mouse.X, x, y);
  60.         NEW(F); F.elem := E; TextFrames.Open (F, CopyText(E.text), 0); F.handle := HandleEdit;
  61.         V := MenuViewers.New (TextFrames.NewMenu("Index Entry",
  62.                 "System.Close  System.Copy  System.Grow  IndexElems.Update "),
  63.                 F, TextFrames.menuH, x, y)
  64.     END OpenEditor;
  65.     PROCEDURE MarkedFrame (VAR name: ARRAY OF CHAR): TextFrames.Frame;
  66.         VAR V: Viewers.Viewer; S: Texts.Scanner;
  67.     BEGIN V := Oberon.MarkedViewer ();
  68.         IF (V#NIL) & (V IS MenuViewers.Viewer) & (V.dsc.next IS TextFrames.Frame) THEN
  69.             Texts.OpenScanner(S, V.dsc(TextFrames.Frame).text, 0); Texts.Scan(S);
  70.             COPY( S.s, name); RETURN V.dsc.next(TextFrames.Frame)
  71.         ELSE RETURN NIL
  72.         END
  73.     END MarkedFrame;
  74.     PROCEDURE Copy (SE, DE: Elem);
  75.     BEGIN
  76.         Texts.CopyElem(SE, DE); DE.key := SE.key;
  77.         DE.visible := TRUE; DE.text := CopyText (SE.text)
  78.     END Copy;
  79.     PROCEDURE Edit (E: Elem; x0, y0, dsr: INTEGER; keysum: SET);
  80.         VAR w, h, x, y: INTEGER; keys: SET;
  81.     BEGIN
  82.         IF keysum = {middleKey} THEN
  83.             w := SHORT (E.W DIV TextFrames.Unit); h := SHORT (E.H DIV TextFrames.Unit);
  84.             Oberon.RemoveMarks (x0, y0, w, h);
  85.             Display.CopyPattern(Display.white, icon, x0, y0 + dsr, Display.invert);
  86.             Display.CopyPattern(Display.white, invIcon, x0, y0 + dsr, Display.invert);
  87.             REPEAT Input.Mouse (keys, x, y); keysum := keysum + keys;
  88.                 Oberon.DrawCursor (Oberon.Mouse, Oberon.Arrow, x, y);
  89.             UNTIL keys = {};
  90.             Display.CopyPattern(Display.white, invIcon, x0, y0 + dsr, Display.invert);
  91.             Display.CopyPattern(Display.white, icon, x0, y0+ dsr, Display.invert);
  92.             IF keysum = {middleKey} THEN OpenEditor (E) END
  93.         END
  94.     END Edit;
  95.     PROCEDURE Handle* (E: Texts.Elem; VAR msg: Texts.ElemMsg);
  96.         VAR e: Elem; pos: LONGINT; w, h, dsr: INTEGER; keys, keysum: SET;
  97.     BEGIN
  98.         WITH E: Elem DO
  99.             WITH msg : TextFrames.DisplayMsg DO
  100.                 WITH msg: TextFrames.DisplayMsg DO
  101.                     IF ~msg.prepare THEN
  102.                         GetDsr (msg.frame, msg.pos, msg.fnt, dsr);
  103.                         IF E.visible THEN Display.CopyPattern(Display.white, icon, msg.X0, msg.Y0 + dsr, Display.paint) END
  104.                     ELSE
  105.                         GetDsr (msg.frame, msg.pos, msg.fnt, msg.Y0); E.W := Width;
  106.                         IF E.visible THEN E.H := 8 * TextFrames.Unit ELSE E.H := 0 END
  107.                     END
  108.                 END
  109.             | msg : Texts.IdentifyMsg DO
  110.                 msg.mod:="IndexElems"; msg.proc:="Alloc"
  111.             | msg : Texts.CopyMsg DO
  112.                 IF msg(Texts.CopyMsg).e = NIL THEN NEW(e); msg(Texts.CopyMsg).e := e
  113.                 ELSE e := msg(Texts.CopyMsg).e(Elem)
  114.                 END ;
  115.                 Copy (E, e); 
  116.             | msg : TextFrames.TrackMsg DO
  117.                 GetDsr (msg.frame, msg.pos, msg.fnt, dsr);
  118.                 Edit(E, msg.X0, msg.Y0, dsr, msg.keys)
  119.             | msg : Texts.FileMsg DO
  120.                 IF msg.id = Texts.load THEN
  121.                     Files.ReadBool (msg.r, E.visible); Files.ReadBool (msg.r, E.empty);
  122.                     E.text := TextFrames.Text (""); Texts.Load (msg.r, E.text)
  123.                 ELSIF msg.id = Texts.store THEN
  124.                     Files.WriteBool (msg.r, E.visible); Files.WriteBool (msg.r, E.empty);
  125.                     Texts.Store (msg.r, E.text)
  126.                 END
  127.             | msg : TextPrinter.PrintMsg DO
  128.                 IF msg.prepare THEN E(Elem).pno := msg.pno; E.W := 0 END
  129.             ELSE
  130.             END
  131.         END
  132.     END Handle;
  133.     PROCEDURE Alloc*;
  134.         VAR e: Elem;
  135.     BEGIN NEW(e); e.handle:=Handle; Texts.new:=e
  136.     END Alloc;
  137.     PROCEDURE Insert*;
  138.         e: Elem; insert: TextFrames.InsertElemMsg;
  139.         t: Texts.Text; buf: Texts.Buffer; start, end, time: LONGINT;
  140.     BEGIN
  141.         Oberon.GetSelection(t, start, end, time);
  142.         NEW (e); e.text := TextFrames.Text ("");
  143.         e.handle := Handle; e.visible := TRUE; e.key := Oberon.Time ();
  144.         e.H := Height; e.W := Width;
  145.         IF time >= 0 THEN
  146.             NEW(buf); Texts.OpenBuf(buf);
  147.             Texts.Save(t, start, end, buf); Texts.Append(e.text, buf)
  148.         ELSE e.empty := TRUE
  149.         END ;
  150.         insert.e := e; Viewers.Broadcast (insert)
  151.     END Insert;
  152.     PROCEDURE Hide*;
  153.     VAR f: TextFrames.Frame; pos: LONGINT; r: Texts.Reader; name: ARRAY 256 OF CHAR;
  154.     BEGIN
  155.         f := MarkedFrame (name);
  156.         Texts.OpenReader (r, f.text, 0); Texts.ReadElem (r);
  157.         WHILE ~r.eot DO
  158.             IF r.elem IS Elem THEN
  159.                 r.elem(Elem).visible := FALSE; pos := Texts.ElemPos (r.elem); r.elem.W := 0;
  160.                 TextFrames.NotifyDisplay(f.text, Texts.replace, pos, pos+1)
  161.              END ;
  162.             Texts.ReadElem (r)
  163.         END
  164.     END Hide;
  165.     PROCEDURE Show*;
  166.     VAR f: TextFrames.Frame; pos: LONGINT; r: Texts.Reader; name: ARRAY 256 OF CHAR;
  167.     BEGIN
  168.         f := MarkedFrame (name);
  169.         Texts.OpenReader (r, f.text, 0); Texts.ReadElem (r);
  170.         WHILE ~r.eot DO
  171.             IF r.elem IS Elem THEN
  172.                 r.elem(Elem).visible := TRUE; pos := Texts.ElemPos (r.elem);
  173.                 r.elem.W := Width;
  174.                 TextFrames.NotifyDisplay(f.text, Texts.replace, pos, pos+1)
  175.             END ;
  176.             Texts.ReadElem (r)
  177.         END
  178.     END Show;
  179.     PROCEDURE Update*;
  180.         VAR f: EditFrame; s: Texts.Scanner; menuText, text: Texts.Text; e: Elem; pos: LONGINT;
  181.     BEGIN
  182.         IF Oberon.Par.frame = Oberon.Par.vwr.dsc THEN
  183.             f := Oberon.Par.frame.next(EditFrame); e := f.elem;
  184.             IF f.text.len # 0 THEN e.text := CopyText(f.text); e.empty := FALSE ELSE e.empty := TRUE END ;
  185.             menuText := Oberon.Par.frame(TextFrames.Frame).text;
  186.             Texts.OpenReader (s, menuText, menuText.len-1); Texts.Read (s, s.c);
  187.             IF s.c = "!" THEN Texts.Delete (menuText, menuText.len-1, menuText.len) END
  188.         END
  189.     END Update;
  190.     PROCEDURE CharDiff (c1, c2: CHAR) : INTEGER;
  191.     BEGIN
  192.         IF (c1 = '
  193. ') OR (c1 = '
  194. ') THEN c1 := 'o' END ;
  195.         IF (c1 = '
  196. ') OR (c1 = '
  197. ') THEN c1 := 'u' END ;
  198.         IF (c1 = '
  199. ') OR (c1 = '
  200. ') THEN c1 := 'a' END ;
  201.         IF (c2 = '
  202. ') OR (c2 = '
  203. ') THEN c2 := 'o' END ;
  204.         IF (c2 = '
  205. ') OR (c2 = '
  206. ') THEN c2 := 'u' END ;
  207.         IF (c2 = '
  208. ') OR (c2 = '
  209. ') THEN c2 := 'a' END ;
  210.         RETURN ORD (CAP (c1)) - ORD (CAP (c2))
  211.     END CharDiff;
  212.     PROCEDURE CompareTexts (t1, t2: Texts.Text) : INTEGER;   (* t1-t2 *)
  213.     VAR r1, r2: Texts.Reader; ch1, ch2: CHAR; diff: INTEGER;
  214.     BEGIN
  215.         Texts.OpenReader(r1, t1, 0); Texts.OpenReader(r2, t2, 0);
  216.         REPEAT Texts.Read (r1, ch1); Texts.Read (r2, ch2); diff := CharDiff (ch1, ch2);
  217.         UNTIL r1.eot OR r2.eot OR (diff # 0);
  218.         IF r1.eot & r2.eot THEN RETURN 0
  219.         ELSIF r1.eot THEN RETURN -1
  220.         ELSIF r2.eot THEN RETURN 1
  221.         ELSE RETURN diff
  222.         END
  223.     END CompareTexts;
  224.     PROCEDURE Sort;
  225.         VAR e, sb, s, sorted: Elem;
  226.     BEGIN
  227.         sorted := elems;
  228.         elems := elems.next;
  229.         sorted.next := NIL;
  230.         WHILE elems # NIL DO
  231.             e := elems; elems := elems.next;
  232.             IF CompareTexts (sorted.text, e.text) >= 0 THEN e.next := sorted; sorted := e
  233.             ELSE
  234.                 sb := sorted; s:= sorted.next;
  235.                 WHILE (s # NIL) & (CompareTexts (s.text, e.text) < 0) DO
  236.                     sb := s; s := s.next
  237.                 END ;
  238.                 e.next := sb.next; sb.next := e
  239.             END
  240.         END ;
  241.         elems := sorted
  242.     END Sort;
  243.     PROCEDURE BuildText (e: Elem; t: Texts.Text; pos: LONGINT);
  244.     VAR s: Texts.Scanner;
  245.     BEGIN
  246.         e.text := TextFrames.Text ("");
  247.         Texts.OpenScanner (s, t, pos+1); Texts.Scan (s);
  248.         IF (s.class = Texts.String) OR (s.class = Texts.Name) THEN
  249.             Texts.WriteString (w, s.s); Texts.Append (e.text, w.buf)
  250.         END
  251.     END BuildText;
  252.     PROCEDURE Index*;
  253.         V : Viewers.Viewer;
  254.         res, X, Y : INTEGER;
  255.         text: Texts.Text;
  256.         f: TextFrames.Frame;
  257.         r: Texts.Reader;
  258.         buf: Texts.Buffer;
  259.         e, ee: Elem;
  260.         name: ARRAY 256 OF CHAR;
  261.     BEGIN
  262.         f := MarkedFrame (name);
  263.         text := TextFrames.Text ("");
  264.         Oberon.Call ("Edit.Print", Oberon.Par, FALSE, res);
  265.         Texts.OpenReader(r, f.text, 0); Texts.ReadElem(r);
  266.         WHILE ~ r.eot DO
  267.             IF r.elem IS Elem THEN
  268.                 IF r.elem(Elem).empty THEN BuildText (r.elem(Elem), f.text, Texts.ElemPos (r.elem)) END ;
  269.                 r.elem(Elem).next := elems; elems := r.elem(Elem)
  270.             END ;
  271.             Texts.ReadElem(r)
  272.         END ;
  273.         Sort (); e:=elems;
  274.         WHILE e # NIL DO
  275.             NEW(buf); Texts.OpenBuf(buf);
  276.             Texts.Save(e.text, 0, e.text.len, buf); Texts.Append (text, buf);
  277.             Texts.Write (w, 9X); Texts.WriteInt (w, e.pno, 0);
  278.             Texts.WriteElem (w, LinkElems.New (name, e.key));
  279.             WHILE (e.next # NIL) & (CompareTexts (e.text, e.next.text) = 0) DO
  280.                 IF e.pno # e.next.pno THEN
  281.                     Texts.WriteString (w, ", "); Texts.WriteInt (w, e.next.pno, 0)
  282.                 END ;
  283.                 Texts.WriteElem (w, LinkElems.New (name, e.next.key));
  284.                 e := e.next
  285.             END ;
  286.             Texts.WriteLn (w);
  287.             Texts.Append (text, w.buf);
  288.             e := e.next
  289.         END ;
  290.         e := elems; WHILE e # NIL DO ee := e.next; e.next := NIL; e := ee END ; elems := NIL;
  291.         Oberon.AllocateUserViewer (0, X, Y);
  292.         V := MenuViewers.New (
  293.             TextFrames.NewMenu ("IndexElems.Index", "^Edit.Menu.Text"),
  294.             TextFrames.NewText (text, 0),
  295.             TextFrames.menuH,
  296.             X, Y)
  297.     END Index;
  298. PROCEDURE InitIcon;
  299.     VAR line: ARRAY 9 OF SET;
  300. BEGIN
  301.     line[1] := {4..8};
  302.     line[2] := {3, 9};
  303.     line[3] := {2, 5..7, 10};
  304.     line[4] := {2, 6, 10};
  305.     line[5] := {2, 6, 10};
  306.     line[6] := {2, 5..7, 10};
  307.     line[7] := {3, 9};
  308.     line[8] := {4..8};
  309.     icon := Display.NewPattern(line, 13, 8);
  310.     line[1] := {4..8};
  311.     line[2] := {3..9};
  312.     line[3] := {2..4, 8..10};
  313.     line[4] := {2..5, 7..10};
  314.     line[5] := {2..5, 7..10};
  315.     line[6] := {2..4, 8..10};
  316.     line[7] := {3..9};
  317.     line[8] := {4..8};
  318.     invIcon := Display.NewPattern(line, 13, 8)
  319. END InitIcon;
  320. BEGIN Texts.OpenWriter (w); InitIcon
  321. END IndexElems.
  322.