/* Transliterated Russian to KOI-8 converter */
/* (c) Bernshtam Pavel Beer Sheva,Israel.1995 */
/* Compile gcc -O2 -o tr2koi tr2koi.c */

/* Do tr2koi example example.koi to  see  principles of conversion */

/*

A - \A
B - \B
V - \V
G - \G
D - \D
E - \E
Zh - \Z\h,\Z\H
Z - \Z
I - \I
J - \J,\Y posle soglasnoy
K - \K
L - \L
M - \M
N - \N
O - \O
P - \P
R - \R
S - \S
T - \T
U - \U
F - \F
H - \H,\X
C - \C
CH - \C\h,\C\H
SH - \S\h,\S\H,\W
CX - \C\x,\C\X
@~ - \@\~
Y - \Y (posle glasnoy)
@'-  \@\'
Eh - \E\h,\E\H
YU - \Y\u,\Y\U
YA - \Y\a,\Y\A,\Q


a - \a
b - \b
v - \v
g - \g
d - \d
e - \e
zh - \z\h,\z\H
z - \z
i - \i
j - \j,\y posle soglasnoy
k - \k
l - \l
m - \m
n - \n
o - \o
p - \p
r - \r
s - \s
t - \t
u - \u
f - \f
h - \h,\x
c - \c
ch - \c\h,\c\H
sh - \s\h,\s\H,\w
cx - \c\x,\c\X
~ - \~
y - \y (posle glasnoy)
' - \'
eh - \e\h,\e\H
yu - \y\u,\y\U
ya - \y\a,\y\A,\q



\# - pustoj simvol (dlya otmeny perevoda 2x bukv v odnu. sm. nizhe)
\\ - otmenyaet perevod sleduyucxego simvola

Text v figurnyh skobkah ne konvertiruetsya -
\{ { It's English text } } ->  { It's English text }.

Chtoby napechatat' lebuyu figurnuyu skobku upotreblyajte \\ -
\\\{ -> \{. Pravaya skobka ehtogo ne trebuet.

Bukva \y posle soglasnoy oboznachaet "y" (\r\y\b\a -> ryba ),
a posle glasnoy - "j" ({siniy} == siniy, {ZHIRNYY} == ZHIRNYY).

S pomocx'yu \# mozhno poluchit' y posle glasnoy:
\a\#\y -> a#y

Posle i glasnyh , i soglasnyh \y\a, \y\u i t.d. perevodyatsya kak ya, yu i t.d.
sootvetstvenno - {celuyutsya} -> celuyutsya.

Primery:

\s\#\h -> s#h
\c\x -> cx
\c\#\x -> c#x
\c\\\#\x -> c\#x
\\\\ -> \\
\\\' -> \'
\\\~ -> \~
\\\@\'-> \@'



*/



#include <stdio.h>
#include <string.h>

int ish(char),isx(char),isa(char),isu(char),iso(char),iss(char),isglas(char);

main (int argc,char **argv)
{
  FILE *fin, *fout;
  char simple(char);
  int c,c1,glas=0;

  switch (argc)
        {
  case  1:     /* Without arguments. Act as filter */
                  fin=stdin;fout=stdout;break;
  case  2:     /* 1 argument.Read from the file. Write to stdout. */
                  fout=stdout;
               if ((fin=fopen(argv[1],"r"))==NULL)
                 { printf("Can't open for input file %s\n",argv[1]); exit(1);}
                 break;

  case  3:   /* 2 arguments */
             if (strcmp(argv[1],"-")==0)
              /* 1st argument '-'. Read from stdin,Write to the file */
               { fin=stdin;
                   puts ("here");
                 if ((fout=fopen(argv[2],"w"))==NULL)
                 { printf("Can't open for output file %s\n",argv[2]); exit(1);}
	       break; }
          else

              if ((fin=fopen(argv[1],"r"))==NULL)
           { printf("Can't open for input file %s\n",argv[1]); exit(1);}
              if ((fout=fopen(argv[2],"w"))==NULL)
           { printf("Can't open for output file %s\n",argv[2]); exit(1);}

                                                             break;

     }

 while((c=getc(fin))!=EOF)
   {
       switch (c)

      {

          case '{'   :
	    while ((c=getc(fin))!=EOF)
	      {;if (c=='}') break; putc(c,fout); }
	    break;

          case '\\'  : putc(getc(fin),fout);break; /*Put next symbol
                                                       without translating */
          case '#'  : break;                                /* Nothing */
          case 'Q'  : putc('\361',fout);break;      /* Ya */
          case 'q'  : putc('\321',fout);break;
          case 'V'  : putc('\367',fout);break;
          case 'v'  : putc('\327',fout);break;
          case 'w'  : putc('\333',fout);break;     /* Sh */
          case 'W'  : putc('\373',fout);break;
          case 'x'  : putc('\310',fout);break;
          case 'X'  : putc('\350',fout);break;
          case '~'  : putc('\337',fout);break;    /* Small hard sign */
          case '\'' : putc('\330',fout);break;     /* Small soft sign */


          case 'z' : if (ish(c1=getc(fin))) putc('\326',fout);
                        else { ungetc(c1,fin);putc('\332',fout);} break;
          case 'Z' : if (ish(c1=getc(fin))) putc('\366',fout);
                        else { ungetc(c1,fin);putc('\372',fout);} break;

          case 'S' :    c1=getc(fin);
                          if (ish(c1)) putc('\373',fout);
                          else { ungetc(c1,fin);putc('\363',fout);} break;
           case 's' :   c1=getc(fin);
                        if (ish(c1))  putc('\333',fout);
                           else {   ungetc(c1,fin);putc('\323',fout); }break;

           case 'E' :    c1=getc(fin);
                          if (ish(c1)) putc('\374',fout);
                          else { ungetc(c1,fin);putc('\345',fout);} break;
           case 'e' :    c1=getc(fin);
                        if (ish(c1))  putc('\334',fout);
                           else {   ungetc(c1,fin);putc('\305',fout); }break;

           case 'C' :    c1=getc(fin);
                          if (ish(c1)) putc('\376',fout);
                          else
                             if (isx(c1)) putc('\375',fout);/* Shch (like'shchuka')  */
                          else { ungetc(c1,fin);putc('\343',fout);} break;
           case 'c' :    c1=getc(fin);
                        if (ish(c1))  putc('\336',fout);
                           else
                                  if (isx(c1)) putc('\335',fout);
                           else { ungetc(c1,fin);putc('\303',fout);} break;



	    case 'Y' :
	                 c1=getc(fin);
       	                 if (isa(c1)) { glas=1;putc('\361',fout);}
			       else if(isu(c1)){ glas=1; putc('\340',fout);}
                                      else if (iso(c1))  { glas=1; putc('\345',fout);}
                                           else
					     { ungetc(c1,fin);
                         if (glas) {glas=0;putc(simple('J'),fout);}
                             else
			      { glas=1;putc('\371',fout);}
					     }
	                  break;


           case 'y' :
	                 c1=getc(fin);
       	                 if (isa(c1)) { glas=1;putc('\321',fout);}
			       else if(isu(c1)){ glas=1; putc('\300',fout);}
                                      else if (iso(c1))  { glas=1; putc('\305',fout);}
                                           else
					     { ungetc(c1,fin);
                         if (glas) {glas=0;putc(simple('j'),fout);}
                             else
			      { glas=1;putc('\331',fout);}
					     }
	                  break;

             case '@' :    c1=getc(fin);
                        if (c1=='~')  putc('\377',fout);  /* Large hard sign */
                           else
                                  if (c1=='\'') putc('\370',fout);  /* Large soft sing */
                           else { ungetc(c,fin);putc('@',fout);} break;

            default:  putc(simple(c),fout); break;

     }

 if ((c!='y') && (c!='Y')) glas=(isglas(c))?1:0;

}

}
char simple(char c)
{

      if (c>='A' && c<='Z') return (c+'\341'-'A');
      else
      if (c>='a' && c<='z')  return(c+'\301'-'a');

      else return(c);
}

int ish (char c)
{
 return( (c=='h') || (c=='H'));
}
int isx (char c)
{
 return( (c=='x') || (c=='X'));
}
int isa (char c)
{
 return( (c=='a') || (c=='A'));
}
int iso (char c)
{
 return( (c=='o') || (c=='O'));
}
int isu (char c)
{
 return( (c=='u') || (c=='U'));
}
int iss (char c)
{
 return( (c=='s') || (c=='S'));
}
int isglas(char c)
{
return ( isa(c) || iso(c) || isu(c) || (c=='e')
 || (c=='E') || (c=='i') || (c=='I'));
}