/* -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);
}