{$A-,B-,D-,E-,F-,I+,L-,N-,O-,R-,S-,V-} {Compile with Turbo-Pascal 5.0} Program Jem2TeX(Input,Output); { This program translates a .JEM file into a .TeX file Author: Francois Jalbert ' Date: November 1990 Version: 1.0 Date: January 1991 Version: 1.01 Modifications: - Added \hskip0pt plus0.1em between all Japanese symbols which improved dramatically line breaks and inter-sentence spacing since [La]TeX could only add glue between whole Japanese sentences. - Extra space after punctuation is now an option since it is not desirable with MuTeX when the text is to go under the staff. - Font names now use only small letters to be compatible with the fontlib program supplied with emTeX. - Command line parameters now supported. - Run-time parameters now supported. - Updated and improved run-time messages. Date: April 1991 Version: 2.00 Modifications: - Added four kanjis. - If desired, only standard JIS '83 characters are allowed. - If desired, a % is added at each Japanese end of line. - Three file name extensions .JEM .JPN .JAP now supported. - Default extension is .JEM and the program has been renamed. - Three run-time parameter flags now supported. - Japanese comments not translated anymore for reference. - Hyphenation and glue handled separately for better control. - More clever algorithm for Japanese hyphenation. - Space after some punctuation now obtained with \eeee. - Small space around some punctuation introduced with \eee. - Tiny space between Japanese characters with \ee. - Space between Japanese and Roman with \eeee and \eee. - Symbols separated only by [La]TeX comments are now recognized as consecutive. - MS-kanji (Shift-JIS) now supported. Error Levels: 0 - Normal termination. 1 - Error. } Const {Highest Bitmap number in JIS24} BitmapMax=7806; {Highest font number} FontMax=60; {Floor of 7806 Div 128} {Highest size number} SizeMax=7; {magsteps are 0, 0.5, 1, 2, 3, 4, 5} {File name extensions in priority order} Extension1:String[4]='.jem'; Extension2:String[4]='.jpn'; Extension3:String[4]='.jap'; {Run-time flag of all the same length} RunFlag1:String[7]='JEM2TEX'; RunFlag2:String[7]='JPN2TEX'; RunFlag3:String[7]='JAP2TEX'; {Parameter flag} Flag1='/'; {DOS style} Flag2='-'; {UNIX style} {Parameter keywords in approximate decreasing length order} Space1:String[10]='EXTRASPACE'; Space2:String[5]='EXTRA'; Space3:String[5]='SPACE'; NoSpace1:String[12]='NOEXTRASPACE'; NoSpace2:String[7]='NOEXTRA'; NoSpace3:String[7]='NOSPACE'; Percent1:String[7]='COMMENT'; Percent2:String[7]='PERCENT'; Percent3:String[3]='EOL'; NoPercent1:String[9]='NOCOMMENT'; NoPercent2:String[9]='NOPERCENT'; NoPercent3:String[5]='NOEOL'; EUC1:String[3]='EUC'; NoEUC1:String[7]='MSKANJI'; NoEUC2:String[8]='SHIFTJIS'; Extended1:String[8]='EXTENDED'; Standard1:String[8]='STANDARD'; LaTeX1:String[5]='LATEX'; TeX1:String[5]='MUTEX'; TeX2:String[3]='TEX'; One1:String[4]='1000'; Two1:String[4]='1095'; Three1:String[4]='1200'; Four1:String[4]='1440'; Five1:String[4]='1728'; Six1:String[4]='2074'; Seven1:String[4]='2488'; One2:String[3]='0.0'; Two2:String[3]='0.5'; Three2:String[3]='1.0'; Four2:String[3]='2.0'; Five2:String[3]='3.0'; Six2:String[3]='4.0'; Seven2:String[3]='5.0'; One3:String[1]='0'; Three3:String[1]='1'; Four3:String[1]='2'; Five3:String[1]='3'; Six3:String[1]='4'; Seven3:String[1]='5'; Type InFileType=File Of Byte; OutFileType=Text; BitmapRange=1..BitmapMax; FontRange=0..FontMax; FontType=Array [FontRange] Of Boolean; SizeRange=1..SizeMax; FontsType=Array [SizeRange] Of FontType; {Run time parameters} RunTimeType=Record FileName,Extension:String; ExtraSpace,Percent,LaTeX,EUC,Extended:Boolean; Size:SizeRange; End; {Japanese punctuation information} PunctuationType=Record {Indicates .,!? present} OldMajorEOL,NewMajorEOL:Boolean; {Indicates :; present} OldMinorEOL,NewMinorEOL:Boolean; {Indicates `"([< and other openings present} OldOpening,NewOpening:Boolean; {Indicates '")]> and other closings present} OldClosing,NewClosing:Boolean; {Indicates Japanese center dot present} OldCenterDot,NewCenterDot:Boolean; {Indicates Hiragana, Katakana, or Kanji present} OldJapanese,NewJapanese:Boolean End; {Scanning Information} ScanningType=Record {Current pass terminated} Done:Boolean; {Indicates the current pass must produce output} Echo:Boolean; {Indicates the current line is a comment} Comment:Boolean; {Indicates current Bitmap immediately followed previous one} Immediate:Boolean; {Indicates the last Roman character was a letter or digit} WasLetter:Boolean; {Used for glue after a bitmap and before a roman} RomanMajorEOL,RomanMinorEOL,RomanOpening:Boolean; {Non-comment Bitmap found} Found:Boolean; {Processing the first character on the line which could be %} First:Boolean; {Comment line which may contain Bitmaps} CommentLine:String; {Current JIS24 Bitmap number} Bitmap:BitmapRange; {Roman or first part of Bitmap read} Data1:Byte End; Var {Input and Output file names} InFile:InFileType; OutFile:OutFileType; {Run time parameters} RunTime:RunTimeType; {JemTeX fonts used} Fonts:FontsType; {------------------------------ EchoParameters -------------------------------} Procedure EchoParameters(Var EchoFile:Text; Var RunTime:RunTimeType); {Echoes the current parameters in EchoFile} Begin With RunTime Do Begin Write(EchoFile,'File='+FileName); If ExtraSpace Then Write(EchoFile,' Space') Else Write(EchoFile,' No Space'); If Percent Then Write(EchoFile,' Added %') Else Write(EchoFile,' No Added %'); If LaTeX Then Write(EchoFile,' LaTeX') Else Write(EchoFile,' TeX'); If EUC Then Write(EchoFile,' EUC') Else Write(EchoFile,' MS-kanji'); If Extended Then Write(EchoFile,' Extended') Else Write(EchoFile,' Standard'); Write(EchoFile,' Font Size='); Case Size Of 1:Write(EchoFile,'1000'); 2:Write(EchoFile,'1095'); 3:Write(EchoFile,'1200'); 4:Write(EchoFile,'1440'); 5:Write(EchoFile,'1728'); 6:Write(EchoFile,'2074'); 7:Write(EchoFile,'2488') End; Writeln(EchoFile,'.') End End; {------------------------------- GetParameters -------------------------------} Procedure SimpleQuery(Title,ChoiceA,ChoiceB:String; Var Answer:Boolean); Var JChar:Char; Valid:Boolean; Begin Repeat Valid:=True; Writeln(Title+':'); Writeln(' a) '+ChoiceA); Writeln(' b) '+ChoiceB); Write('Your choice? '); Readln(JChar); JChar:=UpCase(JChar); If JChar='A' Then Answer:=True Else If JChar='B' Then Answer:=False Else Begin Valid:=False; Write(Chr(7)) End Until Valid; Writeln End; Procedure SizeQuery(Var Size:SizeRange); Var JChar:Char; Valid:Boolean; Begin Repeat Valid:=True; Writeln('Japanese Font Size:'); Writeln(' a) 1000 magstep(0.0)'); Writeln(' b) 1095 magstep(0.5)'); Writeln(' c) 1200 magstep(1.0)'); Writeln(' d) 1440 magstep(2.0)'); Writeln(' e) 1728 magstep(3.0)'); Writeln(' f) 2074 magstep(4.5)'); Writeln(' g) 2488 magstep(5.0)'); Write('Your choice? '); Readln(JChar); JChar:=UpCase(JChar); If ('A'<=JChar) And (JChar<='G') Then Size:=Ord(JChar)-Ord('A')+1 Else Begin Valid:=False; Write(Chr(7)) End Until Valid; Writeln End; Procedure Manual(Var RunTime:RunTimeType); {Get parameters from user} Begin With RunTime Do Begin Write('Japanese file name? '); Readln(FileName); Writeln; SimpleQuery('Space around Japanese punctuation','Space','No space',ExtraSpace); SimpleQuery('Added % at Japanese end of lines','Added %','No added %',Percent); SimpleQuery('LaTeX or TeX (MuTeX) output','LaTeX','TeX',LaTeX); SimpleQuery('EUC or MS-kanji (Shift-JIS) encoding','EUC','MS-kanji',EUC); SimpleQuery('Extended JIS ''83 Bitmaps allowed','Extended','Standard',Extended); SizeQuery(Size) End End; Procedure Automate(Var RunTime:RunTimeType); {Get parameters from command line} Var ParamIndex,Index:Integer; Param:String; Begin With RunTime Do Begin {Defaults} FileName:='japanese'; ExtraSpace:=True; Percent:=True; LaTeX:=True; EUC:=True; Extended:=True; Size:=4; {Scan command line parameters} For ParamIndex:=1 To ParamCount Do Begin Param:=ParamStr(ParamIndex); If (Param[1]=Flag1) Or (Param[1]=Flag2) Then {Not a filename} Begin {Delete 1 char at the 1st position} Delete(Param,1,1); {Convert to upper case} For Index:=1 To Length(Param) Do Param[Index]:=UpCase(Param[Index]); {Scan known keywords} If (Param=Space1) Or (Param=Space2) Or (Param=Space3)Then ExtraSpace:=True Else If (Param=NoSpace1) Or (Param=NoSpace2) Or (Param=NoSpace3) Then ExtraSpace:=False Else If (Param=Percent1) Or (Param=Percent2) Or (Param=Percent3) Then Percent:=True Else If (Param=NoPercent1) Or (Param=NoPercent2) Or (Param=NoPercent3) Then Percent:=False Else If Param=EUC1 Then EUC:=True Else If (Param=NoEUC1) Or (Param=NoEUC2) Then EUC:=False Else If Param=Extended1 Then Extended:=True Else If Param=Standard1 Then Extended:=False Else If Param=LaTeX1 Then LaTeX:=True Else If (Param=TeX1) Or (Param=TeX2) Then LaTeX:=False Else If (Param=One1) Or (Param=One2) Or (Param=One3) Then Size:=1 Else If (Param=Two1) Or (Param=Two2) Then Size:=2 Else If (Param=Three1) Or (Param=Three2) Or (Param=Three3) Then Size:=3 Else If (Param=Four1) Or (Param=Four2) Or (Param=Four3) Then Size:=4 Else If (Param=Five1) Or (Param=Five2) Or (Param=Five3) Then Size:=5 Else If (Param=Six1) Or (Param=Six2) Or (Param=Six3) Then Size:=6 Else If (Param=Seven1) Or (Param=Seven2) Or (Param=Seven3) Then Size:=7 Else {Unknown keyword} Begin Writeln(Chr(7)+'Invalid command line parameter: '+Param+'...'); Halt(1) End End Else {Must be a filename, we'll try to open it later} FileName:=Param End End End; Procedure GetParameters(Var RunTime:RunTimeType); {Get parameters from user or command line} {Current parameter status is echoed on the console} Begin If ParamCount=0 Then Manual(RunTime) Else Automate(RunTime); EchoParameters(Output,RunTime) End; {-------------------------------- OpenFile -----------------------------------} Function TryExtension(Var InFile:InFileType; Var RunTime:RunTimeType; TriedExtension:String):Boolean; {Tries to open FileName using TriedExtension} Begin With RunTime Do Begin Extension:=TriedExtension; Assign(InFile,FileName+TriedExtension); {$I-}Reset(InFile);{$I+} {IOResult must be immediately used once only} TryExtension:=(IOResult=0) End End; Procedure OpenFile(Var InFile:InFileType; Var RunTime:RunTimeType); {Tries to open FileName using all available extensions} Begin If TryExtension(InFile,RunTime,Extension1) Then Write(Extension1) Else If TryExtension(InFile,RunTime,Extension2) Then Write(Extension2) Else If TryExtension(InFile,RunTime,Extension3) Then Write(Extension3) Else Begin Writeln('.'); Writeln(Chr(7)+'File not found'+'...'); Halt(1) End End; {-------------------------------- GetBitmap ----------------------------------} Procedure PerformScan(Var CommentLine:String; Var RunTime:RunTimeType; Echo:Boolean; Var OutFile:OutFileType); {Scans the comment line for run-time JEM2TEX parameters} {Any Bitmap or unknown parameter stops the scan} {Current parameter status is echoed in the .TeX file as a [La]TeX comment} Var Index:Integer; Begin {Delete 1 char at the 1st position which is %} Delete(CommentLine,1,1); {Convert to upper case} For Index:=1 To Length(CommentLine) Do CommentLine[Index]:=UpCase(CommentLine[Index]); {Add space at the line end to characterize premature termination} {Add sentinel at the line end to stop forthcoming loops} CommentLine:=CommentLine+' %'; {Delete leading blanks} If CommentLine[1]=' ' Then Repeat Delete(CommentLine,1,1) Until CommentLine[1]<>' '; {Look for run-time flag at the start of line} If ( RunFlag1=Copy(CommentLine,1,Length(RunFlag1)) ) Or ( RunFlag2=Copy(CommentLine,1,Length(RunFlag1)) ) Or ( RunFlag3=Copy(CommentLine,1,Length(RunFlag1)) ) Then Begin {Remove run-time flag} Delete(CommentLine,1,Length(RunFlag1)); {Scan until sentinel reached} Repeat {Delete leading blanks} If CommentLine[1]=' ' Then Repeat Delete(CommentLine,1,1) Until CommentLine[1]<>' '; If (CommentLine[1]=Flag1) Or (CommentLine[1]=Flag2) Then {Valid run-time parameter flag} Begin {Delete 1 char at the 1st position which is flag} Delete(CommentLine,1,1); {Scan in decreasing length order} With RunTime Do Begin If Space1=Copy(CommentLine,1,Length(Space1)) Then Begin Delete(CommentLine,1,Length(Space1)); ExtraSpace:=True End Else If Space2=Copy(CommentLine,1,Length(Space2)) Then Begin Delete(CommentLine,1,Length(Space2)); ExtraSpace:=True End Else If Space3=Copy(CommentLine,1,Length(Space3)) Then Begin Delete(CommentLine,1,Length(Space3)); ExtraSpace:=True End Else If NoSpace1=Copy(CommentLine,1,Length(NoSpace1)) Then Begin Delete(CommentLine,1,Length(NoSpace1)); ExtraSpace:=False End Else If NoSpace2=Copy(CommentLine,1,Length(NoSpace2)) Then Begin Delete(CommentLine,1,Length(NoSpace2)); ExtraSpace:=False End Else If NoSpace3=Copy(CommentLine,1,Length(NoSpace3)) Then Begin Delete(CommentLine,1,Length(NoSpace3)); ExtraSpace:=False End Else If Percent1=Copy(CommentLine,1,Length(Percent1)) Then Begin Delete(CommentLine,1,Length(Percent1)); Percent:=True End Else If Percent2=Copy(CommentLine,1,Length(Percent2)) Then Begin Delete(CommentLine,1,Length(Percent2)); Percent:=True End Else If Percent3=Copy(CommentLine,1,Length(Percent3)) Then Begin Delete(CommentLine,1,Length(Percent3)); Percent:=True End Else If NoPercent1=Copy(CommentLine,1,Length(NoPercent1)) Then Begin Delete(CommentLine,1,Length(NoPercent1)); Percent:=False End Else If NoPercent2=Copy(CommentLine,1,Length(NoPercent2)) Then Begin Delete(CommentLine,1,Length(NoPercent2)); Percent:=False End Else If NoPercent3=Copy(CommentLine,1,Length(NoPercent3)) Then Begin Delete(CommentLine,1,Length(NoPercent3)); Percent:=False End Else If EUC1=Copy(CommentLine,1,Length(EUC1)) Then Begin Delete(CommentLine,1,Length(EUC1)); EUC:=True End Else If NoEUC1=Copy(CommentLine,1,Length(NoEUC1)) Then Begin Delete(CommentLine,1,Length(NoEUC1)); EUC:=False End Else If NoEUC2=Copy(CommentLine,1,Length(NoEUC2)) Then Begin Delete(CommentLine,1,Length(NoEUC2)); EUC:=False End Else If Extended1=Copy(CommentLine,1,Length(Extended1)) Then Begin Delete(CommentLine,1,Length(Extended1)); Extended:=True End Else If Standard1=Copy(CommentLine,1,Length(Standard1)) Then Begin Delete(CommentLine,1,Length(Standard1)); Extended:=False End Else If LaTeX1=Copy(CommentLine,1,Length(LaTeX1)) Then Begin Delete(CommentLine,1,Length(LaTeX1)); LaTeX:=True End Else If TeX1=Copy(CommentLine,1,Length(TeX1)) Then Begin Delete(CommentLine,1,Length(TeX1)); LaTeX:=False End Else If TeX2=Copy(CommentLine,1,Length(TeX2)) Then Begin Delete(CommentLine,1,Length(TeX2)); LaTeX:=False End Else If One1=Copy(CommentLine,1,Length(One1)) Then Begin Delete(CommentLine,1,Length(One1)); Size:=1 End Else If Two1=Copy(CommentLine,1,Length(Two1)) Then Begin Delete(CommentLine,1,Length(Two1)); Size:=2 End Else If Three1=Copy(CommentLine,1,Length(Three1)) Then Begin Delete(CommentLine,1,Length(Three1)); Size:=3 End Else If Four1=Copy(CommentLine,1,Length(Four1)) Then Begin Delete(CommentLine,1,Length(Four1)); Size:=4 End Else If Five1=Copy(CommentLine,1,Length(Five1)) Then Begin Delete(CommentLine,1,Length(Five1)); Size:=5 End Else If Six1=Copy(CommentLine,1,Length(Six1)) Then Begin Delete(CommentLine,1,Length(Six1)); Size:=6 End Else If Seven1=Copy(CommentLine,1,Length(Seven1)) Then Begin Delete(CommentLine,1,Length(Seven1)); Size:=7 End Else If One2=Copy(CommentLine,1,Length(One2)) Then Begin Delete(CommentLine,1,Length(One2)); Size:=1 End Else If Two2=Copy(CommentLine,1,Length(Two2)) Then Begin Delete(CommentLine,1,Length(Two2)); Size:=2 End Else If Three2=Copy(CommentLine,1,Length(Three2)) Then Begin Delete(CommentLine,1,Length(Three2)); Size:=3 End Else If Four2=Copy(CommentLine,1,Length(Four2)) Then Begin Delete(CommentLine,1,Length(Four2)); Size:=4 End Else If Five2=Copy(CommentLine,1,Length(Five2)) Then Begin Delete(CommentLine,1,Length(Five2)); Size:=5 End Else If Six2=Copy(CommentLine,1,Length(Six2)) Then Begin Delete(CommentLine,1,Length(Six2)); Size:=6 End Else If Seven2=Copy(CommentLine,1,Length(Seven2)) Then Begin Delete(CommentLine,1,Length(Seven2)); Size:=7 End Else If One3=Copy(CommentLine,1,Length(One3)) Then Begin Delete(CommentLine,1,Length(One3)); Size:=1 End Else If Three3=Copy(CommentLine,1,Length(Three3)) Then Begin Delete(CommentLine,1,Length(Three3)); Size:=3 End Else If Four3=Copy(CommentLine,1,Length(Four3)) Then Begin Delete(CommentLine,1,Length(Four3)); Size:=4 End Else If Five3=Copy(CommentLine,1,Length(Five3)) Then Begin Delete(CommentLine,1,Length(Five3)); Size:=5 End Else If Six3=Copy(CommentLine,1,Length(Six3)) Then Begin Delete(CommentLine,1,Length(Six3)); Size:=6 End Else If Seven3=Copy(CommentLine,1,Length(Seven3)) Then Begin Delete(CommentLine,1,Length(Seven3)); Size:=7 End Else {Unknown run-time parameter} {Terminate prematurely current scan} CommentLine:='%' End; {Echo status if allowed} If Echo And (CommentLine<>'%') Then Begin Write(OutFile,'%'); EchoParameters(OutFile,RunTime) End End Else {Unknown run-time parameter flag} {Terminate prematurely current scan} CommentLine:='%' Until Length(CommentLine)=1 End End; Procedure LineBreak(Var OutFile:OutFileType; ExtraSpace:Boolean; Var Scanning:ScanningType); {The continuous chain of Bitmaps has just been interrupted by a line break} {We know the next Roman character is equivalent to a space, i.e. not a letter} {A \eeee may be inserted if the previous Bitmap was a .,!?} {A \eee may be inserted if the previous Bitmap was a :; center dot )]'"} {If glue inserted, make sure to leave a totally blank line as present before} Begin With Scanning Do Begin Immediate:=False; If Echo And ExtraSpace Then If RomanMajorEOL Then Writeln(OutFile,'\eeee') Else If RomanMinorEOL Then Writeln(OutFile,'\eee') End End; Procedure RomanBreak(Var OutFile:OutFileType; ExtraSpace:Boolean; Var Scanning:ScanningType); {The continuous chain of Bitmaps has just been interrupted by a Roman} {The next Roman character may be a letter so a \eee is possible} {A \eeee may be inserted if the previous Bitmap was a .,!?} {A \eee may be inserted if the previous Bitmap was a :; center dot )]'"} {Curly brackets are used in \eee and \eeee when the next Roman is a letter} Begin With Scanning Do Begin Immediate:=False; If Echo And ExtraSpace Then If RomanMajorEOL Then If WasLetter Then Write(OutFile,'\eeee{}') Else Write(OutFile,'\eeee') Else If RomanMinorEOL Then If WasLetter Then Write(OutFile,'\eee{}') Else Write(OutFile,'\eee') Else If WasLetter And Not RomanOpening Then Write(OutFile,'\eee{}') End End; Procedure GotUNIX(Var OutFile:OutFileType; Var Scanning:ScanningType; Var RunTime:RunTimeType); {Handles UNIX EOL} {May add glue after the previous Bitmap and before this Roman} Begin With Scanning,RunTime Do Begin If Immediate Then If First Then LineBreak(OutFile,ExtraSpace,Scanning) Else If Not Comment Then If Percent Then If Echo Then Write(OutFile,'%') Else Else LineBreak(OutFile,ExtraSpace,Scanning); If Echo Then Writeln(OutFile); If Comment Then If Not First Then PerformScan(CommentLine,RunTime,Echo,OutFile) Else Else WasLetter:=False; First:=True; Comment:=True; CommentLine:='' End End; Procedure GotDOS(Var OutFile:OutFileType; Var Scanning:ScanningType; Var RunTime:RunTimeType; Var InFile:InFileType); {Handles DOS EOL} {May add glue after the previous Bitmap and before this Roman} {An error only stops the current pass to help the user determine its cause} Var Data2:Byte; Begin With Scanning Do Begin GotUNIX(OutFile,Scanning,RunTime); {Line Feed must follow immediately} If EOF(InFile) Then Done:=True Else Begin Read(InFile,Data2); If Data2<>$0A Then Done:=True End; If Done Then Begin Writeln('.'); Write(Chr(7)+'Abnormal DOS end of line..') End End End; Procedure ValidateBitmap(Bitmap:BitmapRange); {Prints a warning when an extended or an empty Bitmap is used} Var Invalid:Boolean; Begin Invalid:=False; If (109<=Bitmap) And (Bitmap<=119) Then Invalid:=True Else If (128<=Bitmap) And (Bitmap<=135) Then Invalid:=True Else If (143<=Bitmap) And (Bitmap<=153) Then Invalid:=True Else If (169<=Bitmap) And (Bitmap<=175) Then Invalid:=True Else If (184<=Bitmap) And (Bitmap<=203) Then Invalid:=True Else If (214<=Bitmap) And (Bitmap<=220) Then Invalid:=True Else If (247<=Bitmap) And (Bitmap<=252) Then Invalid:=True Else If (279<=Bitmap) And (Bitmap<=282) Then Invalid:=True Else If Bitmap=366 Then Invalid:=True Else If (463<=Bitmap) And (Bitmap<=470) Then Invalid:=True Else If (495<=Bitmap) And (Bitmap<=502) Then Invalid:=True Else If (527<=Bitmap) And (Bitmap<=564) Then Invalid:=True Else If (598<=Bitmap) And (Bitmap<=612) Then Invalid:=True Else If (646<=Bitmap) And (Bitmap<=658) Then Invalid:=True Else If (691<=Bitmap) And (Bitmap<=1410) Then Invalid:=True Else If (4376<=Bitmap) And (Bitmap<=4418) Then Invalid:=True; If Invalid Then Begin Writeln('.'); Write('Warning! The non-standard JIS ''83 Bitmap ',Bitmap,' encountered') End End; Procedure GotBitmap(Var OutFile:OutFileType; EUC,Extended:Boolean; Var InFile:InFileType; Var Scanning:ScanningType); {Handles Bitmap} {An error only stops the current pass to help the user determine its cause} {If desired, non-standard Bitmaps are pointed out in the first pass} Var Data2:Byte; Begin With Scanning Do Begin If First Then {First character on line} Begin First:=False; Comment:=False End; If EOF(InFile) Then Begin Done:=True; Writeln('.'); If EUC Then Write(Chr(7)+'Incomplete EUC character pair..') Else Write(Chr(7)+'Incomplete MS-kanji character pair..') End Else Begin Read(InFile,Data2); If EUC Then If ($A0=$E0) Then Bitmap:=1+188*(Data1-$C1) Else Bitmap:=1+188*(Data1-$81); If (Data2>=$80) Then Bitmap:=Bitmap+(Data2-$41) Else Bitmap:=Bitmap+(Data2-$40) End Else Begin Done:=True; Writeln('.'); Write(Chr(7)+'Invalid MS-kanji character pair..') End; If Not Done Then {Bitmaps in comment skipped} If Comment Then Begin CommentLine:=CommentLine+Chr(Data1)+Chr(Data2); If Echo Then Write(OutFile,Chr(Data1)+Chr(Data2)) End Else If (1<=Bitmap) And (Bitmap<=BitmapMax) Then Begin Found:=True; {Point out non-standard Bitmaps in first pass} If Not Echo And Not Extended Then ValidateBitmap(Bitmap) End Else Begin Done:=True; Writeln('.'); Write(Chr(7)+'Bitmap ',Bitmap,' does not exist..') End End End End; Procedure GotRoman(Var OutFile:OutFileType; ExtraSpace:Boolean; Var Scanning:ScanningType); {Handles roman} {May add glue after the previous Bitmap and before this Roman} Begin With Scanning Do Begin If First Then {First character on line} Begin First:=False; If Chr(Data1)<>'%' Then Comment:=False End; If Comment Then CommentLine:=CommentLine+Chr(Data1) Else Begin {Determine if this roman is a letter or a number} WasLetter:=( ('A'<=UpCase(Chr(Data1))) And (UpCase(Chr(Data1))<='Z') ) Or ( ('0'<=Chr(Data1)) And (Chr(Data1)<='9') ); If Immediate Then RomanBreak(OutFile,ExtraSpace,Scanning) End; If Echo Then Write(OutFile,Chr(Data1)) End End; Procedure GetBitmap(Var InFile:InFileType; Var OutFile:OutFileType; Var Scanning:ScanningType; Var RunTime:RunTimeType); {Scans input file and stops when a Bitmap is met} {An error only stops the current pass to help the user determine its cause} {Accepts UNIX LF or DOS CR/LF as end of line indicator in input file} {Updates JemTeX parameters with run-time parameters} {Comment indicates the line is a comment line and does not break continuity} {Immediate indicates the current Bitmap immediately followed previous Bitmap} {If the next character encountered is Roman, glue may be inserted} {If desired, will add % at Japanese end of lines to preserve continuity} Begin With Scanning,RunTime Do Begin {No Bitmap found initially} Found:=False; {Assume the next character is a Bitmap} WasLetter:=False; Immediate:=True; {Some non-comment Bitmap was met before or it's the first call to GetBitmap} CommentLine:=''; {Comment holds; it's the first call ever to GetBitmap; it's first character} {Comment fails; some non-comment Bitmap was met before; it isnt 1st character} First:=Comment; Repeat {Check if file just finished} If EOF(InFile) Then Done:=True Else {More file coming} Begin Read(InFile,Data1); If Data1=$0A Then GotUNIX(OutFile,Scanning,RunTime) Else If Data1=$0D Then GotDOS(OutFile,Scanning,RunTime,InFile) Else If EUC Then If ($A0 and other closings} If (39<=Bitmap) And (Bitmap<=59) And Odd(Bitmap) Then NewClosing:=True Else {Half width '")]> and other closings} If (697<=Bitmap) And (Bitmap<=717) And Odd(Bitmap) Then NewClosing:=True Else {Full width Japanese center dot} If (Bitmap=6) Then NewCenterDot:=True Else {Half width Japanese center dot} If (Bitmap=469) Then NewCenterDot:=True Else {Full width Hiragana} If (283<=Bitmap) And (Bitmap<=365) Then NewJapanese:=True Else {Full width Katakana} If (377<=Bitmap) And (Bitmap<=462) Then NewJapanese:=True Else {Full width Kanji level 1} If (1411<=Bitmap) And (Bitmap<=4375) Then NewJapanese:=True Else {Full width Kanji level 2} If (4419<=Bitmap) And (Bitmap<=7806) Then NewJapanese:=True Else {Script Hiragana} If (753<=Bitmap) And (Bitmap<=835) Then NewJapanese:=True Else {Script Katakana} If (847<=Bitmap) And (Bitmap<=932) Then NewJapanese:=True End End; Procedure Hyphenate(Var OutFile:OutFileType; Var Punctuation:PunctuationType); {Adds hyphenation between consecutive Bitmaps} Begin With Punctuation Do {No hyphenation between two odd symbols} If OldJapanese Or NewJapanese Then {No hyphenation before some symbols} If Not NewMajorEOL And Not NewMinorEOL And Not NewCenterDot And Not NewClosing Then {No hyphenation after some symbols} If Not OldOpening Then Write(OutFile,'\hh') End; Procedure Glue(Var OutFile:OutFileType; Var Punctuation:PunctuationType; ExtraSpace:Boolean); {Adds glue between consecutive Bitmaps} Var GlueAdded:Boolean; Begin With Punctuation Do Begin GlueAdded:=False; If ExtraSpace Then Begin {Trying to add big glue} If OldMajorEOL Then {No big glue between identical symbols} If Not NewMajorEOL Then {No big glue before some symbols} If Not NewClosing Then Begin GlueAdded:=True; Write(OutFile,'\eeee') End; If Not GlueAdded Then {Trying to add medium glue based on old symbol} If OldMinorEOL Or OldCenterDot Or OldClosing Then {No medium glue before some symbols} If Not NewMajorEOL And Not NewMinorEOL And Not NewClosing Then Begin GlueAdded:=True; Write(OutFile,'\eee') End; If Not GlueAdded Then {Trying to add medium glue based on new symbol} If NewCenterDot Or NewOpening Then {No medium glue after some symbols} If Not OldOpening Then Begin GlueAdded:=True; Write(OutFile,'\eee') End End; {Always make sure to add some glue} If Not GlueAdded Then Write(OutFile,'\ee') End End; Procedure Convert(Var InFile:InFileType; Var OutFile:OutFileType; Var RunTime:RunTimeType); {Convert .JEM into .TeX by translating Bitmaps and adding hyphenation and glue} Var {Japanese punctuation information} Punctuation:PunctuationType; {Scanning information} Scanning:ScanningType; {Current font number} FontPtr:FontRange; C0,C1,C2:Char; Begin With Punctuation,Scanning,RunTime Do Begin {Not reached EOF yet} Done:=False; {Echo in second pass} Echo:=True; {Nothing done yet} Immediate:=False; WasLetter:=False; {Tell indirectly to GetBitmap that this is the first time it is called} Comment:=True; {Initial japanese punctuation information} NewMajorEOL:=False; NewMinorEOL:=False; NewOpening:=False; NewClosing:=False; NewCenterDot:=False; NewJapanese:=False; Repeat {Set up scanning information in case a roman letter follows immediately} RomanMajorEOL:=NewMajorEOL; RomanMinorEOL:=NewMinorEOL Or NewCenterDot Or NewClosing; RomanOpening:=NewOpening; {Get the next Bitmap skipping over [La]TeX comments} {May add glue between the old Bitmap and an hypothetical Roman} GetBitmap(InFile,OutFile,Scanning,RunTime); If Not Done Then Begin {Find what kind of Bitmap it is} BitmapType(Bitmap,Punctuation); If Immediate Then {Add hyphenation and glue between consecutive Bitmaps} Begin Hyphenate(OutFile,Punctuation); Glue(OutFile,Punctuation,ExtraSpace) End Else {Add glue after the old Roman and before this new Bitmap} If ExtraSpace Then If NewCenterDot Or NewOpening Then Write(OutFile,'\eee') Else If WasLetter Then {No medium glue before some symbols} If Not NewMajorEOL And Not NewMinorEOL And Not NewClosing Then Write(OutFile,'\eee'); {Write the Bitmap} C0:=Chr( Ord('a')+Size-1 ); FontPtr:=Bitmap Div 128; C1:=Chr( Ord('a')+(FontPtr Div 8) ); C2:=Chr( Ord('a')+(FontPtr Mod 8) ); Write(OutFile,'\kk{\k'+C0+C1+C2+'}{',Bitmap Mod 128,'}') {The next character may be Roman, GetBitmap will handle the glue then} End Until Done End End; {------------------------------------ Main -----------------------------------} Begin Writeln; Writeln('Japanese to [La]TeX Conversion Program.'); {To make Borland happy} Writeln('Version 2.00 Copyright F. Jalbert 1991.'); Writeln; GetParameters(RunTime); Writeln; Write('Opening Japanese file '+RunTime.FileName); OpenFile(InFile,RunTime); Writeln('.'); If RunTime.LaTeX Then Write('Creating LaTeX file '+RunTime.FileName+'.tex') Else Write('Creating TeX file '+RunTime.FileName+'.tex'); Assign(OutFile,RunTime.FileName+'.tex'); Rewrite(OutFile); Writeln('.'); Writeln; Write('Scanning Japanese file for fonts'); GetFont(InFile,Fonts,RunTime); Reset(InFile); Writeln('.'); If RunTime.LaTeX Then Write('Writing LaTeX header') Else Write('Writing TeX header'); Header(OutFile,Fonts,RunTime.LaTeX); Writeln('.'); Write('Converting Japanese file'); Convert(InFile,OutFile,RunTime); Writeln('.'); Writeln; Write('Closing Japanese file '+RunTime.FileName+RunTime.Extension); Close(InFile); Writeln('.'); If RunTime.LaTeX Then Write('Closing LaTeX file '+RunTime.FileName+'.tex') Else Write('Closing TeX file '+RunTime.FileName+'.tex'); Close(OutFile); Writeln('.'); Writeln; Writeln('Japanese to [La]TeX conversion completed.'); Writeln End.