home *** CD-ROM | disk | FTP | other *** search
- UNIT datei; {$project vt}
- { Dateioperationen zum Programm VideoText }
-
- INTERFACE; FROM vt USES bildschirm;
-
- VAR configpath: String[20];
-
- FUNCTION filetype(name: Str80): Integer;
- FUNCTION getpages(filename: Str80; sorted: Boolean): Integer;
- FUNCTION printpage(seite: p_onepage): Boolean;
- PROCEDURE page_to_clip(seite: p_onepage);
- FUNCTION save_action(seite: p_onepage; mode: Integer): Integer;
- PROCEDURE name2dosname(s: str80; VAR s2: str80);
- PROCEDURE namefrompage(VAR filename: str80; seite: p_onepage);
-
- { ---------------------------------------------------------------------- }
-
- IMPLEMENTATION;
- {$ opt q,s+,i+} { keine Laufzeitprüfungen außer Stack und Feldindizes }
-
- FUNCTION getlong(VAR datei: Text): Long;
- VAR l: Long;
- i: Integer;
- ch: Char;
- BEGIN
- l := 0;
- FOR i := 1 TO 4 DO BEGIN
- Read(datei,ch);
- l := (l SHL 8) OR Ord(ch);
- END;
- getlong := l;
- END;
-
- FUNCTION filetype{(name: Str80): Integer};
- { Typcodierung: }
- { -1: Datei existiert nicht (oder ist leer) }
- { 0: unbekannter Typ (vermutlich roher ASCII-Text) }
- { 1: programmeigener Typ 'VTPG'=$56545047 }
- { VTex-Format 'FG24'=$46473234 }
- { oder TeleText 'TELE'=$54454C45 }
- { 2: AmigaDOS-Programmdatei $000003F3 }
- { 3: IFF-Datei 'FORM'=$464F524D }
- { 4: Workbench-Icon $E310 }
- VAR head: Long;
- datei: Text;
- BEGIN
- Reset(datei,name);
- IF IOresult=0 THEN BEGIN
- filetype := 0;
- IF FileSize(datei)=0 THEN filetype := -1; { leere Datei }
- head := getlong(datei);
- IF head=$56545047 THEN filetype := 1;
- IF head=$46473234 THEN filetype := 1;
- IF head=$54454C45 THEN filetype := 1;
- IF head=$000003F3 THEN filetype := 2;
- IF head=$464F524D THEN filetype := 3;
- IF (head AND $FFFF0000)=$E3100000 THEN filetype := 4;
- Close(datei);
- END ELSE
- filetype := -1; { Datei existiert nicht }
- END;
-
- FUNCTION getpages{(filename: Str80; sorted: Boolean): Integer};
- { Alle VT-Seiten aus einer VTPG-Datei einlesen und in die Seitenliste }
- { einreihen. Rückgabewert: Anzahl der gelesenen Seiten }
- VAR i,j, jlpageno, gelesen: Integer;
- bytes: ^ARRAY[1..41] OF Char;
- datei: Text;
- zeile: Str80;
- seite: p_onepage;
- l: Long;
- c: Char;
- CONST vtpg=$56545047;
- fg24=$46473234;
- tvtx=$54565458;
- tele=$54454C45;
- texd=$54455854;
- sub=$535542;
- PROCEDURE findword;
- { Hilft, zeile in Worte zu zerlegen. Parameter j: Startpunkt, Ergebnis: }
- { i: 1. Zeichen des Wortes, j: 1. Trennzeichen dahinter }
- BEGIN
- i := j; WHILE (zeile[i]=' ') AND (zeile[i]<>#0) DO Inc(i);
- j := i + 1; WHILE NOT (zeile[j] IN [' ',#0]) DO Inc(j);
- END;
- BEGIN
- gelesen := 0;
- Reset(datei,filename);
- IF (IOresult<>0) THEN { Datei existiert nicht }
- Exit;
- Buffer(datei,200);
- WHILE NOT EoF(datei) DO BEGIN
- l := 0;
- REPEAT
- Read(datei,c); l := l SHL 8 OR Ord(c);
- UNTIL (l=vtpg) OR (l=fg24) OR (l=tele) OR (l AND $FFFFFF=sub)
- OR EoF(datei);
- { mein eigenes Format lesen: }
- IF l=vtpg THEN BEGIN
- New(seite);
- Read(datei,c); { LF überlesen }
- FOR i := 0 TO 23 DO BEGIN
- bytes := Ptr(^seite^.chars[40*i]);
- BlockRead(datei,bytes^,40);
- Read(datei,c); { LF überlesen }
- END;
- ReadLn(datei,zeile); j := 1;
- findword; seite^.pg := hexval(Copy(zeile,i,j-i));
- findword; seite^.sp := hexval(Copy(zeile,i,j-i));
- findword; seite^.cbits := hexval(Copy(zeile,i,j-i));
- seite^.dejavu := False;
- IF make_bcd(get_bcd(seite^.pg))<>seite^.pg THEN
- seite^.cbits := seite^.cbits OR PF_PSEUDO
- ELSE
- seite^.cbits := seite^.cbits AND NOT PF_PSEUDO;
- IF sorted THEN ins_to_list(seite) ELSE add_to_list(seite);
- Inc(gelesen);
- END;
- { das Format der VTex-Software lesen: }
- IF l=fg24 THEN IF getlong(datei)=tvtx THEN BEGIN
- New(seite);
- seite^.pg := make_bcd(getlong(datei));
- seite^.sp := make_bcd(getlong(datei));
- seite^.cbits := 0;
- l := getlong(datei); { aus der Zeichensatz-Nummer die Steuerbits }
- FOR i := 14 DOWNTO 12 DO BEGIN { C12,C13,C14 "rekonstruieren" }
- IF Odd(l) THEN seite^.cbits := seite^.cbits OR (1 SHL i);
- l := l SHR 1;
- END;
- FOR i := 1 TO 18 DO Read(datei,c); { ??? }
- BlockRead(datei,seite^.chars,960);
- seite^.dejavu := False;
- IF sorted THEN ins_to_list(seite) ELSE add_to_list(seite);
- Inc(gelesen);
- END;
- { Jan Leuverink's TeleText-Format lesen: }
- IF l=tele THEN IF getlong(datei)=texd THEN BEGIN { header }
- jlpageno := 0;
- FOR i := 1 TO 3 DO BEGIN
- Read(datei,c); jlpageno := (jlpageno SHL 4) OR (Ord(c)-Ord('0'));
- END;
- END;
- IF (l AND $FFFFFF=sub) THEN BEGIN { eine Seite }
- New(seite);
- seite^.pg := jlpageno;
- seite^.sp := 0;
- seite^.cbits := $4000; { immer dt. Zeichensatz %-( }
- FOR i := 1 TO 4 DO BEGIN
- Read(datei,c); IF c>='0' THEN
- seite^.sp := (seite^.sp SHL 4) OR (Ord(c)-Ord('0'));
- END;
- BlockRead(datei,seite^.chars,960);
- seite^.dejavu := False;
- IF sorted THEN ins_to_list(seite) ELSE add_to_list(seite);
- Inc(gelesen);
- END;
- END;
- Close(datei);
- getpages := gelesen;
- END;
-
-
- FUNCTION printpage{(seite: p_onepage): Boolean};
- { Druckerausgabe, simpelste Ausführung }
- VAR drucker: Text;
- i: Integer;
- s: Str80;
- monster: ^String[1000]
- BEGIN
- printpage := False;
- Reset(drucker,'PRT:');
- IF IOResult<>0 THEN Exit;
- New(monster); monster^ := '';
- FOR i := 0 TO 23 DO BEGIN
- makeascii(seite, i, True, s);
- monster^ := monster^ + s + Chr(10);
- END;
- Write(drucker,monster^);
- Dispose(monster);
- Close(drucker); printpage := True;
- END;
-
- PROCEDURE page_to_clip{(seite: p_onepage)};
- { Seitentext ins Clipboard schreiben }
- VAR s: str80;
- i: Integer;
- BEGIN
- IF seite=Nil THEN Exit;
- start_clip(24*41);
- FOR i := 0 TO 23 DO BEGIN
- makeascii(seite, i, True, s);
- s := s + Chr(10);
- clip_it(s,41);
- END;
- end_clip;
- END;
-
- FUNCTION savepage(seite: p_onepage; ascii: Boolean; VAR datei: Text): Boolean;
- { Seite abspeichern, ASCII oder rohes VT-Format }
- { ASCII-Text wird für Untertitel und Schlagzeilen 'komprimiert' ausgegeben: }
- { nur die auf der Seite befindliche Box (mindestens aber eine Leerzeile, bei }
- { Schlagzeilen zusätzlich die Kopfzeile). }
- { Bei Untertiteln werden die Farbsteuerzeichen in Klartext umgesetzt. }
- VAR i, zeile: Integer;
- s: str80;
- bytes: ^ARRAY [1..41] OF Char;
- is_stitle,is_headln,visible: Boolean;
- BEGIN
- savepage := False; IF seite=Nil THEN Exit;
- IF ascii THEN BEGIN { ASCII-Textausgabe }
- is_stitle := (seite^.cbits AND PF_STITLE)<>0;
- is_headln := (seite^.cbits AND PF_HEADLN)<>0;
- FOR zeile := 0 to 23 DO BEGIN
- IF is_stitle OR is_headln THEN BEGIN
- visible := False;
- FOR i := 0 TO 39 DO
- IF (seite^.chars[zeile*40+i]=11) THEN visible := True;
- IF is_headln AND (zeile=0) THEN
- visible := True;
- END ELSE
- visible := True;
- IF visible THEN BEGIN
- makeascii(seite, zeile, NOT is_stitle, s);
- WriteLn(datei, s); IF IOResult<>0 THEN Exit; { Disk full o. ä. }
- END;
- END;
- WriteLn(datei);
- END ELSE BEGIN { (beinahe) rohes VT-Format }
- WriteLn(datei,'VTPG');
- FOR zeile := 0 to 23 DO BEGIN
- bytes := Ptr(^seite^.chars[40*zeile]);
- BlockWrite(datei,bytes^,40); IF IOResult<>0 THEN Exit; { Disk full }
- WriteLn(datei);
- END;
- Write(datei,hexstr(seite^.pg,0)); Write(datei,' ');
- Write(datei,hexstr(seite^.sp,0)); Write(datei,' $');
- Write(datei,hexstr(seite^.cbits,4)); WriteLn(datei);
- END;
- savepage := True;
- END;
-
- FUNCTION save_action{(seite: p_onepage; mode: Integer): Integer};
- { Verwaltungskram für savepage(). }
- { Bedeutung von <mode>: }
- { 1=nur <seite> speichern, 2=mit allen Unterseiten, 3=alle ab dieser, }
- { 4=wie 3, aber ohne Rückfrage }
- { Ergebnis: }
- { 0: OK, 1: Benutzer wollte nicht, 2: Anhängen unzulässig, 3: IO-Fehler }
- VAR ft: Integer;
- pg1,pg2: p_onepage;
- ok: Boolean;
- s: str80;
- datei: Text;
- BEGIN
- save_action := 1;
- IF seite=Nil THEN Exit;
- fileinfo;
- IF mode=3 THEN BEGIN
- { Rückfrage, weil das etwas länger dauern könnte }
- IF seite=root THEN
- s := 'Alle '+IntStr(listsize)+' Seiten speichern?'
- ELSE
- s := IntStr(listsize-posn_in_list(seite))
- +' Seiten ab dieser speichern?';
- IF NOT ja_nein(s) THEN Exit;
- END;
- { Sicherheitsprüfung: Anhängen nur an geeignete Dateien erlauben: }
- ft := filetype(outputname);
- IF ft IN [2,3,4] THEN BEGIN
- CASE ft OF
- 2: short_msg('Programmdatei',2);
- 3: short_msg('IFF-Datei',2);
- 4: short_msg('Icon-Datei',2);
- END;
- add_msg(', Anhängen unzulässig!',2);
- save_action := 2; Exit;
- END;
- { Alle Rückfragen überstanden -> speichern: }
- busy_pointer;
- Reset(datei,outputname);
- IF (IOresult<>0) THEN { Datei existiert vermutlich nicht }
- Rewrite(datei,outputname);
- IF IOresult<>0 THEN BEGIN { wahrscheinlich 'Object in use' }
- short_msg('Kann die Ausgabedatei nicht öffnen!',2);
- Exit;
- END;
- IF withicon THEN IF FileSize(datei)=0 THEN
- IF asciifile THEN
- create_icon('Icons/ASCII', outputname)
- ELSE
- create_icon('Icons/VT', outputname);
- Buffer(datei, 500);
- Seek(datei, FileSize(datei));
- pg1 := root;
- { um aber auch Seiten speichern zu können, die nicht in der Liste stehen: }
- IF (seite^.prev=Nil) AND (root<>seite) THEN pg1 := seite;
- ok := False;
- WHILE pg1<>NIL DO BEGIN
- CASE mode OF
- 1: ok := (pg1=seite);
- 2: ok := (pg1^.pg=seite^.pg);
- 3,4: IF pg1=seite THEN ok := True;
- END;
- IF ok THEN BEGIN
- short_msg('Seite '+hexstr(pg1^.pg,0)+'/',0);
- add_msg(hexstr(pg1^.sp,0)+' ...',0);
- IF savepage(pg1,asciifile,datei) THEN
- add_msg(' gespeichert.',0)
- ELSE BEGIN
- add_msg(' Dateifehler!',2);
- save_action := 3;
- pg1 := Nil;
- END;
- END;
- IF pg1<>Nil THEN pg1 := pg1^.next;
- END;
- Close(datei);
- normal_pointer;
- save_action := 0;
- END;
-
- PROCEDURE civilize(s: str80; VAR s2: str80;);
- { String als DOS-Namen tauglich machen }
- VAR i,k,l: Integer;
- sonder: String[8];
- uebers: String[15];
- BEGIN
- sonder := '{|}[\]~'; uebers := 'aeoeueAEOEUEss';
- i := 1; k := 1;
- REPEAT
- CASE s[i] OF
- ' ': s2[k] := '_'; { Leerzeichen }
- '/',':': s2[k] := '-'; { Verzeichnis-Begrenzer }
- OTHERWISE s2[k] := s[i];
- END;
- l := Pos(s[i],sonder);
- IF l>0 THEN BEGIN
- s2[k] := uebers[2*l-1]; Inc(k); s2[k] := uebers[2*l];
- END;
- Inc(i); Inc(k);
- UNTIL s[i] = #0;
- s2[k] := #0;
- END;
-
- PROCEDURE name2dosname{(s: str80; VAR s2: str80)};
- { Bekommt eine Titelzeile übergeben und liefert (normalerweise mit Hilfe }
- { der ".stations"-Liste) einen DOS-tauglichen Filenamen zurück. }
- VAR zeile,name: str80;
- i,j,l: Integer;
- stnfile: Text;
- has_letters, complain: Boolean;
- BEGIN
- s2 := ''; name := configpath+'.stations'; complain := False;
- Reset(stnfile, name);
- IF IOResult=0 THEN BEGIN
- Buffer(stnfile,100);
- WHILE NOT EoF(stnfile) AND (s2='') DO BEGIN
- ReadLn(stnfile,zeile); i := Pos('=',zeile);
- IF i>1 THEN BEGIN
- l := Length(zeile); WHILE l>0 DO BEGIN
- IF zeile[l]<=' ' THEN zeile[l] := #0 ELSE l := 1;
- Dec(l);
- END;
- l := Length(zeile);
- s2 := Copy(zeile,1,i-1);
- IF Pos(s2, s)>0 THEN s2 := Copy(zeile,i+1,l-i) ELSE s2 := '';
- END;
- END;
- Close(stnfile);
- IF s2='' THEN complain := True;
- END ELSE
- short_msg('Senderliste nicht gefunden',2);
- IF s2='' THEN BEGIN { das 1. Wort nehmen, das auch Buchstaben enthält: }
- j := 1;
- REPEAT
- i := j;
- WHILE (s[i]=' ') DO Inc(i);
- j := i; has_letters := False;
- WHILE NOT (s[j] IN [' ', #0]) DO BEGIN
- IF s[j] IN ['a'..'z','A'..'Z'] THEN has_letters := True;
- Inc(j);
- END;
- UNTIL has_letters OR (s[i]=#0);
- IF j>i THEN BEGIN
- zeile := Copy(s, i, j-i); civilize(zeile, s2);
- END;
- IF complain THEN
- short_msg('"'+s2+'"'+' nicht in der Senderliste',0);
- END;
- END;
-
- PROCEDURE namefrompage{(VAR filename: str80; seite: p_onepage)};
- { Dateinamen nach der Titelzeile einer Seite abändern }
- VAR i,j,l: Integer;
- pfad,name,s: str80;
- has_letters: Boolean;
- BEGIN
- IF seite=Nil THEN Exit;
- { Dateinamen zerlegen: }
- l := Length(filename);
- j := 0; FOR i := 1 TO l DO
- IF filename[i] IN ['/',':'] THEN j := i;
- IF j=0 THEN pfad := '' ELSE pfad := Copy(filename,1,j);
- IF j=l THEN name := '' ELSE name := Copy(filename,j+1,l-j);
- { Titelzeile extrahieren: }
- FOR i := 1 TO 40 DO BEGIN
- s[i] := Chr(seite^.chars[i-1]); IF s[i]<' ' THEN s[i] := ' ';
- END;
- s[41] := #0;
- name2dosname(s, filename);
- IF filename<>'' THEN name := filename;
- filename := pfad + name;
- END;
-
- BEGIN { Initialisierungen }
- configpath := 'presets/'; { bitte *nicht* mehr ändern! }
- END.
-
-