/* -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 <stdio.h>
#include <string.h>
#include <ctype.h>
#ifdef __TURBOC__
#include <process.h>
#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 ; ParamIndex<argc ; ParamIndex++) {
   ParamLength=strlen(argv[ParamIndex]);
   if (ParamLength>ParamMax) {
     /* 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 ; Index<ParamLength ; Index++)
       Param[Index]=toupper(Param[Index]);
     /* Scan known keywords */
     if ( (!strcmp(Param,Space1)) || (!strcmp(Param,Space2)) ||
          (!strcmp(Param,Space3)) ) RunTime->ExtraSpace=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 ; Index<strlen(CommentLine) ; Index++)
   CommentLine[Index]=toupper(CommentLine[Index]);
 /* Add space at the line end to characterize premature termination */
 /* Add sentinel at the line end to stop forthcoming loops */
 strcat(CommentLine," %");
 /* Delete leading blanks */
 if (CommentLine[0]==' ')
   do Delete(CommentLine,1);
   while (CommentLine[0]==' ');
 /* Look for run-time flag at the start of line */
 if ( !strncmp(RunFlag1,CommentLine,strlen(RunFlag1)) ||
      !strncmp(RunFlag2,CommentLine,strlen(RunFlag1)) ||
      !strncmp(RunFlag3,CommentLine,strlen(RunFlag1)) ) {
   /* Remove run-time flag */
   Delete(CommentLine,strlen(RunFlag1));
   /* Scan until sentinel reached */
   do {
     /* Delete leading blanks (inefficient) */
     if (CommentLine[0]==' ')
       do Delete(CommentLine,1);
       while (CommentLine[0]==' ');
     if ((CommentLine[0]==Flag1) || (CommentLine[0]==Flag2)) {
       /* Valid run-time parameter flag */
       /* Delete 1 char at the 1st position which is flag */
       Delete(CommentLine,1);
       /* Scan in decreasing length order */
       if (!strncmp(Space1,CommentLine,strlen(Space1)))
         { Delete(CommentLine,strlen(Space1)); RunTime->ExtraSpace=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'<Data2) && (Data2<(unsigned char)'\xFF'))
       Scanning->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'<Scanning->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);
}