home *** CD-ROM | disk | FTP | other *** search
- (* ----------------------------------------------------------------------- *)
- (* DRUCK.PAS *)
- (* Schoenschrift-Ausdruck selbst gemacht. Hier mit WordStar 3.40, NEC P6 *)
- (* 24-Nadel-Drucker und Turbo-Pascal *)
-
- PROGRAM Druck;
- CONST
- check = FALSE; (* true: diagnostischer Output *)
- ESC = '#'; (* Escape-Signal *)
- bell = 7; (* ASCII-Code Klingelsignal *)
- MaxLen = 130; (* max. Zeilenlaenge *)
- MIN = 16; (* min/max. Ausdehnung fuer *)
- MAX = 56; (* Blanks in 360stel Zoll *)
- LeftMargin = 16;
- CwFileName = 'CHRDATA.TXT'; (* enthaelt Schrittweitentabelle *)
-
- TYPE
- signset = SET OF CHAR;
- strmaxlen = STRING[MaxLen];
- string80 = STRING[80];
- str50 = STRING[50]; (* f. Dateinamen *)
- VAR
- CR, stop, checking, (* checking ist fuer Diagnostik ! *)
- dotline : BOOLEAN;
- spaces, chars, allchars: signset;
- Word, Line, Linebuf : strmaxlen;
- WSFileName, OutFileName: str50;
- LeftJust, FullJust : STRING[3];
- cwf, inp, out : TEXT;
- cw : ARRAY[30..255] OF INTEGER;
- Wordcount, Sum, mmTab,
- Tab, ladj, BOLFont,
- Font, blanks, adj,
- RightMargin : INTEGER;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Cursor (row, col: INTEGER); (* Cursor positionieren *)
- BEGIN GotoXY(col, row); END;
-
- PROCEDURE BlackOnWhite; (* inverse Textdarstellung aktivieren *)
- BEGIN TextColor(Black); TextBackground(White); END;
-
- PROCEDURE WhiteOnBlack; (* und wieder normale Textdarstellung *)
- BEGIN NormVideo; END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Initialize;
- VAR
- i: INTEGER; c: CHAR; temp: str50;
- BEGIN
- allchars := [];
- FOR i := 30 TO 255 DO allchars := allchars + [Chr(i)];
- (* Proportional-Schrittweitentabelle der Zeichen lesen: *)
- (* Datei zu lesen oeffnen, andere Pascal-C.: ReSet(cwf, CwFileName); *)
- Assign(cwf, CwFileName); ReSet(cwf);
- ReadLn(cwf); (* erste Kommentarzeile in der Datei ueberlesen *)
- (* Schrittweiten fuer die IBM-Sonderzeichen initialisieren, die nicht *)
- (* in der Datei enthalten sind: *)
- FOR i := 127 TO 255 DO cw[i] := 30;
- cw[30] := 30; cw[31] := 30; cw[132] := 32;
- cw[148] := 30; cw[129] := 34; cw[225] := 30;
- cw[142] := 42; cw[153] := 38; cw[154] := 36;
- FOR i := 32 TO 126 DO BEGIN (* Rest aus der Datei lesen: *)
- Read(cwf, c, c, cw[i]);
- IF Eoln(cwf) THEN ReadLn(cwf) ELSE Read(cwf, c);
- END;
- Close(cwf);
- Write('WordStar-Datei : '); ReadLn(WSFileName);
- Assign(inp, WSFileName); ReSet(inp); (* s.o. *)
- OutFileName := 'LST:'; (* Ausgabe auf den Drucker *)
- Write('Ausgabe (RETURN -> Drucker): '); ReadLn(temp);
- IF temp <> '' THEN OutFileName := temp;
- (* Ausgabedatei oeffnen, fuer andere Pascal-C.: ReWrite(out, OutFileName); *)
- Assign(out, OutFileName); ReWrite(out);
- Write('Zeilenspiegel (mm) : '); ReadLn(mmTab);
- Tab := Round(mmTab*7.0733*2.0);
- FOR i := 1 TO 79 DO Write('-');
- WriteLn; WriteLn;
- Line := ''; Word := ''; Sum := 0;
- adj := 100; Font := 0; BOLFont := 0;
- stop := FALSE; CR := TRUE; Wordcount := 0;
- Linebuf := ''; spaces := [' '];
- chars := allchars - spaces; checking := FALSE;
- RightMargin := Round(mmTab * 0.79) + LeftMargin;
- dotline:=FALSE; stop:=FALSE;
- Write(out, Chr(28),Chr(64)); (* Drucker-Reset *)
- Write(out, Chr(28),Chr(73),Chr(1)); (* IBM-Zeichens. *)
- Write(out, Chr(27),Chr(33),Chr(5)); (* 20 Zeichen/Zoll *)
- Write(out, Chr(27),Chr(108),Chr(LeftMargin)); (* linker Rand *)
- Write(out, Chr(27),Chr(81),Chr(RightMargin)); (* rechter Rand *)
- Write(out, Chr(27),Chr(120),Chr(1)); (* Schoendruck (LQ) *)
- Write(out, Chr(27),Chr(33),Chr(2)); (* proportional = default *)
- (* NEC P6/P7 Randausgleich AUS: *)
- LeftJust := Concat(Chr(27),Chr(97),Chr(0));
- (* NEC P6/P7 Randausgleich AN: *)
- FullJust := Concat(Chr(27),Chr(97),Chr(3));
- END;
- (* ----------------------------------------------------------------------- *)
- (* Auswahl aus den Escape-Sequenzen fuer NEC P6/P7 *)
- PROCEDURE PtrEscape (c: CHAR);
- BEGIN
- CASE c OF
- '0': Write(out, Chr(27),Chr(33),Chr(2)); (* Proportional *)
- '1': Write(out, Chr(27),Chr(33),Chr(0)); (* Courier *)
- '2': Write(out, Chr(27),Chr(33),Chr(1)); (* Elite *)
- 'a': Write(out, Chr(27),Chr(51),Chr(30)); (* einzeilig *)
- 'b': Write(out, Chr(27),Chr(51),Chr(45)); (* anderthalbzeilig *)
- 'd': Write(out, Chr(28),Chr(86),Chr(1),
- Chr(28),Chr(69),Chr(1)); (* gross + breit *)
- 'D': Write(out, Chr(28),Chr(86),Chr(0),
- Chr(28),Chr(69),Chr(0)); (* dto. AUS *)
- '/': Write(out, Chr(27),Chr(52)); (* kursiv *)
- '%': Write(out, Chr(27),Chr(120),Chr(0)); (* Draft *)
- '&': Write(out, Chr(27),Chr(120),Chr(1)); (* Letter Quality *)
- 'k': Write(out, Chr(27),Chr(45),Chr(1)); (* unterstreichen AN *)
- 'K': Write(out, Chr(27),Chr(45),Chr(0)); (* unterstreichen AUS *)
- 's': Write(out, Chr(27),Chr(69)); (* Schattendruck *)
- 'h': Write(out, Chr(27),Chr(83),Chr(0)); (* Superskript AN *)
- 't': Write(out, Chr(27),Chr(84)); (* Superskript AUS *)
- 'z': Write(out, Chr(27),Chr(97),Chr(1)); (* zentrieren *)
- END; (* Case *)
- END; (* Escape *)
- (* ----------------------------------------------------------------------- *)
- (* Unterbrechung nach jeder Kommentarzeile oder .pa *)
- PROCEDURE ContactUser;
- VAR c: CHAR;
- i: INTEGER;
- BEGIN
- FOR i := 1 TO 79 DO Write('-'); WriteLn(Chr(bell));
- Write('weiter: CR stop: ESC naechste Seite: "n" ');
- Read(Kbd, c); (* Zeichen ohne Bildschirmecho von Tastatur lesen *)
- WriteLn;
- IF Ord(c) = 27 THEN stop := TRUE
- ELSE IF c = 'n' THEN Write(out, Chr(12)); (* Seitenvorschub *)
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE PrintLn (Line: strmaxlen);
- VAR
- i: INTEGER;
- c: CHAR;
- Escapeflag : BOOLEAN;
- BEGIN
- dotline := (Copy(Line,1,3) = '.pa') OR (Copy(Line,1,2) = '..');
- IF dotline THEN ContactUser
- ELSE BEGIN
- Escapeflag := FALSE;
- i := Length(Line);
- IF Line[i] = Chr(254) THEN (* Absatzende? *)
- BEGIN Delete(Line, i, 1); Write(out, LeftJust); END
- ELSE Write(out, FullJust);
- FOR i := 1 TO Length(Line) DO BEGIN
- c := Line[i];
- IF Escapeflag THEN
- BEGIN PtrEscape(c); Escapeflag := FALSE; END
- ELSE IF c = ESC THEN Escapeflag := TRUE
- ELSE IF c = '@' THEN Write(out, '#')
- ELSE Write(out, c);
- END;
- WriteLn(out);
- END;
- END;
- (* ----------------------------------------------------------------------- *)
- (* wandelt WordStar-Zeile in ASCII *)
- PROCEDURE Readline (VAR Line: strmaxlen);
- VAR
- c: CHAR; k: INTEGER; HardCR, HyphenCon: BOOLEAN;
- BEGIN
- HyphenCon := FALSE; c := ' '; Line := ''; HardCR := FALSE;
- WHILE NOT Eof(inp) AND (c <> Chr(10)) DO (* Chr(10) = Zeilenende *)
- BEGIN
- Read(inp, c);
- IF c = Chr(13) THEN HardCR := TRUE (* Zeilenvorschub *)
- ELSE IF (Ord(c) = 27) OR (Ord(c) = 155) THEN
- BEGIN
- IF NOT Eof(inp) THEN Read(inp, c);
- END
- ELSE IF Ord(c) > 127 THEN c := Chr(Ord(c) - 128);
- IF (Ord(c) >= 30) AND (Ord(c) <> 138) THEN Line := Concat(Line,c);
- END;
- IF Line > '' THEN (* folgende Leerzeichen loeschen: *)
- WHILE Line[Length(Line)] = ' ' DO Delete(Line, Length(Line), 1);
- k := Length(Line);
- IF k > 1 THEN (* Trennvorschlag ? *)
- HyphenCon := (Line[k] = '-') AND (Line[k - 1] <> ' ');
- IF HardCR THEN Line := Concat(Line, Chr(254)) (* Absatz ? *)
- ELSE IF NOT HyphenCon THEN Line := Concat(Line, ' ');
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Span (signs: signset; VAR sp: string80);
- VAR
- outcon: BOOLEAN;
- BEGIN
- sp := ''; outcon := FALSE;
- REPEAT
- IF Linebuf[1] IN signs THEN
- BEGIN
- sp := Concat(sp, Linebuf[1]); Delete(Linebuf, 1, 1);
- END
- ELSE outcon := TRUE;
- UNTIL (Linebuf = '') OR outcon;
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Readword;
- VAR temp: string80;
- BEGIN
- IF (Linebuf = '') THEN BEGIN
- IF NOT Eof(inp) THEN Readline(Linebuf)
- ELSE BEGIN stop := TRUE; Linebuf := Concat(' ',Chr(254)); END;
- END;
- Span(spaces, temp); Word := temp;
- Span(chars, temp); Word := Concat(Word,temp);
- Span(spaces, temp); Word := Concat(Word,temp);
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Escape (c: CHAR);
- BEGIN
- CASE c OF
- '0': Font := 0; (* proportional *)
- '1': Font := 36; (* Courier *)
- '2': Font := 30; (* Elite *)
- END;
- END;
- (* ----------------------------------------------------------------------- *)
- (* errechnet die Ausdehnung eines Strings *)
- PROCEDURE Sigma (OldSum: INTEGER; Line: strmaxlen);
- VAR
- i, Width, space : INTEGER;
- Escflag, BOL : BOOLEAN; (* BOL = beginning of line *)
- x : CHAR;
- BEGIN
- Sum := OldSum; BOL:= Sum = 0; Escflag := FALSE;
- IF Sum = 0 THEN Font := BOLFont;
- FOR i := 1 TO Length(Line) DO BEGIN
- Width := 0; x := Line[i];
- IF x <> ' ' THEN BOL := FALSE;
- IF Escflag THEN BEGIN Escape(x); Escflag := FALSE; END
- ELSE IF x = ESC THEN Escflag := TRUE (* Esc ausfuehren? *)
- ELSE IF BOL THEN (* b.o.l. blanks ? *)
- BEGIN
- IF Font = 0 THEN Width := 30 ELSE Width := Font;
- END
- ELSE IF Ord(x) = 30 THEN Width := 30
- ELSE IF Ord(x) > 32 THEN (* non-b.o.l. chars *)
- BEGIN
- IF Font = 0 THEN Width := cw[Ord(x)] ELSE Width := Font;
- END;
- Sum := Sum + Width;
- IF checking THEN Write(Width, ' ');
- END;
- space := Tab - Sum;
- IF blanks > 0 THEN adj := Round(space/blanks) ELSE adj := space;
- IF checking THEN BEGIN
- WriteLn;
- Write('CHARS: ', Length(Line), ' CR: ', CR, ' SUM: ', Sum);
- WriteLn(' BLANKS: ', blanks, ' ADJ: ', adj);
- END;
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Hyphenate; (* interaktiver Trennalgorithmus *)
- VAR
- c: CHAR; Option, p, row, n, FixAdj, FixLadj: INTEGER;
- syllab: str50; TempLine, TempWord: strmaxlen;
-
- PROCEDURE HyphenWindow;
- CONST lenx = 78; leny = 2;
- VAR i: INTEGER;
- BEGIN
- WhiteOnBlack;
- (* fuer den Rahmen nach Bedarf schoenere Zeichen Ihres Systems einsetzen: *)
- Cursor(row, 1); FOR i := 1 TO lenx DO Write('-'); (* Kanten *)
- Cursor(row + leny, 1); FOR i := 1 TO lenx DO Write('-');
- Cursor(row + 1, 1); Write('!');
- Cursor(row + 1, lenx); Write('!');
- Cursor(row, 1); Write('+'); (* Ecken *)
- Cursor(row, lenx); Write('+');
- Cursor(row + leny, 1); Write('+');
- Cursor(row + leny, lenx); Write('+');
- Cursor(row + 1, 12); Write('!'); (* Waende *)
- Cursor(row + 1, 22); Write('!');
- Cursor(row, 12); Write('+'); (* T-Stuecke *)
- Cursor(row, 22); Write('+');
- Cursor(row + leny, 12); Write('+');
- Cursor(row + leny, 22); Write('+');
- Cursor(row, 4); Write('mit'); (* Text *)
- Cursor(row, 14); Write('ohne');
- Cursor(row, 25); Write('trenne');
- Cursor(row + 1, 25); Write(Word);
- Cursor(row + 1, 4); Write(FixLadj:3, '(', MIN, ')');
- Cursor(row + 1, 14); Write(FixAdj:3, '(', MAX, ')');
- END;
-
- PROCEDURE writeOption (i: INTEGER);
- BEGIN
- CASE Option OF
- 1: BEGIN
- Cursor(row+1,4); Write(FixLadj:3,'(', MIN,')'); Cursor(row+1,4);
- END;
- 2: BEGIN
- Cursor(row+1,14); Write(FixAdj:3,'(',MAX,')'); Cursor(row+1,14);
- END;
- 3: BEGIN Cursor(row+1,25); Write(Word); Cursor(row+1,25); END;
- END; (* case *)
- END;
-
- PROCEDURE OptionHandler (change: INTEGER);
- BEGIN
- WhiteOnBlack; writeOption(Option); Option := change + Option;
- IF Option > 3 THEN Option := 1
- ELSE IF Option < 1 THEN Option := 3;
- p := 0; BlackOnWhite; writeOption(Option);
- END;
-
- PROCEDURE MenuLoop;
- VAR i: INTEGER; ch : CHAR; ok: BOOLEAN;
-
- PROCEDURE ParallelDisplay;
- VAR hyph: BOOLEAN; temp: strmaxlen;
- BEGIN
- blanks := blanks + 1; hyph := Word[p] = '-';
- temp := Copy(Word, 1, p); temp := Concat(Line, temp);
- IF hyph THEN Sigma(0, temp)
- ELSE BEGIN temp := Concat(temp, '-'); Sigma(0, temp); END;
- blanks := blanks - 1; Cursor(row, 35); Write(adj:3, ' OK?(CR)');
- END;
-
- BEGIN (* MenuLoop *)
- ok := FALSE;
- REPEAT (* option loop *)
- Read(Kbd, c); (* Zeichen ohne Bildschirmecho von Tastatur lesen *)
- CASE Ord(c) OF
- 27: BEGIN (* behandle IBM-Cursortasten: *)
- IF KeyPressed THEN (* es folgt der Code einer Cursortaste *)
- Read(Kbd, c)
- ELSE (* sonst wurde die ESC-Taste gedrueckt und... *)
- BEGIN (* ...ESC-Taste bricht Programm ab! *)
- WriteLn(out); Close(inp); Close(out);
- Halt; (* beendet das Programm *)
- END;
- IF Option < 3 THEN (* Zeile mit oder ohne Wort *)
- CASE Ord(c) OF
- 77: OptionHandler(1); (* Cursor rechts *)
- 75: OptionHandler(-1); (* Cursor links *)
- ELSE Write(Chr(bell));
- END
- ELSE (* Trennposition im Word bestimmen *)
- BEGIN
- CASE Ord(c) OF
- 77: IF p < Length(Word) THEN
- BEGIN (* im Word nach rechts gehen *)
- WhiteOnBlack; p := p + 1; ParallelDisplay;
- Cursor(row+1,p+24); Write(Word[p]);
- END
- ELSE (* in den Punkt "mit" gehen *)
- OptionHandler(1);
- 75: IF p > 1 THEN
- BEGIN (* im Word nach links gehen *)
- BlackOnWhite;
- Cursor(row+1,p+24); Write(Word[p]);
- p := p - 1; ParallelDisplay;
- Cursor(row+1,p+24);
- END
- ELSE (* in den Punkt "ohne" gehen *)
- OptionHandler(-1);
- ELSE Write(Chr(bell));
- END;
- END;
- END; (* OF 27 *)
- 13: BEGIN (* CR trifft eine Wahl *)
- CASE Option OF
- 1: BEGIN (* letztes ADJ akzeptiert: inkludiere Wort *)
- Line := Concat(Line,Word); blanks := blanks+1;
- Sigma(0, Line); Word := ''; ok := TRUE;
- END;
- 2: ok := TRUE; (* ADJ akzeptiert: Wort auf Vorrat *)
- 3: BEGIN (* Hyphenation Routine *)
- syllab := Copy(Word, 1, p); blanks := blanks + 1;
- n := Length(Word); ch := ' ';
- IF syllab[p] = '-' THEN
- TempLine := Concat(Line, syllab)
- ELSE
- TempLine := Concat(Line, syllab, '-');
- TempWord := Copy(Word, p+1, n-p);
- Sigma(0, TempLine);
- IF adj IN [MIN .. MAX] THEN BEGIN
- Line := TempLine; Word := TempWord;
- ok := TRUE;
- END;
- END;
- END; (* CASE option *)
- END; (* OF 13 *)
- ELSE Write(Chr(bell));
- END; (* CASE *)
- UNTIL ok;
- END; (* menu loop *)
-
- BEGIN (* Hyphenate *)
- WriteLn(Line); WriteLn(Word); WriteLn(Chr(bell));
- WriteLn; WriteLn; WriteLn; WriteLn; WriteLn;
- row := 22; Option := 3; FixAdj := adj; FixLadj := ladj;
- HyphenWindow; OptionHandler(1); MenuLoop;
- WhiteOnBlack; WriteLn; WriteLn;
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE reinitial;
- BEGIN
- Line := ''; (* neue Zeile; Word moeglicherweise nicht leer *)
- Sum := 0; BOLFont := Font; Wordcount := 0; adj := 100;
- END;
- (* ----------------------------------------------------------------------- *)
- (* fuellt Line so lange mit Woertern bis ADJ < MIN oder CR *)
- PROCEDURE Umbruch;
- VAR c : CHAR;
- BEGIN
- IF Word = '' THEN Readword;
- CR := Word[Length(Word)] = Chr(254);
- blanks := Wordcount; Wordcount := Wordcount + 1;
- Sigma(Sum, Word); (* wie gross sind wir mit dem neuen Wort? *)
- ladj := adj; (* Ergebnis festhalten *)
- IF (adj < MIN) OR CR THEN (* Abschlussbedingungen erfuellt ? *)
- BEGIN
- IF CR THEN
- BEGIN
- IF adj >= 30 THEN
- BEGIN (* 1: CR und adj >= 30 *)
- Line := Concat(Line, Word); Word := '';
- WriteLn(Line); PrintLn(Line);
- IF check THEN WriteLn('EXIT: 1 ');
- END
- ELSE (* fuer adj < 30 *)
- BEGIN (* 2: CR und adj < 30 *)
- blanks := blanks - 1; Sigma(0, Line);
- IF adj > MAX THEN Hyphenate;
- WriteLn(Line); PrintLn(Line);
- IF Length(Word) > 0 THEN BEGIN
- WHILE Word[1] = ' ' DO Delete(Word, 1, 1);
- WriteLn(Word); PrintLn(Word);
- END;
- IF check THEN WriteLn('EXIT: 2 ');
- Word := '';
- END;
- END (* IF CR *)
- ELSE (* 3: nicht CR, adj < min *)
- BEGIN
- blanks := blanks - 1; Sigma(0, Line);
- IF (adj > MAX) THEN Hyphenate;
- WriteLn(Line); PrintLn(Line); (* Wort ist nicht Nullstring! *)
- IF check THEN WriteLn('EXIT: 3 ');
- END;
- IF check THEN BEGIN
- checking := TRUE; Sigma(0, Line);
- Read(Kbd, c); WriteLn; checking := FALSE;
- END;
- reinitial;
- END (* IF (adj < MIN) OR CR *)
- ELSE (* (adj >= MIN) and not CR *)
- BEGIN
- Line := Concat(Line, Word); (* solange bis ADJ < MIN oder CR *)
- Word := '';
- END;
- END; (* UmbruchRoutine *)
- (* ----------------------------------------------------------------------- *)
- BEGIN (* MAIN *)
- WriteLn; WriteLn;
- WriteLn('Umbruch & Druck (c) 1987 M.Jahn & PASCAL INT.'); WriteLn;
- Initialize;
- WHILE NOT stop DO Umbruch;
- WriteLn(Concat(Line, Word)); PrintLn(Concat(Line, Word));
- Close(inp); Close(out);
- WriteLn; WriteLn('fertig...');
- END.