Von 1st_Word zu Signum!2

Als ich bei der Textverarbeitung von 1st_Word auf Signum!2 gewechselt habe, wollte ich die alten Texte auch übernehmen. Da Signum!2 die Möglichkeit bietet, ASCII-Texte zu importieren, sollte es dabei eigentlich keine Probleme geben. Mit dem Ergebnis war ich aber nicht zufrieden. Zum einen hatte ich keine reine ASCII-Datei ausgewählt, so daß die Fehlinterpretation von Steuerzeichen zu unerwünschten Ergebnissen führte, zum anderen enthielt der Text einige griechische Buchstaben, die nicht übersetzt werden können. Die verwendeten Textattribute wurden natürlich auch ignoriert.

Wenn man bei Signum!2 reine ASCII-Dateien importiert, gibt es zwar keine Probleme mit den Steuerzeichen und den Textattributen, da diese gar nicht vorhanden sind, aber die Sonderzeichen fehlen immer noch.

Die Aufgabe hieß also: Schreibe ein Programm, das 1st_WORD-Dateien in Signum!2-Dateien umwandelt und dabei die Textattribute beachtet.

Die Voraussetzung dafür ist, daß man erst einmal weiß, wie die beiden Programme die Daten abspeichern. Also habe ich kurze Texte geschrieben, abgespeichert und analysiert, was sich in den Dateien bei Verwendung der verschiedenen Parameter änderte. Bei 1st_WORD war die Analyse noch recht einfach, da es nicht allzuviele Möglichkeiten gibt. Bei Signum!2 hat die Analyse erheblich mehr Zeit in Anspruch genommen. Es gibt ja auch viel mehr Parameter, die man einstellen kann. (Das Dokument. in dem ich die Bedeutung der einzelnen Bits kurz kommentiert habe, ist drei Seiten lang.) Eine ausführliche Erklärung des Aufbaus der Dokumente würde den Rahmen dieses Artikels sprengen. Zum Aufbau von Signum!2-Dokumenten sei hier nur gesagt. daß sie modular aufgebaut sind. Das ist auch der Grund, weswegen Signum!2 und Signum!1 die Dokumente der jeweils anderen Version im Rahmen ihrer Möglichkeiten weiterverarbeiten können: Bei Signum!2 werden einfach noch die Module für Bilder, Fußnoten, Spaltensatz und zusätzliche Systemparameter angehängt. Wird das Dokument nun mit Signum!1 bearbeitet, so werden diese Module zwar mit verschoben (bei einfügen/löschen), aber sonst nicht weiter beachtet. Die einzelnen Module beginnen jeweils mit einer Kennung und einem Langwort, das die Länge dieses Moduls (ohne Kennung und Langwort) angibt.

Was leistet das Programm?

Das Programm ignoriert:

Die Parameterdatei

Damit das Programm die Zeichen richtig umsetzen kann, muß es wissen, welches Zeichen bei 1st_Word welchem bei Signum! zugeordnet ist und welche Breite es hat. Alle erforderlichen Informationen stehen in der Parameterdatei 'CONVERT.PAR'. Diese Datei hat folgenden Aufbau:

Zunächst werden die Namen der verwendeten Zeichensätze angegeben:

In der ersten Spalte steht die Nummer, die dem Zeichensatz zugeordnet wird (1-4), die zweite Spalte wird ignoriert (ein beliebiges Separationszeichen), und ab der dritten Spalte steht der Name des Zeichensatzes ohne Extention. Das Ende der Zeichensatznamen wird durch eine Null in der ersten Spalte gekennzeichnet. Es müssen nicht alle vier Zeichensätze verwendet werden, und man kann sie in beliebiger Reihenfolge angeben.

Nun folgen die Parameter für die einzelnen Zeichen:

Am Anfang der Zeile steht der ASCII-Wert des Zeichens im ST-Zeichensatz, dann folgen die Nummer des Signum!-Zeichensatzes, die Breite des Zeichens (in 1/90 Zoll, wie bei Signum! üblich) und die Nummer im Signum!-Zeichensatz, jeweils durch ein Komma getrennt. Zusätzliche Leerzeichen sind erlaubt. Die Zahlen können in allen von GFA BASIC unterstützten Zahlenformaten eingegeben werden.

Zusätzlich sind Kommentare erlaubt:

Hinter den einzelnen Zeicheninformationen können beliebige Kommentare stehen. Sie müssen sich nur durch irgendein Separationszeichen von den Zahlen dieser Zeile abheben.

Wenn sich der Zeilenanfang nicht als Zahl interpretieren läßt, wird die ganze Zeile als Kommentar interpretiert.

Die Tabelle muß nicht vollständig sein, aber es müssen alle verwendeten Zeichen definiert werden. Sie müssen nicht aufsteigend sortiert sein, obwohl es dann übersichtlicher ist.

1st_Word benutzt als internes Trennungszeichen den Code 25. Diesem Code sollte daher das interne Trennungszeichen von Signum! zugeordnet werden. Signum! verwendet dafür den Code 126. Der Zeichensatz kann beliebig gewählt werden.

Da Signum! kein Leerzeichen kennt (es wird nur ein größere Abstand zum vorhergehenden Zeichen gespeichert), ist es überflüssig, die verschiedenen Leerzeichen zu definieren.

Das Ende der Tabelle wird wieder mit einer Null gekennzeichnet.

Wenn es jemandem nicht gefällt, daß die Parameter nachgeladen werden, kann er ja die Prozedur 'Zeichen.einlesen' so ändern, daß die Daten aus DATA-Zeilen gelesen werden.

Woher bekomme ich...

...die Informationen über die Zeichenbreite und -nummer? Die Breite der Zeichen kann man abzählen, wenn man den entsprechenden Zeichensatz in den Zeichensatzeditor lädt und dann das Zeichen in den Editor holt. Um an die Nummer im Zeichensatz zu kommen, muß man den Zeichensatz analysieren. Um Ihnen die Arbeit zu ersparen möchte ich hier die Reihenfolge der Zeichen darlegen:

Signum! hält sich weitestgehend an die Standard-ASCII Nummern. Dies gilt für alle Zeichen zwischen dem ASCII Code 33 und 127 mit folgenden Ausnahmen:

ä =93   Ä = 125 
ö =91   Ö = 123 
ü =64   Ü =  92 
§ =32   ß = 127

Signum!-internes Trennungszeichen = 126

Im Bereich von 1 bis 31 liegen die Zeichen des Ziffernblocks mit folgender Zuordnung:

Zuerst die 14 geshifteten Zeichen: ()/*0123456789 (Werte 1 - 14), dann die gleichen Zeichen ohne Shift (Werte 15 bis 28), am Ende noch die Zeichen: +-. mit den Werten 29 bis 31.

Sie empfinden es als mühsam, die Zeichensatznummer auszurechnen und die Zeichenbreite abzuzählen?

Dann überlassen wir es doch dem Computer. Das Programm 'ZEIGE' zeigt einen Editorzeichensatz von Signum! an und schreibt unter jedes Zeichen die Nummer und die Breite. Durch die Verwendung einer Menüzeile ist es möglich, mit ‘SNAPSHOT.ACC' das Bild zu speichern. Bei der Erstellung der Parameterdatei mit 1st_Word kann man dieses Bild laden und nachsehen, welche Werte eingegeben werden müssen.

Die Handhabung des Programms

Wenn die Parameterdatei erst einmal steht, ist die Bedienung des Programms ganz einfach. Man wählt das 1st_Word-Dokument aus und speichert das Signum! Dokument nach der Übersetzung ab.

Durch das "ZEIGE”-Programm dargestellter Signum!-Zeichensatz
' (c) MAXON Computer GmbH 1988
'
DIM menue$(50),a%(10000)
DEFTEXT ,,,6
CLR i%
DO
  READ menue$(i%)
  EXIT IF menue$(i%)="***"
  INC i%
LOOP
DATA Desk,  info,-----------------------,1,2,3,4,5,6,""
DATA Laden,  *.E24   ,""
DATA Anzeigen,  zeige,""
DATA Ende, Exit,""
DATA "",***
ON MENU  GOSUB menu
MENU menue$()
'
REPEAT
  ON MENU &HFFFFFF
UNTIL ende!
MENU KILL
EDIT
PROCEDURE menu
  ON MENU(4)-2 GOSUB info,laden,anzeigen,ende
  MENU OFF
RETURN
PROCEDURE info
  info$="Programm zur Anzeige von|SIGNUM!-Editorzeichens„tze mit|"
  info$=info$+"Nummer und Breite|(C) Georg Scheibler, 4920 Lemgo"
  ALERT 0,info$,1,"OK",dummy%
RETURN
PROCEDURE ende
  ende!=TRUE
RETURN
PROCEDURE laden
  FILESELECT "\*.E24","",namen$
  IF EXIST(namen$)
    BLOAD namen$,VARPTR(a%(0))
    IF a%(0)=CVL("eset")
      CLOSEW 0
      TEXT 300,11,SPACE$(12)
      TEXT 300,11,namen$
      OPENW 0
    ELSE
      ALERT 1,"Dies ist kein korrekter|Zeichensatz",1,"Schade",dummy%
    ENDIF
  ENDIF
RETURN
PROCEDURE anzeigen
  IF a%(0)=CVL("eset")
    CLS
    p1%=XBIOS(2)+1600
    n%=0
    FOR l%=36 TO 163 STEP 16
      FOR l1%=l% TO l%+15
        pz%=VARPTR(a%(163))+a%(l1%)
        p%=p1%+PEEK(pz%)*80
        zaehler%=PEEK(pz%+1)
        spalte%=PEEK(pz%+2)
        breite%=2
        ADD pz%,4
        WHILE zaehler%>0
          BMOVE pz%,p%,breite%
          ADD pz%,breite%
          ADD p%,80
          DEC zaehler%
        WEND
        ADD p1%,5
        TEXT (n% MOD 16)*40,(n% DIV 16)*46+30,n%+1
        TEXT (n% MOD 16)*40,(n% DIV 16)*46+40,spalte%
        INC n%
        EXIT IF n%>126
      NEXT l1%
      ADD p1%,3600
    NEXT l%
  ELSE
    ALERT 1,"Sie haben keinen|gültigen Zeichensatz|geladen",1," Ach so ",dummy%
  ENDIF
RETURN

Zeige.bas


' ***************************************************************************** ' * * ' * Dieses Programm wandelt ein 1ST-WORD-Dokument in ein SIGNUM2-Dokument * ' * um. Dabei werden einige Textatribute (insbesondere Exponent und Index, * ' * aber auch Fett, Kursiv, Unterstreichen, Absatz) richtig umgesetzt. * ' * * ' * By Georg Scheibler, Fillekuhle 7, 4920 Leogo, 08.01.1988 * ' * * ' * (c) MAXON Computer GmbH 1988 * ' * * ' ***************************************************************************** ' DIM zeichen%(256),zeichensatz%(256),breite%(256),seite$(100) DIM zeichensatz.name$(4) PRINT AT(20,24);"Dieses Programm ist (C) by G.A.S. 11.01.1988"; PRINT AT(4,2);"Dieses Programm wandelt ein 1ST-WORD Dokument in ein SIGNUM2-Dokument um" @zeichen.einlesen path$="\" ' ' neue.datei: PRINT AT(22,3);"Bitte 1ST-WORT-Dokument auswählen" REPEAT FILESELECT path$+"*.DOC","",name$ IF name$="" ALERT 2,"Wollen Sie das Programm|beenden??",2,"ja|nein",dummy% IF dummy%=1 END ENDIF ENDIF name.neu$=name$ WHILE INSTR(name.neu$,"\")>0 name.neu$=MID$(name.neu$,INSTR(name.neu$,"\")+1) WEND path$=LEFT$(name$,LEN(name$)-LEN(name.neu$)) UNTIL EXIST(name$) PRINT AT(22,3);SPC(40) seiten.zahl%=1 zeilenabstand%=11 indexabstand%=3 seitenparameter$="" n.zeilenabstand%=zeilenabstand% CLR atribute%,e.space%,gesamt.laenge%,gesamt.zeilen%,i.space%,index% CLR seiten.laenge%,space%,zeilenzaehler% absatz!=FALSE fussnote!=FALSE fuss.seite!=FALSE seite$(1)=MKL$(2)+MKI$(&HC000) absatz%=&H400 zeilen.pro.seite%=60 !Voreinstellung für ASCII-Dateien PRINT AT(35,9);"Seite : 1";AT(35,10);"Zeile :" OPEN "i",#1,name$ DO LINE INPUT #1,z$ z$=z$+CHR$(13) lol%=LEN(z$)+1 pointer%=1 WHILE lol%>pointer% b%=ASC(MID$(z$,pointer%,1)) INC pointer% IF b%=&H1F @systemeintrag ELSE IF b%>&H1B OR b%=&H19 @normales.zeichen ELSE @format ENDIF ENDIF WEND EXIT IF EOF(#1) LOOP @seitenparameter PRINT AT(43,9);seiten.zahl% CLOSE #1 PRINT AT(20,3);"Bitte Namen für neues Dokument eingeben" IF INSTR(name.neu$,".")>0 name.neu$=LEFT$(name.neu$,INSTR(name.neu$,".")-1) ENDIF name.neu$=name.neu$+".SDO" FILESELECT path$+"*.sdo",name.neu$,name.neu$ IF name.neu$<>"" OPEN "o",#2,name.neu$ @signum.kopf @signum.text @signum.ende CLOSE #2 ENDIF ALERT 2,"Wollen Sie eine weitere Datei|umwandeln?",1,"Ja|Ende",dummy% IF dummy%=1 GOTO neue.datei ENDIF ' PROCEDURE zeichen.einlesen ' einlesen der Parameter für die Zeichen PRINT AT(22,10);"Ich lade die Datei 'CONVERT.PAR'" OPEN "i",#3,"CONVERT.PAR" REPEAT LINE INPUT #3,a$ i%=VAL(a$) IF i%>0 AND i%<5 zeichensatz.name$(i%)=MID$(a$,3,INSTR(a$+" "," ")-2) ENDIF UNTIL LEFT$(a$)="0" REPEAT LINE INPUT #3,a$ i%=VAL(a$) PRINT AT(55,10);i% IF i%>0 AND i%<256 p%=1 @naechste.zahl zeichensatz%(i%)=VAL(MID$(a$,p%))-1 @naechste.zahl breite%(i%)=VAL(MID$(a$,p%)) @naechste.zahl zeichen%(i%)=VAL(MID$(a$,p%)) ENDIF UNTIL LEFT$(a$)="0" CLOSE #3 PRINT AT(20,10);SPC(40) RETURN PROCEDURE naechste.zahl p%=INSTR(a$,",",p%)+1 WHILE MID$(a$,p%,1)=" " INC p% WEND RETURN ' PROCEDURE signum.kopf PRINT #2,"sdoc0001";MKL$(&H80);STRING$(&H48,0); PRINT #2,MKL$(XBIOS(23));MKL$(XBIOS(23));STRING$(&H30,0); PRINT #2,"cset";MKL$(&H50); FOR i%=1 TO 4 PRINT #2,zeichensatz.name$(i%);STRING$(10-LEN(zeichensatz.name$(i%)),0); NEXT i% PRINT #2,STRING$(&HE4-LOC(#2),0); PRINT #2,"sysp";MKL$(&H6E);STRING$(&H50,0); ' Standartseitenformat PRINT #2,MKI$(6); !Leerzeichenbreite PRINT #2,MKI$(0); !Sperrung PRINT #2,MKI$(zeilenabstand%); !Hauptzeilenabstand PRINT #2,MKI$(indexabstand%); !Indexabstand PRINT #2,MKI$(0); !Linker Rand PRINT #2,MKI$(6.5*90); !Rechter Rand PRINT #2,MKI$(0.1*54); !Kopfzeilen PRINT #2,MKI$(0.1*54); !Fußzeilen PRINT #2,MKI$(10.4*54); !Seitenlänge PRINT #2,MKI$(&H5800); !keine Seitennummerierung PRINT #2,MKI$(&X10011); !format. optionen PRINT #2,MKI$(&H302); !trennen PRINT #2,MKI$(0); !randausgleiche und Sperren PRINT #2,MKL$(1); !nicht einrücken, absatzabstand mitkorigieren ' PRINT #2,"pbuf";MKL$(&H20+&H22*seiten.zahl%); PRINT #2,MKL$(seiten.zahl%);MKL$(&H20);MKL$(1); PRINT #2,"undeundeundeundeunde"; PRINT #2,LEFT$(seitenparameter$,seiten.zahl%*&H22); RETURN ' PROCEDURE signum.text PRINT #2,"tebu";MKL$(gesamt.laenge%+8);MKL$(gesamt.zeilen%+460); FOR i%=1 TO seiten.zahl% PRINT #2,seite$(i%); NEXT i% PRINT #2,MKL$(&HF90000); RETURN ' PROCEDURE signum.ende PRINT #2,"hcim";MKL$(&H10);STRING$(&H10,0); PRINT #2,"pl01";MKL$(0); PRINT #2,"syp2";MKL$(&H40);MKI$(zeilenabstand%);MKL$(5);STRING$(&H3A,0); RETURN ' PROCEDURE seitenparameter seite$(seiten.zahl%)=seite$(seiten.zahl%)+MKI$(n.zeilenabstand%) IF seiten.zahl%>1 seite$(seiten.zahl%)=seite$(seiten.zahl%)+MKI$(4)+MKI$(&HA080)+MKI$(seiten.zahl%-1) ELSE seite$(seiten.zahl%)=seite$(seiten.zahl%)+MKL$(&H2A000) ENDIF ADD gesamt.laenge%,LEN(seite$(seiten.zahl%)) ADD seiten.laenge%,n.zeilenabstand% ADD gesamt.zeilen%,n.zeilenabstand% s$=MKI$(seiten.zahl%-1)+MKI$(seiten.zahl%)+MKI$(seiten.zahl%) s$=s$+MKI$(seiten.laenge%)+MKI$(0)+MKI$(6.5*90)+MKI$(1)+MKI$(1) s$=s$+MKI$(&H5800)+STRING$(30,0) seitenparameter$=seitenparameter$+LEFT$(s$,&H22) PRINT AT(43,9);seiten.zahl%+1' CLR seiten.laenge%,zeilenzaehler% seite$(seiten.zahl%+1)=MKI$(&HF)+MKI$(4)+MKI$(&HC080)+MKI$(seiten.zahl%) ADD gesamt.zeilen%,16 RETURN ' PROCEDURE systemeintrag ' systemeinträge werden überlesen b%=ASC(MID$(z$,pointer%,1)) INC pointer% IF b%=&H4E ! Fußnotentexte z$=STR$(VAL(MID$(z$,pointer%,3))) lol%=LEN(z$)+1 pointer%=1 IF fuss.seite!=FALSE @seitenparameter INC seiten.zahl% PRINT "Fußseite" fuss.seite!=TRUE ENDIF atribute%=&H4000000 ELSE IF b%=&H30 zeilen.pro.seite%=VAL(MID$(z$,pointer%,2)) ADD pointer%,2 FOR i%=1 TO 4 SUB zeilen.pro.seite%,VAL(MID$(z$,pointer%,2)) ADD pointer%,2 NEXT i% ENDIF ENDIF IF b%<>&H4E pointer%=lol%+1 ENDIF RETURN ' PROCEDURE normales.zeichen IF b%=&H1E OR b%=&H19 OR b%=&H2D absatz!=FALSE ELSE absatz!=TRUE ENDIF IF b%>&H20 OR b%=&H19 IF index%>0 IF index%=1 e.zeile$=e.zeile$+MKL$((zeichen%(b%)+zeichensatz%(b%)*128)*&H10000+e.space%+atribute%) CLR e.space% ELSE i.zeile$=i.zeile$+MKL$((zeichen%(b%)+zeichensatz%(b%)*128)*&H10000+i.space%+atribute%) CLR i.space% ENDIF ELSE IF space%>63 OR atribute%>0 zeile$=zeile$+MKL$((zeichen%(b%)+zeichensatz%(b%)*128)*&H10000+space%+atribute%) ELSE zeile$=zeile$+MKI$(&H8000+zeichen%(b%)+zeichensatz%(b%)*128+space%*512) ENDIF CLR space% ENDIF ADD space%,breite%(b%) ADD i.space%,breite%(b%) ADD e.space%,breite%(b%) ELSE IF b%>&H1C !dehnungsleerzeichen ignorieren ADD space%,6 ADD i.space%,6 ADD e.space%,6 IF b%=&H1D !erstes leerzeichen beim einrücken WHILE ASC(MID$(z$,pointer%,1))=&H1C !dehnungsleerzeichen beachten INC pointer% ADD space%,6 ADD i.space%,6 ADD e.space%,6 WEND ENDIF ENDIF ENDIF RETURN ' PROCEDURE format IF b%=&H1B b%=ASC(MID$(z$,pointer%,1)) INC pointer% IF b%>127 CLR atribute%,index% IF b% AND &X1 ! Fett atribute%=atribute% OR &X100000000000000 ENDIF IF b% AND &X10 ' hell, ignorieren ENDIF IF b% AND &X100 !Kursiv atribute%=atribute% OR &X10000000000000 ENDIF IF b% AND &X1000 !unterstrichen atribute%=atribute% OR &H40000000 ENDIF IF b% AND &X10000 !superscript (klein schreiben, unterstreichen löschen) atribute%=atribute% OR &X100000000000 AND &HBFFFFFFF index%=1 ENDIF IF b% AND &X100000 !supscript (klein schreiben, unterstreichen löschen) atribute%=atribute% OR &X100000000000 AND &HBFFFFFFF index%=2 ENDIF ENDIF ELSE IF b%=&HD IF LEN(e.zeile$)>0 SUB n.zeilenabstand%,indexabstand% e.zeile$=MKI$(n.zeilenabstand%-1)+MKI$(LEN(e.zeile$)+2)+MKI$(0)+e.zeile$ seite$(seiten.zahl%)=seite$(seiten.zahl%)+e.zeile$ ADD seiten.laenge%,n.zeilenabstand% ADD gesamt.zeilen%,n.zeilenabstand% n.zeilenabstand%=indexabstand% ENDIF zeile$=MKI$(n.zeilenabstand%-1)+MKI$(LEN(zeile$)+2)+MKI$(absatz%)+zeile$ seite$(seiten.zahl%)=seite$(seiten.zahl%)+zeile$ ADD seiten.laenge%,n.zeilenabstand% ADD gesamt.zeilen%,n.zeilenabstand% n.zeilenabstand%=zeilenabstand% IF LEN(i.zeile$)>0 SUB n.zeilenabstand%,indexabstand% i.zeile$=MKI$(indexabstand%-1)+MKI$(LEN(i.zeile$)+2)+MKI$(0)+i.zeile$ seite$(seiten.zahl%)=seite$(seiten.zahl%)+i.zeile$ ADD seiten.laenge%,indexabstand% ADD gesamt.zeilen%,indexabstand% ENDIF CLR space%,zeile$,e.space%,e.zeile$,i.zeile$,i.space% INC zeilenzaehler% PRINT AT(43,10);zeilenzaehler%' IF zeilenzaehler%=zeilen.pro.seite% @seitenparameter INC seiten.zahl% ENDIF IF absatz! absatz%=&HC00 ELSE absatz%=&H400 ENDIF ELSE IF b%<>10 !linefeed ignorieren IF b%=11 b%=256-ASC(MID$(z$,pointer%,1)) INC pointer% !abhängige Seitenende IF zeilenzaehler%+b%>=zeilen.pro.seite% AND b%<zeilen.pro.seite% @seitenparameter INC seiten.zahl% ENDIF ELSE IF b%=12 ! hartes Seitenende @seitenparameter INC seiten.zahl% ELSE IF b%=&H18 IF fussnote! fussnote!=FALSE ELSE ADD pointer%,3 !Fußnoten zusatzinformation atribute%=atribute% OR &H4000000 !fußnotenflag fussnote!=TRUE ENDIF ELSE ALERT 3,"unbekanntes Steuerzeichen| | "+STR$(b%)+"| ",1,"weiter",dummy% ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF RETURN

CONVERT.BAS


Georg Scheibler
Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]