Syntax10.Scn.Fnt Syntax12.Scn.Fnt Syntax10i.Scn.Fnt Syntax10b.Scn.Fnt MODULE TextPreview; (** CAS 19-May-92 (Rel. 2.42) **) IMPORT Texts, Viewers, Oberon, Printer, MenuViewers, TextFrames, TextPrinter, TextPFrames; CONST Version = "TextPreview 1.0 (cas 19 May 92)"; Menu = "System.Close System.Copy System.Grow TextPreview.Synch Edit.Store "; mm = TextFrames.mm; Scale = mm DIV 10; Unit = TextPrinter.Unit; bodyX = 15 * mm DIV Unit; bodyY = 15 * mm DIV Unit; bodyW = 165 * mm DIV Unit; bodyH = 260 * mm DIV Unit; W: Texts.Writer; PROCEDURE Ch (ch: CHAR); BEGIN Texts.Write(W, ch); Texts.Append(Oberon.Log, W.buf) END Ch; PROCEDURE Str (s: ARRAY OF CHAR); BEGIN Texts.WriteString(W, s); Texts.Append(Oberon.Log, W.buf) END Str; PROCEDURE Int (n: LONGINT); BEGIN Texts.Write(W, " "); Texts.WriteInt(W, n, 0); Texts.Append(Oberon.Log, W.buf) END Int; PROCEDURE Ln; BEGIN Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END Ln; (* arguments *) PROCEDURE GetMainArg (VAR S: Texts.Scanner; text: Texts.Text; org: LONGINT; VAR beg, end: LONGINT); VAR time: LONGINT; BEGIN Texts.OpenScanner(S, text, org); Texts.Scan(S); beg := org; end := text.len; 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) ELSE end := 0 END END; IF S.line # 0 THEN S.class := Texts.Inval END END GetMainArg; PROCEDURE ScanArgs (VAR S: Texts.Scanner; VAR pno, first, last, bx, by, bw, bh: INTEGER); VAR i, k: INTEGER; ch: CHAR; BEGIN bx := bodyX; by := bodyY; bw := bodyW; bh := bodyH; pno := 0; first := 0; last := 10000; WHILE (S.class = Texts.Char) & (S.c = "\") DO Texts.Scan(S); IF S.class = Texts.Name THEN ch := CAP(S.s[0]); Texts.Scan(S); IF ch = "A" THEN ELSIF (ch = "C") & (S.class = Texts.Int) & (1 <= S.i) & (S.i < 10) THEN Texts.Scan(S) ELSIF (ch = "F") & (S.class = Texts.Name) THEN Texts.Scan(S) ELSIF ch = "H" THEN IF (S.class = Texts.Name) OR (S.class = Texts.String) THEN Texts.Scan(S) END ELSIF ch = "M" THEN (*margin options*) IF S.class = Texts.Name THEN ch := CAP(S.s[0]); Texts.Scan(S); i := 0; WHILE (S.class = Texts.Int) & (0 <= S.i) DO k := SHORT(S.i * Scale DIV TextPrinter.Unit); INC(i); Texts.Scan(S); IF ch = "H" THEN ELSIF ch = "B" THEN IF i = 1 THEN bx := k ELSIF i = 2 THEN by := k ELSIF i = 3 THEN bw := k ELSIF i = 4 THEN bh := k END END END END ELSIF ch = "P" THEN (*page options*) IF (S.class = Texts.Int) & (0 <= S.i) THEN pno := SHORT(S.i); first := pno; Texts.Scan(S) ELSIF S.class = Texts.Name THEN ch := CAP(S.s[0]); Texts.Scan(S) END ELSIF (ch = "S") & (S.class = Texts.Int) & (0 <= S.i) THEN first := SHORT(S.i); Texts.Scan(S); IF (S.class = Texts.Int) & (0 <= S.i) THEN last := SHORT(S.i); Texts.Scan(S) ELSE last := first END END END END END ScanArgs; (* pagination *) PROCEDURE OpenDmyPrinter; VAR name: ARRAY 32 OF CHAR; BEGIN name := "Out.Prt"; Printer.Open(name, Oberon.User, Oberon.Password); IF Printer.res # 0 THEN HALT(99) END END OpenDmyPrinter; PROCEDURE LocatePageBreaks (text: Texts.Text; pno, first, last, bx, by, bw, bh: INTEGER; VAR pages: INTEGER; VAR porg: ARRAY OF LONGINT); VAR org: LONGINT; BEGIN org := 0; pages := 0; WHILE (org < text.len) & (Printer.res = 0) DO IF pages < LEN(porg) THEN porg[pages] := org END; IF (first <= pno) & (pno <= last) THEN INC(pages) END; TextPrinter.PlaceBody(bx, by, bw, bh, text, org, pno, FALSE); Ch("."); INC(pno) END END LocatePageBreaks; PROCEDURE CountPages (text: Texts.Text; pno, first, last, bx, by, bw, bh: INTEGER; VAR pages: INTEGER); VAR porg: ARRAY 1000 OF LONGINT; BEGIN LocatePageBreaks(text, pno, first, last, bx, by, bw, bh, pages, porg) END CountPages; (* commands *) PROCEDURE Synch*; VAR V: Viewers.Viewer; F: TextPFrames.Frame; BEGIN F := Oberon.Par.vwr.dsc.next(TextPFrames.Frame); V := Oberon.MarkedViewer(); IF (V IS MenuViewers.Viewer) & (V.dsc.next IS TextFrames.Frame) THEN IF V.dsc.next IS TextPFrames.Frame THEN TextPFrames.Show(V.dsc.next(TextPFrames.Frame), F.org) ELSIF V.dsc.next IS TextFrames.Frame THEN TextFrames.Show(V.dsc.next(TextFrames.Frame), F.org) ELSE TextFrames.Show(V.dsc.next(TextFrames.Frame), F.org) END END END Synch; PROCEDURE This*; VAR S: Texts.Scanner; V: Viewers.Viewer; F: TextFrames.Frame; beg, end: LONGINT; x, y: INTEGER; BEGIN GetMainArg(S, Oberon.Par.text, Oberon.Par.pos, beg, end); IF (S.class = Texts.Char) & (S.c = "*") THEN V := Oberon.MarkedViewer(); IF (V IS MenuViewers.Viewer) & (V.dsc.next IS TextFrames.Frame) THEN IF V.dsc IS TextFrames.Frame THEN Texts.OpenScanner(S, V.dsc(TextFrames.Frame).text, 0); Texts.Scan(S) ELSE S.s := "TextPreview.Text" END; F := V.dsc.next(TextFrames.Frame); Oberon.AllocateUserViewer(Oberon.Mouse.X, x, y); V := MenuViewers.New(TextFrames.NewMenu(S.s, Menu), TextPFrames.NewText(F.text, F.org), TextFrames.menuH, x, y) END END END This; PROCEDURE Paginate*; VAR S: Texts.Scanner; V: Viewers.Viewer; F: TextPFrames.Frame; beg, end: LONGINT; pages, h, pno, first, last, bx, by, bw, bh: INTEGER; porg: ARRAY 1000 OF LONGINT; BEGIN GetMainArg(S, Oberon.Par.text, Oberon.Par.pos, beg, end); IF (S.class = Texts.Char) & (S.c = "*") THEN Str("TextPreview.Paginate * "); Texts.Scan(S); V := Oberon.MarkedViewer(); IF (V IS MenuViewers.Viewer) & (V.dsc.next IS TextPFrames.Frame) THEN ScanArgs(S, pno, first, last, bx, by, bw, bh); F := V.dsc.next(TextPFrames.Frame); OpenDmyPrinter; LocatePageBreaks(F.text, pno, first, last, bx, by, bw, bh, pages, porg); TextPFrames.SetPagination(F, pages, pno, bw, porg); Int(pages); h := F.H; TextPFrames.Resize(F, F.X, F.Y, F.W, 0); TextPFrames.Resize(F, F.X, F.Y, F.W, h) ELSE Str("failed (* not a preview)") END; Ln END END Paginate; PROCEDURE PageCount*; VAR S: Texts.Scanner; V: Viewers.Viewer; text: Texts.Text; beg, end: LONGINT; pages, total, pno, first, last, bx, by, bw, bh: INTEGER; BEGIN Str("TextPreview.PageCount"); Ln; GetMainArg(S, Oberon.Par.text, Oberon.Par.pos, beg, end); OpenDmyPrinter; IF (S.class = Texts.Char) & (S.c = "*") THEN Texts.Scan(S); V := Oberon.MarkedViewer(); IF (V # NIL) & (V IS MenuViewers.Viewer) & (V.dsc.next IS TextFrames.Frame) THEN ScanArgs(S, pno, first, last, bx, by, bw, bh); text := V.dsc.next(TextFrames.Frame).text(Texts.Text); IF V.dsc IS TextFrames.Frame THEN Texts.OpenScanner(S, V.dsc(TextFrames.Frame).text, 0); Texts.Scan(S); IF S.class # Texts.Name THEN S.s[0] := "*"; S.s[1] := 0X END ELSE S.s[0] := "*"; S.s[1] := 0X END; Str(" "); Str(S.s); Str(" counting "); CountPages(text, pno, first, last, bx, by, bw, bh, pages); Int(pages); Ln ELSE Str(" failed (bad * marker)"); Ln END ELSIF S.class = Texts.Name THEN text := TextFrames.Text(S.s); Str(" "); Str(S.s); Str(" counting "); Texts.Scan(S); ScanArgs(S, pno, first, last, bx, by, bw, bh); CountPages(text, pno, first, last, bx, by, bw, bh, pages); Int(pages); Ln ELSE total := 0; ScanArgs(S, pno, first, last, bx, by, bw, bh); WHILE (S.class = Texts.Name) & (beg < end) DO Str(" "); Str(S.s); Str(" counting "); text := TextFrames.Text(S.s); beg := Texts.Pos(S); Texts.Scan(S); CountPages(text, pno, first, last, bx, by, bw, bh, pages); INC(total, pages); Int(pages); Ln END; Str(" total"); Int(total); Ln END END PageCount; BEGIN Texts.OpenWriter(W); Str(Version); Ln END TextPreview.