/* -mt -f -A -K -G -O -w */ /* Compile with Turbo-C 2.0 */ /* 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. */ #include #include #include #ifdef __TURBOC__ #include #endif #define True 1 #define False 0 /* Highest Bitmap number in JIS24 */ #define BitmapMax 7806 /* Highest font number */ #define FontMax 60 /* Floor of 7806 Div 128 */ /* Highest size number */ #define SizeMax 7 /* magsteps are 0, 0.5, 1, 2, 3, 4, 5 */ /* DOS file name length */ #define FileNameDOS 250 /* includes path */ #define ExtensionDOS 4 /* includes . */ #define TotalNameDOS 254 /* File name extensions in priority order */ char Extension1[]=".jem"; char Extension2[]=".jpn"; char Extension3[]=".jap"; /* Run-time flag of all the same length */ char RunFlag1[]="JEM2TEX"; char RunFlag2[]="JPN2TEX"; char RunFlag3[]="JAP2TEX"; /* Parameter flag */ #define Flag1 '/' /* DOS style */ #define Flag2 '-' /* UNIX style */ /* Parameter keywords in approximate decreasing length order */ #define ParamMax 12 char Space1[]="EXTRASPACE"; char Space2[]="EXTRA"; char Space3[]="SPACE"; char NoSpace1[]="NOEXTRASPACE"; char NoSpace2[]="NOEXTRA"; char NoSpace3[]="NOSPACE"; char Percent1[]="COMMENT"; char Percent2[]="PERCENT"; char Percent3[]="EOL"; char NoPercent1[]="NOCOMMENT"; char NoPercent2[]="NOPERCENT"; char NoPercent3[]="NOEOL"; char EUC1[]="EUC"; char NoEUC1[]="MSKANJI"; char NoEUC2[]="SHIFTJIS"; char Extended1[]="EXTENDED"; char Standard1[]="STANDARD"; char LaTeX1[]="LATEX"; char TeX1[]="MUTEX"; char TeX2[]="TEX"; char One1[]="1000"; char Two1[]="1095"; char Three1[]="1200"; char Four1[]="1440"; char Five1[]="1728"; char Six1[]="2074"; char Seven1[]="2488"; char One2[]="0.0"; char Two2[]="0.5"; char Three2[]="1.0"; char Four2[]="2.0"; char Five2[]="3.0"; char Six2[]="4.0"; char Seven2[]="5.0"; char One3[]="0"; char Three3[]="1"; char Four3[]="2"; char Five3[]="3"; char Six3[]="4"; char Seven3[]="5"; /* Comment line maximum length */ #define CommentLineMax 254 typedef char FileNameType[FileNameDOS+1]; typedef char ExtensionType[ExtensionDOS+1]; typedef char TotalNameType[TotalNameDOS+1]; typedef char ParamType[ParamMax+1]; typedef int FontType[FontMax+1]; typedef FontType FontsType[SizeMax+1]; typedef char CommentLineType[CommentLineMax+2]; /* note the 2 used */ /* Run time parameters */ struct RunTimeType { FileNameType FileName; ExtensionType Extension; int ExtraSpace,Percent,LaTeX,EUC,Extended; int Size; }; /* Japanese punctuation information */ struct PunctuationType { /* Indicates .,!? present */ int OldMajorEOL,NewMajorEOL; /* Indicates :; present */ int OldMinorEOL,NewMinorEOL; /* Indicates `"([< and other openings present */ int OldOpening,NewOpening; /* Indicates '")]> and other closings present */ int OldClosing,NewClosing; /* Indicates Japanese center dot present */ int OldCenterDot,NewCenterDot; /* Indicates Hiragana, Katakana, or Kanji present */ int OldJapanese,NewJapanese; }; /* Scanning Information */ struct ScanningType { /* Current pass terminated */ int Done; /* Indicates the current pass must produce output */ int Echo; /* Indicates the current line is a comment */ int Comment; /* Indicates current Bitmap immediately followed previous one */ int Immediate; /* Indicates the last Roman character was a letter or digit */ int WasLetter; /* Used for glue after a bitmap and before a roman */ int RomanMajorEOL,RomanMinorEOL,RomanOpening; /* Non-comment Bitmap found */ int Found; /* Processing the first character on the line which could be % */ int First; /* Comment line which may contain Bitmaps */ CommentLineType CommentLine; /* Current JIS24 Bitmap number */ int Bitmap; /* Roman or first part of Bitmap read */ unsigned char Data1; }; void Delete(char *String, int Length) /* Delete the first Length characters of String */ { int Index; Index=0; do String[Index]=String[Index+Length]; while (String[++Index]!='\0'); } /*----------------------------- EchoParameters ------------------------------*/ void EchoParameters(FILE *EchoFile, struct RunTimeType *RunTime) /* Echoes the current parameters in EchoFile */ { fprintf(EchoFile,"File=%s",RunTime->FileName); if (RunTime->ExtraSpace) fprintf(EchoFile," Space"); else fprintf(EchoFile," No Space"); if (RunTime->Percent) fprintf(EchoFile," Added %%"); else fprintf(EchoFile," No Added %%"); if (RunTime->LaTeX) fprintf(EchoFile," LaTeX"); else fprintf(EchoFile," TeX"); if (RunTime->EUC) fprintf(EchoFile," EUC"); else fprintf(EchoFile," MS-kanji"); if (RunTime->Extended) fprintf(EchoFile," Extended"); else fprintf(EchoFile," Standard"); fprintf(EchoFile," Font Size="); switch (RunTime->Size) { case 1:fprintf(EchoFile,"1000"); break; case 2:fprintf(EchoFile,"1095"); break; case 3:fprintf(EchoFile,"1200"); break; case 4:fprintf(EchoFile,"1440"); break; case 5:fprintf(EchoFile,"1728"); break; case 6:fprintf(EchoFile,"2074"); break; case 7:fprintf(EchoFile,"2488"); break; } fprintf(EchoFile,".\n"); if (ferror(EchoFile)) exit(1); } /*------------------------------ GetParameters ------------------------------*/ void SimpleQuery(char Title[], char ChoiceA[], char ChoiceB[], int *Answer) { char JChar[2]; int Valid; do { Valid=True; printf("%s:\n",Title); printf(" a) %s\n",ChoiceA); printf(" b) %s\n",ChoiceB); printf("Your choice? "); if (ferror(stdout)) exit(1); if (gets(JChar)==NULL) exit(1); if (strlen(JChar)>1) exit(1); JChar[0]=toupper(JChar[0]); if (JChar[0]=='A') *Answer=True; else if (JChar[0]=='B') *Answer=False; else { Valid=False; if (putchar('\7')==EOF) exit(1); } } while (!Valid); printf("\n"); if (ferror(stdout)) exit(1); } void SizeQuery(int *Size) { char JChar[2]; int Valid; do { Valid=True; printf("Japanese Font Size:\n"); printf(" a) 1000 magstep(0.0)\n"); printf(" b) 1095 magstep(0.5)\n"); printf(" c) 1200 magstep(1.0)\n"); printf(" d) 1440 magstep(2.0)\n"); printf(" e) 1728 magstep(3.0)\n"); printf(" f) 2074 magstep(4.5)\n"); printf(" g) 2488 magstep(5.0)\n"); printf("Your choice? "); if (ferror(stdout)) exit(1); if (gets(JChar)==NULL) exit(1); if (strlen(JChar)>1) exit(1); JChar[0]=toupper(JChar[0]); if (('A'<=JChar[0]) && (JChar[0]<='G')) *Size=JChar[0]-'A'+1; else { Valid=False; if (putchar('\7')==EOF) exit(1); } } while (!Valid); printf("\n"); if (ferror(stdout)) exit(1); } void Manual(struct RunTimeType *RunTime) /* Get parameters from user */ { printf("Japanese file name? "); if (ferror(stdout)) exit(1); if (gets(RunTime->FileName)==NULL) exit(1); if (strlen(RunTime->FileName)>FileNameDOS) { /* File name too long */ printf("\7File name too long: %s...",RunTime->FileName); exit(1); } printf("\n"); if (ferror(stdout)) exit(1); SimpleQuery("Space around Japanese punctuation","Space","No space", &RunTime->ExtraSpace); SimpleQuery("Added % at Japanese end of lines","Added %","No added %", &RunTime->Percent); SimpleQuery("LaTeX or TeX (MuTeX) output","LaTeX","TeX",&RunTime->LaTeX); SimpleQuery("EUC or MS-kanji (Shift-JIS) encoding","EUC","MS-kanji", &RunTime->EUC); SimpleQuery("Extended JIS '83 Bitmaps allowed","Extended","Standard", &RunTime->Extended); SizeQuery(&RunTime->Size); } void Automate(struct RunTimeType *RunTime, int argc, char *argv[]) /* Get parameters from command line */ { int ParamIndex,ParamLength,Index; ParamType Param; /* Defaults */ strcpy(RunTime->FileName,"japanese"); RunTime->ExtraSpace=True; RunTime->Percent=True; RunTime->LaTeX=True; RunTime->EUC=True; RunTime->Extended=True; RunTime->Size=4; /* Scan command line parameters */ /* 0th is program's name, last is NULL */ for (ParamIndex=1 ; ParamIndexParamMax) { /* Keyword too long */ printf("\7Invalid command line parameter: %s...",argv[ParamIndex]); exit(1); } strcpy(Param,argv[ParamIndex]); if ((Param[0]==Flag1) || (Param[0]==Flag2)) { /* Not a filename */ /* Delete 1 char at the 1st position */ Delete(Param,1); /* Convert to upper case */ for (Index=0 ; IndexExtraSpace=True; else if ( (!strcmp(Param,NoSpace1)) || (!strcmp(Param,NoSpace2)) || (!strcmp(Param,NoSpace3)) ) RunTime->ExtraSpace=False; else if ( (!strcmp(Param,Percent1)) || (!strcmp(Param,Percent2)) || (!strcmp(Param,Percent3)) ) RunTime->Percent=True; else if ( (!strcmp(Param,NoPercent1)) || (!strcmp(Param,NoPercent2)) || (!strcmp(Param,NoPercent3)) ) RunTime->Percent=False; else if (!strcmp(Param,EUC1)) RunTime->EUC=True; else if ((!strcmp(Param,NoEUC1))||(!strcmp(Param,NoEUC2))) RunTime->EUC=False; else if (!strcmp(Param,Extended1)) RunTime->Extended=True; else if (!strcmp(Param,Standard1)) RunTime->Extended=False; else if (!strcmp(Param,LaTeX1)) RunTime->LaTeX=True; else if ((!strcmp(Param,TeX1)) || (!strcmp(Param,TeX2))) RunTime->LaTeX=False; else if ( (!strcmp(Param,One1)) || (!strcmp(Param,One2)) || (!strcmp(Param,One3)) ) RunTime->Size=1; else if ( (!strcmp(Param,Two1)) || (!strcmp(Param,Two2)) ) RunTime->Size=2; else if ( (!strcmp(Param,Three1)) || (!strcmp(Param,Three2)) || (!strcmp(Param,Three3)) ) RunTime->Size=3; else if ( (!strcmp(Param,Four1)) || (!strcmp(Param,Four2)) || (!strcmp(Param,Four3)) ) RunTime->Size=4; else if ( (!strcmp(Param,Five1)) || (!strcmp(Param,Five2)) || (!strcmp(Param,Five3)) ) RunTime->Size=5; else if ( (!strcmp(Param,Six1)) || (!strcmp(Param,Six2)) || (!strcmp(Param,Six3)) ) RunTime->Size=6; else if ( (!strcmp(Param,Seven1)) || (!strcmp(Param,Seven2)) || (!strcmp(Param,Seven3)) ) RunTime->Size=7; else { /* Unknown keyword */ printf("\7Invalid command line parameter: %s...\n",Param); exit(1); } } else { /* Must be a filename, we'll try to open it later */ if (ParamLength>FileNameDOS) { /* File name too long */ printf("\7File name too long: %s...\n",Param); exit(1); } strcpy(RunTime->FileName,Param); } } } void GetParameters(struct RunTimeType *RunTime, int argc, char *argv[]) /* Get parameters from user or command line */ /* Current parameter status is echoed on the console */ { /* 0th is program's name, last is NULL */ if (argc==1) Manual(RunTime); else Automate(RunTime,argc,argv); EchoParameters(stdout,RunTime); } /*------------------------------- OpenFile ----------------------------------*/ int TryExtension(FILE *(*InFile), struct RunTimeType *RunTime, ExtensionType TriedExtension) /* Tries to open FileName using TriedExtension */ { TotalNameType TotalName; strcpy(RunTime->Extension,TriedExtension); strcpy(TotalName,RunTime->FileName); strcat(TotalName,TriedExtension); *InFile=fopen(TotalName,"rt"); return(*InFile!=NULL); } void OpenFile(FILE *(*InFile), struct RunTimeType *RunTime) /* Tries to open FileName using all available extensions */ { if (TryExtension(InFile,RunTime,Extension1)) printf("%s",Extension1); else if (TryExtension(InFile,RunTime,Extension2)) printf("%s",Extension2); else if (TryExtension(InFile,RunTime,Extension3)) printf("%s",Extension3); else { printf(".\n"); printf("\7File not found...\n"); exit(1); } } /*------------------------------- GetBitmap ---------------------------------*/ void PerformScan(CommentLineType CommentLine, struct RunTimeType *RunTime, int Echo, FILE *OutFile) /* 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 */ { int Index; /* Delete 1 char at the 1st position which is % */ Delete(CommentLine,1); /* Convert to upper case */ for (Index=0 ; IndexExtraSpace=True; } else if (!strncmp(Space2,CommentLine,strlen(Space2))) { Delete(CommentLine,strlen(Space2)); RunTime->ExtraSpace=True; } else if (!strncmp(Space3,CommentLine,strlen(Space3))) { Delete(CommentLine,strlen(Space3)); RunTime->ExtraSpace=True; } else if (!strncmp(NoSpace1,CommentLine,strlen(NoSpace1))) { Delete(CommentLine,strlen(NoSpace1)); RunTime->ExtraSpace=False; } else if (!strncmp(NoSpace2,CommentLine,strlen(NoSpace2))) { Delete(CommentLine,strlen(NoSpace2)); RunTime->ExtraSpace=False; } else if (!strncmp(NoSpace3,CommentLine,strlen(NoSpace3))) { Delete(CommentLine,strlen(NoSpace3)); RunTime->ExtraSpace=False; } else if (!strncmp(Percent1,CommentLine,strlen(Percent1))) { Delete(CommentLine,strlen(Percent1)); RunTime->Percent=True; } else if (!strncmp(Percent2,CommentLine,strlen(Percent2))) { Delete(CommentLine,strlen(Percent2)); RunTime->Percent=True; } else if (!strncmp(Percent3,CommentLine,strlen(Percent3))) { Delete(CommentLine,strlen(Percent3)); RunTime->Percent=True; } else if (!strncmp(NoPercent1,CommentLine,strlen(NoPercent1))) { Delete(CommentLine,strlen(NoPercent1)); RunTime->Percent=False; } else if (!strncmp(NoPercent2,CommentLine,strlen(NoPercent2))) { Delete(CommentLine,strlen(NoPercent2)); RunTime->Percent=False; } else if (!strncmp(NoPercent3,CommentLine,strlen(NoPercent3))) { Delete(CommentLine,strlen(NoPercent3)); RunTime->Percent=False; } else if (!strncmp(EUC1,CommentLine,strlen(EUC1))) { Delete(CommentLine,strlen(EUC1)); RunTime->EUC=True; } else if (!strncmp(NoEUC1,CommentLine,strlen(NoEUC1))) { Delete(CommentLine,strlen(NoEUC1)); RunTime->EUC=False; } else if (!strncmp(NoEUC2,CommentLine,strlen(NoEUC2))) { Delete(CommentLine,strlen(NoEUC2)); RunTime->EUC=False; } else if (!strncmp(Extended1,CommentLine,strlen(Extended1))) { Delete(CommentLine,strlen(Extended1)); RunTime->Extended=True; } else if (!strncmp(Standard1,CommentLine,strlen(Standard1))) { Delete(CommentLine,strlen(Standard1)); RunTime->Extended=False; } else if (!strncmp(LaTeX1,CommentLine,strlen(LaTeX1))) { Delete(CommentLine,strlen(LaTeX1)); RunTime->LaTeX=True; } else if (!strncmp(TeX1,CommentLine,strlen(TeX1))) { Delete(CommentLine,strlen(TeX1)); RunTime->LaTeX=False; } else if (!strncmp(TeX2,CommentLine,strlen(TeX2))) { Delete(CommentLine,strlen(TeX2)); RunTime->LaTeX=False; } else if (!strncmp(One1,CommentLine,strlen(One1))) { Delete(CommentLine,strlen(One1)); RunTime->Size=1; } else if (!strncmp(Two1,CommentLine,strlen(Two1))) { Delete(CommentLine,strlen(Two1)); RunTime->Size=2; } else if (!strncmp(Three1,CommentLine,strlen(Three1))) { Delete(CommentLine,strlen(Three1)); RunTime->Size=3; } else if (!strncmp(Four1,CommentLine,strlen(Four1))) { Delete(CommentLine,strlen(Four1)); RunTime->Size=4; } else if (!strncmp(Five1,CommentLine,strlen(Five1))) { Delete(CommentLine,strlen(Five1)); RunTime->Size=5; } else if (!strncmp(Six1,CommentLine,strlen(Six1))) { Delete(CommentLine,strlen(Six1)); RunTime->Size=6; } else if (!strncmp(Seven1,CommentLine,strlen(Seven1))) { Delete(CommentLine,strlen(Seven1)); RunTime->Size=7; } else if (!strncmp(One2,CommentLine,strlen(One2))) { Delete(CommentLine,strlen(One2)); RunTime->Size=1; } else if (!strncmp(Two2,CommentLine,strlen(Two2))) { Delete(CommentLine,strlen(Two2)); RunTime->Size=2; } else if (!strncmp(Three2,CommentLine,strlen(Three2))) { Delete(CommentLine,strlen(Three2)); RunTime->Size=3; } else if (!strncmp(Four2,CommentLine,strlen(Four2))) { Delete(CommentLine,strlen(Four2)); RunTime->Size=4; } else if (!strncmp(Five2,CommentLine,strlen(Five2))) { Delete(CommentLine,strlen(Five2)); RunTime->Size=5; } else if (!strncmp(Six2,CommentLine,strlen(Six2))) { Delete(CommentLine,strlen(Six2)); RunTime->Size=6; } else if (!strncmp(Seven2,CommentLine,strlen(Seven2))) { Delete(CommentLine,strlen(Seven2)); RunTime->Size=7; } else if (!strncmp(One3,CommentLine,strlen(One3))) { Delete(CommentLine,strlen(One3)); RunTime->Size=1; } else if (!strncmp(Three3,CommentLine,strlen(Three3))) { Delete(CommentLine,strlen(Three3)); RunTime->Size=3; } else if (!strncmp(Four3,CommentLine,strlen(Four3))) { Delete(CommentLine,strlen(Four3)); RunTime->Size=4; } else if (!strncmp(Five3,CommentLine,strlen(Five3))) { Delete(CommentLine,strlen(Five3)); RunTime->Size=5; } else if (!strncmp(Six3,CommentLine,strlen(Six3))) { Delete(CommentLine,strlen(Six3)); RunTime->Size=6; } else if (!strncmp(Seven3,CommentLine,strlen(Seven3))) { Delete(CommentLine,strlen(Seven3)); RunTime->Size=7; } else /* Unknown run-time parameter */ /* Terminate prematurely current scan */ strcpy(CommentLine,"%"); /* Echo status if allowed */ if ( Echo && strcmp(CommentLine,"%") ) { fprintf(OutFile,"%"); if (ferror(OutFile)) exit(1); EchoParameters(OutFile,RunTime); } } else /* Unknown run-time parameter flag */ /* Terminate prematurely current scan */ strcpy(CommentLine,"%"); } while (strlen(CommentLine)!=1); } } void LineBreak(FILE *OutFile, int ExtraSpace, struct ScanningType *Scanning) /* The continuous chain of Bitmaps has just been interrupted by a line break */ /* We know the next Roman character is equivalent to 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 */ { Scanning->Immediate=False; if (Scanning->Echo && ExtraSpace) if (Scanning->RomanMajorEOL) { fprintf(OutFile,"\\eeee\n"); if (ferror(OutFile)) exit(1); } else if (Scanning->RomanMinorEOL) { fprintf(OutFile,"\\eee\n"); if (ferror(OutFile)) exit(1); } } void RomanBreak(FILE *OutFile, int ExtraSpace, struct ScanningType *Scanning) /* 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 */ { Scanning->Immediate=False; if (Scanning->Echo && ExtraSpace) if (Scanning->RomanMajorEOL) { if (Scanning->WasLetter) fprintf(OutFile,"\\eeee{}"); else fprintf(OutFile,"\\eeee"); if (ferror(OutFile)) exit(1); } else if (Scanning->RomanMinorEOL) { if (Scanning->WasLetter) fprintf(OutFile,"\\eee{}"); else fprintf(OutFile,"\\eee"); if (ferror(OutFile)) exit(1); } else if (Scanning->WasLetter && !Scanning->RomanOpening) { fprintf(OutFile,"\\eee{}"); if (ferror(OutFile)) exit(1); } } void GotUNIX(FILE *OutFile, struct ScanningType *Scanning, struct RunTimeType *RunTime) /* Handles UNIX EOL */ /* May add glue after the previous Bitmap and before this Roman */ { if (Scanning->Immediate) if (Scanning->First) LineBreak(OutFile,RunTime->ExtraSpace,Scanning); else if (!Scanning->Comment) if (RunTime->Percent) if (Scanning->Echo) { fprintf(OutFile,"%"); if (ferror(OutFile)) exit(1); } else ; else LineBreak(OutFile,RunTime->ExtraSpace,Scanning); if (Scanning->Echo) { fprintf(OutFile,"\n"); if (ferror(OutFile)) exit(1); } if (Scanning->Comment) if (!Scanning->First) PerformScan(Scanning->CommentLine,RunTime,Scanning->Echo,OutFile); else ; else Scanning->WasLetter=False; Scanning->First=True; Scanning->Comment=True; strcpy(Scanning->CommentLine,""); } void GotDOS(FILE *OutFile, struct ScanningType *Scanning, struct RunTimeType *RunTime, FILE *InFile) /* 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 */ { unsigned char Data2; GotUNIX(OutFile,Scanning,RunTime); /* Line Feed must follow immediately */ fscanf(InFile,"%c",&Data2); if (ferror(InFile)) exit(1); if (feof(InFile)) { clearerr(InFile); Scanning->Done=True; } else if (Data2!=(unsigned char)'\xA') Scanning->Done=True; if (Scanning->Done) { printf(".\n"); printf("\7Abnormal DOS end of line.."); if (ferror(stdout)) exit(1); } } void ValidateBitmap(int Bitmap) /* Prints a warning when an extended or an empty Bitmap is used */ { int Invalid; Invalid=False; if ((109<=Bitmap) && (Bitmap<=119) ) Invalid=True; else if ((128<=Bitmap) && (Bitmap<=135) ) Invalid=True; else if ((143<=Bitmap) && (Bitmap<=153) ) Invalid=True; else if ((169<=Bitmap) && (Bitmap<=175) ) Invalid=True; else if ((184<=Bitmap) && (Bitmap<=203) ) Invalid=True; else if ((214<=Bitmap) && (Bitmap<=220) ) Invalid=True; else if ((247<=Bitmap) && (Bitmap<=252) ) Invalid=True; else if ((279<=Bitmap) && (Bitmap<=282) ) Invalid=True; else if (Bitmap==366) Invalid=True; else if ((463<=Bitmap) && (Bitmap<=470) ) Invalid=True; else if ((495<=Bitmap) && (Bitmap<=502) ) Invalid=True; else if ((527<=Bitmap) && (Bitmap<=564) ) Invalid=True; else if ((598<=Bitmap) && (Bitmap<=612) ) Invalid=True; else if ((646<=Bitmap) && (Bitmap<=658) ) Invalid=True; else if ((691<=Bitmap) && (Bitmap<=1410) ) Invalid=True; else if ((4376<=Bitmap) && (Bitmap<=4418) ) Invalid=True; if (Invalid) { printf(".\n"); printf("Warning! The non-standard JIS '83 Bitmap %d encountered",Bitmap); if (ferror(stdout)) exit(1); } } void GotBitmap(FILE *OutFile, int EUC, int Extended, FILE *InFile, struct ScanningType *Scanning) /* 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 */ { unsigned char Data2; int CommentLength; if (Scanning->First) { /* First character on line */ Scanning->First=False; Scanning->Comment=False; } fscanf(InFile,"%c",&Data2); if (ferror(InFile)) exit(1); if (feof(InFile)) { clearerr(InFile); Scanning->Done=True; printf(".\n"); if (EUC) printf("\7Incomplete EUC character pair.."); else printf("\7Incomplete MS-kanji character pair.."); if (ferror(stdout)) exit(1); } else { if (EUC) if (((unsigned char)'\xA0'Bitmap=94*(int)(Scanning->Data1-(unsigned char)'\xA1')+ (int)(Data2-(unsigned char)'\xA1')+1; else { Scanning->Done=True; printf(".\n"); printf("\7Invalid EUC character pair.."); if (ferror(stdout)) exit(1); } else if ((((unsigned char)'\x40'<=Data2) && (Data2<=(unsigned char)'\x7E')) || (((unsigned char)'\x80'<=Data2) && (Data2<=(unsigned char)'\xFC'))) { if (Scanning->Data1>=(unsigned char)'\xE0') Scanning->Bitmap=1+188*(int)(Scanning->Data1-(unsigned char)'\xC1'); else Scanning->Bitmap=1+188*(int)(Scanning->Data1-(unsigned char)'\x81'); if (Data2>=(unsigned char)'\x80') Scanning->Bitmap+=(int)(Data2-(unsigned char)'\x41'); else Scanning->Bitmap+=(int)(Data2-(unsigned char)'\x40'); } else { Scanning->Done=True; printf(".\n"); printf("\7Invalid MS-kanji character pair.."); if (ferror(stdout)) exit(1); } if (!Scanning->Done) /* Bitmaps in comment skipped */ if (Scanning->Comment) { CommentLength=strlen(Scanning->CommentLine); if ((CommentLength+1)>=CommentLineMax) { /* Comment too long */ printf(".\n"); printf("\7Comment too long: %s...\n",Scanning->CommentLine); exit(1); } Scanning->CommentLine[CommentLength]=(char)Scanning->Data1; Scanning->CommentLine[CommentLength+1]=(char)Data2; Scanning->CommentLine[CommentLength+2]=(char)'\0'; if (Scanning->Echo) { fprintf(OutFile,"%c%c",Scanning->Data1,Data2); if (ferror(OutFile)) exit(1); } } else if ( (1<=Scanning->Bitmap) && (Scanning->Bitmap<=BitmapMax) ) { Scanning->Found=True; /* Point out non-standard Bitmaps in first pass */ if (!Scanning->Echo && !Extended) ValidateBitmap(Scanning->Bitmap); } else { Scanning->Done=True; printf(".\n"); printf("\7Bitmap %d does not exist..",Scanning->Bitmap); if (ferror(stdout)) exit(1); } } } void GotRoman(FILE *OutFile, int ExtraSpace,struct ScanningType *Scanning) /* Handles roman */ /* May add glue after the previous Bitmap and before this Roman */ { int CommentLength; if (Scanning->First) { /* First character on line */ Scanning->First=False; if (Scanning->Data1!=(unsigned char)'%') Scanning->Comment=False; } if (Scanning->Comment) { CommentLength=strlen(Scanning->CommentLine); if (CommentLength==CommentLineMax) { /* Comment too long */ printf(".\n"); printf("\7Comment too long: %s...\n",Scanning->CommentLine); exit(1); } Scanning->CommentLine[CommentLength]=(char)Scanning->Data1; Scanning->CommentLine[CommentLength+1]=(char)'\0'; } else { /* Determine if this roman is a letter or a number */ Scanning->WasLetter=isalnum(Scanning->Data1); if (Scanning->Immediate) RomanBreak(OutFile,ExtraSpace,Scanning); } if (Scanning->Echo) { fprintf(OutFile,"%c",Scanning->Data1); if (ferror(OutFile)) exit(1); } } void GetBitmap(FILE *InFile, FILE *OutFile, struct ScanningType *Scanning, struct RunTimeType *RunTime) /* 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 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 */ { /* No Bitmap found initially */ Scanning->Found=False; /* Assume the next character is a Bitmap */ Scanning->WasLetter=False; Scanning->Immediate=True; /* Some non-comment Bitmap was met before or it's the first call to GetBitmap */ strcpy(Scanning->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 first char */ Scanning->First=Scanning->Comment; do { fscanf(InFile,"%c",&Scanning->Data1); if (ferror(InFile)) exit(1); if (feof(InFile)) { /* File just finished */ clearerr(InFile); Scanning->Done=True; } else { /* More file coming */ if (Scanning->Data1==(unsigned char)'\xA') GotUNIX(OutFile,Scanning,RunTime); else if (Scanning->Data1==(unsigned char)'\xC') GotDOS(OutFile,Scanning,RunTime,InFile); else if (RunTime->EUC) if (((unsigned char)'\xA0'Data1) && (Scanning->Data1<(unsigned char)'\xFF')) GotBitmap(OutFile,RunTime->EUC,RunTime->Extended,InFile,Scanning); else GotRoman(OutFile,RunTime->ExtraSpace,Scanning); else if ( (((unsigned char)'\x81'<=Scanning->Data1) && (Scanning->Data1<=(unsigned char)'\x9F')) || (((unsigned char)'\xE0'<=Scanning->Data1) && (Scanning->Data1<=(unsigned char)'\xEA')) ) GotBitmap(OutFile,RunTime->EUC,RunTime->Extended,InFile,Scanning); else GotRoman(OutFile,RunTime->ExtraSpace,Scanning); } } while (!Scanning->Done && !Scanning->Found); } /*--------------------------------- GetFont ---------------------------------*/ void GetFont(FILE *InFile, FontsType Fonts, struct RunTimeType *InitialRunTime) /* Finds the Japanese fonts needed */ /* The last state of LaTeX will prevail for forthcoming header and 2nd pass */ { /* Run time parameters */ struct RunTimeType RunTime; /* Current font number */ int FontPtr; int SizePtr; /* Scanning information */ struct ScanningType Scanning; /* Dummy since no output in first pass */ FILE *DummyOutFile=NULL; strcpy(RunTime.FileName,InitialRunTime->FileName); strcpy(RunTime.Extension,InitialRunTime->Extension); RunTime.ExtraSpace=InitialRunTime->ExtraSpace; RunTime.Percent=InitialRunTime->Percent; RunTime.LaTeX=InitialRunTime->LaTeX; RunTime.EUC=InitialRunTime->EUC; RunTime.Extended=InitialRunTime->Extended; RunTime.Size=InitialRunTime->Size; /* No Japanese font needed so far */ for (SizePtr=1 ; SizePtr<=SizeMax ; SizePtr++) for (FontPtr=0 ; FontPtr<=FontMax ; FontPtr++) Fonts[SizePtr][FontPtr]=False; /* Not reached EOF yet */ Scanning.Done=False; /* No echo in first pass */ Scanning.Echo=False; /* Dummy since no output in first pass */ Scanning.Immediate=False; Scanning.WasLetter=False; Scanning.RomanMajorEOL=False; Scanning.RomanMinorEOL=False; Scanning.RomanOpening=False; /* Tell indirectly to GetBitmap that this is the first time it is called */ Scanning.Comment=True; do { /* Get the next Bitmap skipping over [La]TeX comments */ GetBitmap(InFile,DummyOutFile,&Scanning,&RunTime); if (!Scanning.Done) Fonts[RunTime.Size][Scanning.Bitmap/128]=True; } while (!Scanning.Done); /* Last state of LaTeX prevails for the second pass */ InitialRunTime->LaTeX=RunTime.LaTeX; } /*---------------------------------- Header ---------------------------------*/ void Header(FILE *OutFile, FontsType Fonts, int LaTeX) /* Writes [La]TeX header */ { int FontPtr; int SizePtr; char C0,C1,C2; int Scale; fprintf(OutFile,"\\tracingstats=1\n"); if (ferror(OutFile)) exit(1); for (SizePtr=1 ; SizePtr<=SizeMax ; SizePtr++) { C0='a'+(char)(SizePtr-1); switch (SizePtr) { case 1:Scale=1000; break; case 2:Scale=1095; break; case 3:Scale=1200; break; case 4:Scale=1440; break; case 5:Scale=1728; break; case 6:Scale=2074; break; case 7:Scale=2488; break; } for (FontPtr=0 ; FontPtr<=FontMax ; FontPtr++) if (Fonts[SizePtr][FontPtr]) { C1='a'+(char)(FontPtr / 8); C2='a'+(char)(FontPtr % 8); if (LaTeX) fprintf(OutFile,"\\newfont{\\k%c%c%c}{kanji%c%c scaled %d}\n", C0,C1,C2,C1,C2,Scale); else fprintf(OutFile,"\\font\\k%c%c%c=kanji%c%c scaled %d\n", C0,C1,C2,C1,C2,Scale); if (ferror(OutFile)) exit(1); } } if (LaTeX) { fprintf(OutFile,"\\newcommand{\\kk}[2]{{#1\\symbol{#2}}}\n"); fprintf(OutFile,"\\newcommand{\\hh}{\\discretionary{}{}{}}\n"); fprintf(OutFile,"\\newcommand{\\ee}{\\nobreak\\hskip0pt plus.1em\\relax}\n"); fprintf(OutFile,"\\newcommand{\\eee}{\\nobreak\\hskip.3em plus.1em\\relax}\n"); fprintf(OutFile,"\\newcommand{\\eeee}{\\nobreak\\hskip.9em plus.1em minus.1em}\n"); } else { fprintf(OutFile,"\\def\\kk#1#2{{#1\\char#2}}\n"); fprintf(OutFile,"\\def\\hh{\\discretionary{}{}{}}\n"); fprintf(OutFile,"\\def\\ee{\\nobreak\\hskip0pt plus.1em\\relax}\n"); fprintf(OutFile,"\\def\\eee{\\nobreak\\hskip.3em plus.1em\\relax}\n"); fprintf(OutFile,"\\def\\eeee{\\nobreak\\hskip.9em plus.1em minus.1em}\n"); } fprintf(OutFile,"\n"); if (ferror(OutFile)) exit(1); } /*--------------------------------- Convert ---------------------------------*/ void BitmapType(int Bitmap, struct PunctuationType *Punctuation) /* Finds characteristics of current Bitmap */ { Punctuation->OldMajorEOL=Punctuation->NewMajorEOL; Punctuation->OldMinorEOL=Punctuation->NewMinorEOL; Punctuation->OldOpening=Punctuation->NewOpening; Punctuation->OldClosing=Punctuation->NewClosing; Punctuation->OldCenterDot=Punctuation->NewCenterDot; Punctuation->OldJapanese=Punctuation->NewJapanese; Punctuation->NewMajorEOL=False; Punctuation->NewMinorEOL=False; Punctuation->NewOpening=False; Punctuation->NewClosing=False; Punctuation->NewCenterDot=False; Punctuation->NewJapanese=False; /* Full width .,!? */ if ((2<=Bitmap) && (Bitmap<=5)) Punctuation->NewMajorEOL=True; else if ((Bitmap==9) || (Bitmap==10)) Punctuation->NewMajorEOL=True; else /* Half width .,!? */ if ((Bitmap==691) || (Bitmap==720)) Punctuation->NewMajorEOL=True; else /* Full width :; */ if ((Bitmap==7) || (Bitmap==8)) Punctuation->NewMinorEOL=True; else /* Half width :; */ if ((Bitmap==692) || (Bitmap==693)) Punctuation->NewMinorEOL=True; else /* Full width `"([< and other openings */ if ((38<=Bitmap) && (Bitmap<=58) && !(Bitmap%2)) Punctuation->NewOpening=True; else /* Half width `"([< and other openings */ if ((696<=Bitmap)&& (Bitmap<=716)&& !(Bitmap%2)) Punctuation->NewOpening=True; else /* Full width '")]> and other closings */ if ((39<=Bitmap) && (Bitmap<=59) && (Bitmap%2)) Punctuation->NewClosing=True; else /* Half width '")]> and other closings */ if ((697<=Bitmap) && (Bitmap<=717)&& (Bitmap%2)) Punctuation->NewClosing=True; else /* Full width Japanese center dot */ if (Bitmap==6) Punctuation->NewCenterDot=True; else /* Half width Japanese center dot */ if (Bitmap==469) Punctuation->NewCenterDot=True; else /* Full width Hiragana */ if ((283<=Bitmap) && (Bitmap<=365)) Punctuation->NewJapanese=True; else /* Full width Katakana */ if ((377<=Bitmap) && (Bitmap<=462)) Punctuation->NewJapanese=True; else /* Full width Kanji level 1 */ if ((1411<=Bitmap) && (Bitmap<=4375)) Punctuation->NewJapanese=True; else /* Full width Kanji level 2 */ if ((4419<=Bitmap) && (Bitmap<=7806)) Punctuation->NewJapanese=True; else /* Script Hiragana */ if ((753<=Bitmap) && (Bitmap<=835)) Punctuation->NewJapanese=True; else /* Script Katakana */ if ((847<=Bitmap) && (Bitmap<=932)) Punctuation->NewJapanese=True; } void Hyphenate(FILE *OutFile, struct PunctuationType *Punctuation) /* Adds hyphenation between consecutive Bitmaps */ { /* No hyphenation between two odd symbols */ if (Punctuation->OldJapanese || Punctuation->NewJapanese) /* No hyphenation before some symbols */ if (!Punctuation->NewMajorEOL && !Punctuation->NewMinorEOL && !Punctuation->NewCenterDot && !Punctuation->NewClosing) /* No hyphenation after some symbols */ if (!Punctuation->OldOpening) { fprintf(OutFile,"\\hh"); if (ferror(OutFile)) exit(1); } } void Glue(FILE *OutFile, struct PunctuationType *Punctuation, int ExtraSpace) /* Adds glue between consecutive Bitmaps */ { int GlueAdded; GlueAdded=False; if (ExtraSpace) { /* Trying to add big glue */ if (Punctuation->OldMajorEOL) /* No big glue between identical symbols */ if (!Punctuation->NewMajorEOL) /* No big glue before some symbols */ if (!Punctuation->NewClosing) { GlueAdded=True; fprintf(OutFile,"\\eeee"); if (ferror(OutFile)) exit(1); } if (!GlueAdded) /* Trying to add medium glue based on old symbol */ if (Punctuation->OldMinorEOL || Punctuation->OldCenterDot || Punctuation->OldClosing) /* No medium glue before some symbols */ if (!Punctuation->NewMajorEOL && !Punctuation->NewMinorEOL && !Punctuation->NewClosing) { GlueAdded=True; fprintf(OutFile,"\\eee"); if (ferror(OutFile)) exit(1); } if (!GlueAdded) /* Trying to add medium glue based on new symbol */ if (Punctuation->NewCenterDot || Punctuation->NewOpening) /* No medium glue after some symbols */ if (!Punctuation->OldOpening) { GlueAdded=True; fprintf(OutFile,"\\eee"); if (ferror(OutFile)) exit(1); } } /* Always make sure to add some glue */ if (!GlueAdded) { /* Adding small glue */ fprintf(OutFile,"\\ee"); if (ferror(OutFile)) exit(1); } } void Convert(FILE *InFile, FILE *OutFile, struct RunTimeType *RunTime) /* Convert .JEM into .TeX by translating Bitmaps & adding hyphenation & glue */ { /* Japanese punctuation information */ struct PunctuationType Punctuation; /* Scanning information */ struct ScanningType Scanning; /* Current font number */ int FontPtr; char C0,C1,C2; /* Not reached EOF yet */ Scanning.Done=False; /* Echo in second pass */ Scanning.Echo=True; /* Nothing done yet */ Scanning.Immediate=False; Scanning.WasLetter=False; /* Tell indirectly to GetBitmap that this is the first time it is called */ Scanning.Comment=True; /* Initial japanese punctuation information */ Punctuation.NewMajorEOL=False; Punctuation.NewMinorEOL=False; Punctuation.NewOpening=False; Punctuation.NewClosing=False; Punctuation.NewCenterDot=False; Punctuation.NewJapanese=False; do { /* Set up scanning information in case a roman letter follows immediately */ Scanning.RomanMajorEOL=Punctuation.NewMajorEOL; Scanning.RomanMinorEOL=(Punctuation.NewMinorEOL || Punctuation.NewCenterDot || Punctuation.NewClosing); Scanning.RomanOpening=Punctuation.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 (!Scanning.Done) { /* Find what kind of Bitmap it is */ BitmapType(Scanning.Bitmap,&Punctuation); if (Scanning.Immediate) { /* Add hyphenation and glue between consecutive Bitmaps */ Hyphenate(OutFile,&Punctuation); Glue(OutFile,&Punctuation,RunTime->ExtraSpace); } else /* Add glue after the old Roman and before this new Bitmap */ if (RunTime->ExtraSpace) if (Punctuation.NewCenterDot || Punctuation.NewOpening) { fprintf(OutFile,"\\eee"); if (ferror(OutFile)) exit(1); } else if (Scanning.WasLetter) /* No medium glue before some symbols */ if (!Punctuation.NewMajorEOL && !Punctuation.NewMinorEOL && !Punctuation.NewClosing) { fprintf(OutFile,"\\eee"); if (ferror(OutFile)) exit(1); } /* Write the Bitmap */ C0='a'+(char)(RunTime->Size-1); FontPtr=Scanning.Bitmap / 128; C1='a'+(char)(FontPtr / 8); C2='a'+(char)(FontPtr % 8); fprintf(OutFile,"\\kk{\\k%c%c%c}{%d}",C0,C1,C2,(Scanning.Bitmap % 128)); if (ferror(OutFile)) exit(1); /* The next character may be Roman, GetBitmap will handle the glue then */ } } while (!Scanning.Done); } /*----------------------------------- Main ----------------------------------*/ main(int argc, char *argv[]) { /* Input and Output file names */ TotalNameType TotalName; FILE *InFile; FILE *OutFile; /* Run time parameters */ struct RunTimeType RunTime; /* JemTeX fonts used */ FontsType Fonts; printf("\n"); printf("Japanese to [La]TeX Conversion Program.\n"); /*To make Borland happy*/ printf("Version 2.00 Copyright F. Jalbert 1991.\n"); printf("\n"); if (ferror(stdout)) exit(1); GetParameters(&RunTime,argc,argv); printf("\n"); printf("Opening Japanese file %s",RunTime.FileName); OpenFile(&InFile,&RunTime); printf(".\n"); if (RunTime.LaTeX) printf("Creating LaTeX file %s.tex",RunTime.FileName); else printf("Creating TeX file %s.tex",RunTime.FileName); strcpy(TotalName,RunTime.FileName); strcat(TotalName,".tex"); OutFile=fopen(TotalName,"wt"); if (OutFile==NULL) exit(1); printf(".\n"); printf("\n"); if (ferror(stdout)) exit(1); printf("Scanning Japanese file for fonts"); #ifndef __TURBOC__ printf("\n"); #endif GetFont(InFile,Fonts,&RunTime); rewind(InFile); /* ferror now cleared */ printf(".\n"); if (RunTime.LaTeX) printf("Writing LaTeX header"); else printf("Writing TeX header"); #ifndef __TURBOC__ printf("\n"); #endif Header(OutFile,Fonts,RunTime.LaTeX); printf(".\n"); printf("Converting Japanese file"); #ifndef __TURBOC__ printf("\n"); #endif Convert(InFile,OutFile,&RunTime); printf(".\n"); printf("\n"); if (ferror(stdout)) exit(1); printf("Closing Japanese file %s%s",RunTime.FileName,RunTime.Extension); if (fclose(InFile)==EOF) exit(1); printf(".\n"); if (RunTime.LaTeX) printf("Closing LaTeX file %s.tex",RunTime.FileName); else printf("Closing TeX file %s.tex",RunTime.FileName); if (fclose(OutFile)==EOF) exit(1); printf(".\n"); printf("\n"); if (ferror(stdout)) exit(1); printf("Japanese to [La]TeX conversion completed.\n"); printf("\n"); if (ferror(stdout)) exit(1); return(0); }