/*----------------------------------------------------------------------*/
/* File: konvCS.c		(C) 1997-2004 Miroslav Kolar		*/
static char *ver = "konvCS.c, Ver. 1.3, Oct. 25, 2004, M. Kolar";
/*----------------------------------------------------------------------*/
/* Usage:  konvCS  KOD1  KOD2  fileIN  fileOUT  [-notag]		*/
/* This program converts between 9 different encodings of the		*/
/* Czech/Slovak subset of the Central European character set (Latin 2),	*/
/* and my input format (MK); and generates output to LaTeX.		*/
/* Will also convert/correct the "META http-equiv" HTML tag.		*/
/*----------------------------------------------------------------------*/

/* Version 1.0 (konvCz): Dec. 1, 1997
   Version 1.1 (konvCz): Oct. 4, 1999
	- pridana konverze vsech vyskytu "META http-equiv" tagu HTML
	- opravena chyba pro abcIn=3 & abcOut<8
   Version 1.2: June 29, 2001
	- pridan Microsoft UNICODE
	- a samostatne se vyskytujici hacky, carky a krouzky
	- opraveno charset jmeno KOI-8_CS2
   Version 1.3: Oct. 25, 2004
	- pridan KOD2 = latexR
	- zmeneno charset jmeno UNICODE na UTF-16 (presne se jedna o
		implementaci UCS-2, fixni 2 bajty; Mozilla mu rika UTF-16LE)
	- odstraneny zbytecne pruchody programem, optimalizace
	- jen prvni vyskyt charset META tagu je konvertovan;
       		jeho konverzi lze nyni vypnout (viz -notag) => mozne zrychleni
	- v prostredi bez "carriage return" mozny standardni vstup/vystup
		(viz nize definici macro IS_1310 pro pripadne doplneni;
	       	konvCS potrebuje binarni vstup/vystup) 

   Compilation:	gcc -s -O3 konvCS.c -o konvCS
   Chcete-li v MS Windows chybova hlaseni misto na stdout posilat do
   souboru na disku se jmenem  jmeno_souboru , prelozte takto:
		gcc -s -O3 -DERRNAME=\"jmeno_souboru\" konvCS.c -o konvCS
*/

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

#define PR	(void)fprintf(outfile,
#define PC(x)	(void)fputc(x,outfile)
#define GC	fgetc(infile)

#if defined(MSDOS) || defined(__BORLANDC__) || defined(_MSC_VER) || defined(__CYGWIN__) || defined(__CYGWIN32__)
#define IS_1310
#define LINE_END "\r\n"
#ifdef ERRNAME
#define PE	(void)fprintf(errFile,
FILE	*errFile;
#else
#define PE	(void)fprintf(stdout,
#endif
#else
#define LINE_END "\n"
#define PE	(void)fprintf(stderr,
#endif

static char
*meta = "<META http-equiv=\"Content-Type\" content=\"text/html; charset=",
*charsetName[12] = {
	"US-ASCII", "windows-1250", "CP852", "ISO-8859-1", "ISO-8859-2",
	"x-kam-cs", "KOI-8_CS2", "x-mac-ce", "", "", "", "UTF-16" },
*outChrstName;

static unsigned char
BUFF[BUFSIZ], /* Optimal buffer size BUFSIZ from <stdio.h> */
abcAll[8][48] = {
	"AACDEEILLNOOORRSTUUUYZaacdeeillnooorrstuuuyz~'*",
	"聊认商团家又岳貖嵹佘輲徜栾殪礤掘篥羿鴼濟秊〈",
	"祹惙謶曊鄼忤涢逇恙爠熢傌栧撽湥厑歆箫",
	"聊切伤蚅L延衷RRST谯茌Z徜鏳殡韑l耋鲷rrstz~窗",
	"聊认商团ヒ又岳丞佘莓徜栾殪礤凋篥羿机反",
	"弾厫墜姕櫑珵泦棪殱挔剣儌垺崒あ敁仒憕'",
	"狁沅麇殡祛镯疰蝮趱觇裂媚着伤涛贤衅矣哉嗜仝",
	"鐎墤儩杲慌顓镔坩栩駟噴嫇帪捑妓棜欄掬闇鬅'" };

#define FLUSH {if(b >= p2) { *p2 = 0; if(charsetTest) convCharset(); (void)fputs(BUFF,outfile); b = p1;}}

void outMK(int), outMKforISO1(int), outLatex(int),
     (*outStr)(int), prologLatex(void), convCharset(void), noWork(char*);

FILE *infile, *outfile;

static int
	abcIn, charsetTest, abcOut,
	MAXchars; /* max # of chars to be read into BUFF; is smaller than BUFSIZ	if charset testing is done, to allow shift right if needed */

int AbcInd(char *codeName)
/*======================*/
{
 if(!strcmp(codeName,"asc")) return 0;
 if(!strcmp(codeName,"1250")) return 1;
 if(!strcmp(codeName,"852")) return 2;
 if(!strcmp(codeName,"iso1")) return 3;
 if(!strcmp(codeName,"iso2")) return 4;
 if(!strcmp(codeName,"kam")) return 5;
 if(!strcmp(codeName,"koi")) return 6;
 if(!strcmp(codeName,"mac")) return 7;
 if(!strcmp(codeName,"MK")) return 8;
 if(!strcmp(codeName,"latex")) return 10;
 if(!strcmp(codeName,"latexR")) return -10;
 if(!strcmp(codeName,"UNI")) return 11;
 PE"%s: nezname kodovani/format\n", codeName);
 exit(1);
}

void ExIt0(void)
/*============*/
{
 (void)fclose(infile);
 (void)fclose(outfile);
#if defined(IS_1310) && defined(ERRNAME)
 (void)fclose(errFile);
#endif
 exit(0);
}


main(int argc, char *argv[])
/*========================*/
{
register int ch;
int abcOutNextPass = -1,
     latexBreaks = 0; 
register unsigned char *b, *p1, *p2, *a;

#if defined(IS_1310) && defined(ERRNAME)
 errFile = fopen(ERRNAME,"w");
#endif

if(argc < 5 || !strncmp(argv[1],"-h",2)) {
 PE"\n\t\t\t\t%s\n\n", ver);
 PE"Ucel: Konverze diakritiky mezi ruznymi kodovanimi cestiny/slovenstiny\n\n");
 PE"Pouziti:  %s  KOD1  KOD2  Vstup  Vystup  [-notag]\n\n", argv[0]);
 PE"  KOD1 a KOD2 muze byt: 1250, 852, iso1, iso2, kam, koi, mac, UNI a MK\n");
 PE"  KOD2 muze byt tez: asc, latex a latexR\n\n");
 PE"    1250  ... windows-1250		852  ... CP852\n");
 PE"    iso1  ... ISO-8859-1		iso2 ... ISO-8859-2\n");
 PE"    kam   ... Kamenicti			koi  ... KOI-8_CS2\n");
 PE"    mac   ... Macintosh CE\n");
 PE"    UNI   ... Microsoft UNICODE (UCS-2, ~ UTF-16)\n");
 PE"    MK    ... sprezkovy vstupni format pouzivajici ^, \', `\n");
 PE"    asc   ... 7-bitovy ASCII bez diakritiky\n");
 PE"    latex ... Vystup je vstupem pro LaTeX\n");
 PE"    latexR .. Vystup je vstupem pro LaTeX, ktery zachovava Radky puvodniho\n\
\t      vstupniho souboru (prechod na novy radek a pocet prazdnych radku)\n");
 PE"\t(`iso1' aproximuje nektere chybejici ceske znaky: C^,D^,E^,N^,U^,c^,e^,\n");
 PE"\t n^,u^; `kam' aproximuje samostatny hacek a carku; `mac' carku)\n\n");
 PE" Vstup  a  Vystup  - jmena vstupniho a vystupniho souboru");
#ifndef IS_1310
 PE";\n	mohou byt nahrazeny '-' pro standardni vstup a/nebo vystup");
#endif
 PE"\n\n -notag  -  nepovinne, musi byt uvedeno doslovne; vypina konverzi HTML tagu\n\
	<META http-equiv=\"Content-Type\" content=\"text/html; charset=...\">\n");
 PE"  Pokud KOD1=KOD2 a -notag neni pozadovan, je jen zkontrolovan pripadny\n\
	vyskyt vyse uvedeneho META tagu v souboru\n\n");
 PE"  Konvertovano je pouze 47 znaku, zapsanych v MK formatu takto:\n\
	A'A`C^D^E'E^I'L'L^N^O'O`O^R'R^S^T^U'U^U`Y'Z^\n\
	a'a`c^d^e'e^i'l'l^n^o'o`o^r'r^s^t^u'u^u`y'z^ |^ |' \"^\n");
 PE"  Jejich prevod napr. do ISO-8859-2 prikazem `%s MK iso2 ...' da:\n\
	%s\n", argv[0], abcAll[4]);
 PE"  Nebo do windows-1250 prikazem `%s MK 1250 ...':\n\
	%s\n\n", argv[0], abcAll[1]);
 PE"Purpose: Conversion between encodings of Czech/Slovak\n\
 			http://code.mkolar.org/konvCS/cestina.html\n");
 exit(argc==1 || strncmp(argv[1],"-h",2));
}

abcIn= AbcInd(argv[1]);
if(abcIn==0) noWork("ASCII nelze zpetne konvertovat!");
if(abcIn==10 || abcIn==-10)
	noWork("Zadany vstupni format neumim zpetne konvertovat!");
abcOut= AbcInd(argv[2]);
if(abcOut==-10) { abcOut=10; latexBreaks = 1; }
if(argc>5 && !strcmp(argv[5],"-notag")) charsetTest = 0;
else charsetTest = abcOut>7&&abcOut!=11 ? 0 : 1;
if(abcIn==abcOut && (!charsetTest || abcIn==8)) noWork("Neni co delat!");
outChrstName= charsetName[abcOut];
if(charsetTest) {
	MAXchars = BUFSIZ-15;
	if(MAXchars<100) {
		PE"BUFSIZ=%d z stdio.h neni dost velky pro konverzi charset\
 META tagu\nUprav program a znovu preloz!\n",BUFSIZ);
		exit(1);
	}
} else MAXchars = BUFSIZ;
#ifndef IS_1310
if(strcmp(argv[3],"-")) {
#endif
	if((infile = fopen(argv[3],"rb"))==NULL) {
		PE"Nelze otevrit vstupni soubor: %s\n", argv[3]);
		exit(1);
	}
#ifndef IS_1310
} else infile = stdin;
#endif
if(abcOut>8 && abcIn==3 || abcIn==8 && abcOut==10 || abcIn==11 && abcOut!=4 || abcOut==11 && (abcIn!=4 || charsetTest)) {
	if((outfile = tmpfile()) == NULL) {
		PE"Nemuzu otevrit docasny soubor!\n");
		exit(1);
	}
	abcOutNextPass = abcOut;
	if(abcOut>8 || abcIn==11) abcOut = 4; /* intermediate format = iso-2 */
} else {
#ifndef IS_1310
	if(!strcmp(argv[4],"-")) outfile = stdout;
		else 
#endif
		outfile = fopen(argv[4],"wb");
}

OnceMore:
 /*
 PE"abcIn=%d abcOut=%d chrstTest=%d ltxBreaks=%d outChstNam=%s abcOutNxtP=%d\n",
	abcIn, abcOut, charsetTest, latexBreaks, outChrstName, abcOutNextPass);
 */
 // if abcIn=4 & abcOut=11	...  1st pass is only to check the META tag;
 if(abcIn == abcOut) {
   /* fgets reads till `\n' or at most MAXchars-1 chars: */
   while(fgets(BUFF,MAXchars,infile) != NULL) {
	convCharset();
	(void)fputs(BUFF,outfile);
   }
   if(abcOutNextPass==11) goto NextPass;
   ExIt0();
 }

 if(abcIn == 3 && abcOut < 8) {

   register int i;
   PE"Varovani: chybejici znaky rozsireneho ISO-8859-1 samozrejme neumim vykouzlit!\n");
   p1 = abcAll[abcIn]; p2 = p1 + 47;
   while(fgets(BUFF,MAXchars,infile) != NULL) {
	for(b = BUFF; *b != 0; b++) {
		ch = *b;
		for(a = p1; a < p2; a++) {
		 i = a - p1;
		 if(ch == *a) {
		   if(i != 7 && i != 8 && i != 21 && i != 43 &&
		    (i < 13 || i > 16) && i != 29 && i != 30 && i != 25 &&
		    (i < 35 || i > 38) && i != 43 && i != 44)
				*b = abcAll[abcOut][i];
		   break;
		 }
		}
	}
	if(charsetTest) convCharset();
	(void)fputs(BUFF,outfile);
   }

 } else if(abcIn == 8) {

   register int ch1;
   b = p1 = BUFF; p2 = BUFF + MAXchars - 1;
  BEG:
   if((ch1 = GC) != EOF) {
     while((ch = GC) != EOF) {
	if(ch == '\'') {
	  switch (ch1) {
		case '\\': *(b++) = ch; break;
		case 'A':  *(b++) = abcAll[abcOut][0]; break;
		case 'E':  *(b++) = abcAll[abcOut][4]; break;
		case 'I':  *(b++) = abcAll[abcOut][6]; break;
		case 'O':  *(b++) = abcAll[abcOut][10]; break;
		case 'U':  *(b++) = abcAll[abcOut][17]; break;
		case 'Y':  *(b++) = abcAll[abcOut][20]; break;
		case 'L':  *(b++) = abcAll[abcOut][7]; break;
		case 'R':  *(b++) = abcAll[abcOut][13]; break;
		case 'a':  *(b++) = abcAll[abcOut][22]; break;
		case 'e':  *(b++) = abcAll[abcOut][26]; break;
		case 'i':  *(b++) = abcAll[abcOut][28]; break;
		case 'o':  *(b++) = abcAll[abcOut][32]; break;
		case 'u':  *(b++) = abcAll[abcOut][39]; break;
		case 'y':  *(b++) = abcAll[abcOut][42]; break;
		case 'l':  *(b++) = abcAll[abcOut][29]; break;
		case 'r':  *(b++) = abcAll[abcOut][35]; break;
		case '|':  *(b++) = abcAll[abcOut][45]; break;
		default:   *(b++) = ch1; FLUSH
			   *(b++) = ch;
	  }
	  FLUSH
	  goto BEG;
	}
	if(ch == '^') {
	  switch (ch1) {
		case '\\': *(b++) = ch; break;
		case 'C':  *(b++) = abcAll[abcOut][2]; break;
		case 'D':  *(b++) = abcAll[abcOut][3]; break;
		case 'N':  *(b++) = abcAll[abcOut][9]; break;
		case 'R':  *(b++) = abcAll[abcOut][14]; break;
		case 'S':  *(b++) = abcAll[abcOut][15]; break;
		case 'T':  *(b++) = abcAll[abcOut][16]; break;
		case 'Z':  *(b++) = abcAll[abcOut][21]; break;
		case 'E':  *(b++) = abcAll[abcOut][5]; break;
		case 'U':  *(b++) = abcAll[abcOut][18]; break;
		case 'O':  *(b++) = abcAll[abcOut][12]; break;
		case 'c':  *(b++) = abcAll[abcOut][24]; break;
		case 'd':  *(b++) = abcAll[abcOut][25]; break;
		case 'n':  *(b++) = abcAll[abcOut][31]; break;
		case 'r':  *(b++) = abcAll[abcOut][36]; break;
		case 's':  *(b++) = abcAll[abcOut][37]; break;
		case 't':  *(b++) = abcAll[abcOut][38]; break;
		case 'z':  *(b++) = abcAll[abcOut][43]; break;
		case 'e':  *(b++) = abcAll[abcOut][27]; break;
		case 'u':  *(b++) = abcAll[abcOut][40]; break;
		case 'o':  *(b++) = abcAll[abcOut][34]; break;
		case 'L':  *(b++) = abcAll[abcOut][8]; break;
		case 'l':  *(b++) = abcAll[abcOut][30]; break;
		case '|':  *(b++) = abcAll[abcOut][44]; break;
		case '"':  *(b++) = abcAll[abcOut][46]; break;
		default:   *(b++) = ch1; FLUSH
			   *(b++) = ch;
	  }
	  FLUSH
	  goto BEG;
	}
	if(ch == '`') {
	  switch (ch1) {
		case '\\': *(b++) = ch; break;
		case 'A':  *(b++) = abcAll[abcOut][1]; break;
		case 'O':  *(b++) = abcAll[abcOut][11]; break;
		case 'U':  *(b++) = abcAll[abcOut][19]; break;
		case 'a':  *(b++) = abcAll[abcOut][23]; break;
		case 'o':  *(b++) = abcAll[abcOut][33]; break;
		case 'u':  *(b++) = abcAll[abcOut][41]; break;
		default:   *(b++) = ch1; FLUSH
			   *(b++) = ch;
	  }
	  FLUSH
	  goto BEG;
	}
	*(b++) = ch1; FLUSH
	ch1 = ch;
     }
     *(b++) = ch1;
   }
   if(b != p1) {
	*b = 0;
	if(charsetTest) convCharset();
	(void)fputs(BUFF,outfile);
   }

 } else if(abcOut == 8) {

   outStr = abcIn==3 ? outMKforISO1 :  outMK;

   p1 = abcAll[abcIn]; p2 = p1 + 47;
   while(fgets(BUFF,BUFSIZ,infile) != NULL) {
	for(b = BUFF; *b != 0; b++) {
		ch = *b;
		if(ch == 39 || ch == 94 || ch == 96) {
			PC(92); PC(ch);
		} else { 
			for(a = p1; a < p2; a++)
			   if(ch == *a) { outStr((int)(a - p1)); break; }
			if(a == p2) PC(ch);
		}
	}
   }

 //} else if(abcOut == 9) { zde bylo priPS

 } else if(abcOut == 10) {

   prologLatex();

   p1 = abcAll[abcIn]; p2 = p1 + 47;
   if(latexBreaks) {
     register int nlCnt, pos;
#ifdef IS_1310
     register int ch13flag;
     ch13flag=0;
#endif
     nlCnt=0;
     while(fgets(BUFF,BUFSIZ,infile) != NULL) {
	pos=0;
	for(b = BUFF; *b != 0; b++) {
		ch = *b;
#ifdef IS_1310
		if(ch == 13) {
			if(ch13flag) PC(13); // another 13 preceeded this one 
			else ch13flag=1;
			continue;
		}
		if(ch == 10) {
			if(nlCnt) PR"\\ \\\\\r\n");
			else PR"\r\n\r\n");
			nlCnt++;
			ch13flag=0;
		} else {
		 if(ch13flag) {PC(13); ch13flag=0;}
#else
		if(ch == '\n') {
			if(nlCnt) PR"\\ \\\\\n");
			else PR"\n\n");
			nlCnt++;
		} else {
#endif
		 nlCnt=0;
		 if(ch==32) PC('~');
		 else if(ch==9) {
			PC('~');
			while((++pos)%8) PC('~');
			pos--;
		 } else if(ch == '#' || ch == '%' || ch == '{' || ch == '}'
		    || ch == '&' || ch == '$' || ch == '_') {
			PC(92); PC(ch);
		 } else if(ch == '~' || ch == '^' || ch == '\\'
			  || ch == '<' || ch == '>' || ch == '|') {
			PR"\\verb.%c.", ch); 
		 } else { 
			for(a = p1; a < p2; a++)
			   if(ch == *a) { outLatex((int)(a - p1)); break; }
			if(a == p2) PC(ch);
		 }
		 pos++;
		}
	}
     }
   } else {
     while(fgets(BUFF,BUFSIZ,infile) != NULL) {
	for(b = BUFF; *b != 0; b++) {
		ch = *b;
		if(ch == '#' || ch == '%' || ch == '{' || ch == '}'
		   || ch == '&' || ch == '$' || ch == '_') {
			PC(92); PC(ch);
		} else if(ch == '~' || ch == '^' || ch == '\\'
			  || ch == '<' || ch == '>' || ch == '|') {
			PR"\\verb.%c.", ch); 
		} else { 
			for(a = p1; a < p2; a++)
			   if(ch == *a) { outLatex((int)(a - p1)); break; }
			if(a == p2) PC(ch);
		}
	}
     }
   }

   PR"\\end{document}%s",LINE_END);

 } else if(abcIn==11) { /* UNI to iso2 */

   register int ch1;
   b = p1 = BUFF; p2 = BUFF + MAXchars - 1;
   GC; GC; /* Discard MS Unicode indicator */
   while((ch=GC) != EOF) {
	ch1= GC;
	if(ch1==1) {
		if(ch==96) ch=169;
		else if(ch==97) ch=185;
		else if(ch==100) ch=171;
		else if(ch==101) ch=187;
		else if(ch==71) ch=210;
		else if(ch==72) ch=242;
		else if(ch==88) ch=216;
		else if(ch==89) ch=248;
		else if(ch==26) ch=204;
		else if(ch==27) ch=236;
		else if(ch==12) ch=200;
		else if(ch==13) ch=232;
		else if(ch==14) ch=207;
		else if(ch==15) ch=239;
		else if(ch==110) ch=217;
		else if(ch==111) ch=249;
		else if(ch==125) ch=174;
		else if(ch==126) ch=190;
		else if(ch==57) ch=197;
		else if(ch==58) ch=229;
		else if(ch==61) ch=165;
		else if(ch==62) ch=181;
		else if(ch==84) ch=192;
		else if(ch==85) ch=224;
	} else if(ch1==2) {
		if(ch=199) ch=183; // samotny hacek
	}
	*(b++) = ch;
	FLUSH
   }
   if(b != p1) {
	*b = 0;
	if(charsetTest) convCharset();
	(void)fputs(BUFF,outfile);
   }

 } else if(abcOut==11) { /* iso2 to UNI */

   register int ch1, i;
   p1 = abcAll[abcIn]; p2 = p1 + 47;
   PC(255); PC(254); /* Add MS Unicode indicator */
   while((ch=GC) != EOF) {
	ch1=0;
	for(a = p1; a < p2; a++) {
		i = a - p1;
		if(ch == *a) {
			if(i==2) {ch=12; ch1=1;}
			else if(i==3) {ch=14; ch1=1;}
			else if(i==5) {ch=26; ch1=1;}
			else if(i==7) {ch=57; ch1=1;}
			else if(i==8) {ch=61; ch1=1;}
			else if(i==9) {ch=71; ch1=1;}
			else if(i==13) {ch=84; ch1=1;}
			else if(i==14) {ch=88; ch1=1;}
			else if(i==15) {ch=96; ch1=1;}
			else if(i==16) {ch=100; ch1=1;}
			else if(i==18) {ch=110; ch1=1;}
			else if(i==21) {ch=125; ch1=1;}
			else if(i==24) {ch=13; ch1=1;}
			else if(i==25) {ch=15; ch1=1;}
			else if(i==27) {ch=27; ch1=1;}
			else if(i==29) {ch=58; ch1=1;}
			else if(i==30) {ch=62; ch1=1;}
			else if(i==31) {ch=72; ch1=1;}
			else if(i==35) {ch=85; ch1=1;}
			else if(i==36) {ch=89; ch1=1;}
			else if(i==37) {ch=97; ch1=1;}
			else if(i==38) {ch=101; ch1=1;}
			else if(i==40) {ch=111; ch1=1;}
			else if(i==43) {ch=126; ch1=1;}
			else if(i==44) {ch=199; ch1=2;}
			break;
		}
	}
	PC(ch); PC(ch1);
   }

 } else if(abcIn==7) {
	/* mac: nema smysl prekladat zpet apostrof jako carku */

   register int i;
   p1 = abcAll[abcIn]; p2 = p1 + 47;
   while(fgets(BUFF,MAXchars,infile) != NULL) {
	for(b = BUFF; *b != 0; b++) {
		ch = *b;
		for(a = p1; a < p2; a++) {
			i = a - p1;
			if(ch == *a) {
				if(i != 45) *b = abcAll[abcOut][i];
				break;
			}
		}
	}
	if(charsetTest) convCharset();
	(void)fputs(BUFF,outfile);
   }

 } else if(abcIn==5) {
	/* kam: nema smysl prekladat zpet ' jako carku; ~ jako hacek */

   register int i;
   p1 = abcAll[abcIn]; p2 = p1 + 47;
   while(fgets(BUFF,MAXchars,infile) != NULL) {
	for(b = BUFF; *b != 0; b++) {
		ch = *b;
		for(a = p1; a < p2; a++) {
			i = a - p1;
			if(ch == *a) {
				if(i != 44 && i != 45) *b = abcAll[abcOut][i];
				break;
			}
		}
	}
	if(charsetTest) convCharset();
	(void)fputs(BUFF,outfile);
   }

 } else { /* abcIn=1,2,4,6; abcOut=0,1,...,7 */

   p1 = abcAll[abcIn]; p2 = p1 + 47;
   while(fgets(BUFF,MAXchars,infile) != NULL) {
	for(b = BUFF; *b != 0; b++) {
		ch = *b;
		for(a = p1; a < p2; a++)
			if(ch == *a) { *b = abcAll[abcOut][a-p1]; break; }
	}
	if(charsetTest) convCharset();
	(void)fputs(BUFF,outfile);
   }
 }

 if(abcOutNextPass < 0) ExIt0();

NextPass:
 fclose(infile);
 rewind(outfile);
 infile = outfile;
#ifndef IS_1310
 if(!strcmp(argv[4],"-")) outfile = stdout;
 else 
#endif
 outfile = fopen(argv[4],"wb");
 abcIn = abcOut;
 abcOut = abcOutNextPass;
 abcOutNextPass = -2;
 goto OnceMore;

}


void outMK(int i)
/*=============*/
{
 if(i==44) {if(abcIn==5)PC(126);else{PC(124);PC(94);} return;}
 if(i==45) {if(abcIn!=5&&abcIn!=7)PC(124);PC(39);return;}
 if(i==46) {PC(34);PC(94);return;}
 PC(abcAll[0][i]);
 switch (i) {
	case 0: case 4: case 6: case 7: case 10: case 13:
	case 17: case 20: case 22: case 26: case 28: case 29:
	case 32: case 35: case 39: case 42: 
		PC(39); break;	/*  '  */
	case 1: case 11: case 19: case 23: case 33: case 41:
		PC(96); break;	/*  `  */
	default:
		PC(94); 	/*  ^  */
 }
}


void outMKforISO1(int i)
/*====================*/
{
 if(i==45) {PC(124);PC(39);return;}
 if(i==46) {PC(34);PC(94);return;}
 PC(abcAll[0][i]);
 switch (i) {
	case 7: case 8: case 13: case 14: case 15: case 16:
	case 21: case 25: case 29: case 30: case 35: case 36:
	case 37: case 38: case 43:
		break; /* neurcitelne znaky z rozsireneho ISO-1 */ 
	case 0: case 4: case 6: case 10: case 17: case 20:
	case 22: case 26: case 28: case 32: case 39: case 42: 
		PC(39); break;	/*  '  */
	case 1: case 11: case 19: case 23: case 33: case 41:
		PC(96); break;	/*  `  */
	default:
		PC(94); 	/*  ^  */
 }
}


void outLatex(int i)
/*================*/
{
 switch (i) {
	case 25:
		PR"{\\dd}"); return;
	case 38:
		PR"{\\TT}"); return;
	case 30:
		PR"{\\ll}"); return;
	case 8:
		PR"{\\LL}"); return;
	case 28:
		PR"{\\ii}"); return;
	case 18:
		PR"{\\UU}"); return;
	case 40:
		PR"{\\uu}"); return;
	case 44:
		PR"\\v{ }"); return;
	case 45:
		PR"\\'{ }"); return;
	case 46:
		PR"\\r{ }"); return;
	case 0: case 4: case 6: case 7: case 10: case 13:
	case 17: case 20: case 22: case 26: case 29:
	case 32: case 35: case 39: case 42: 
		PC(92); PC(39); break;	/*  '  */
	case 1: case 11: case 19: case 23: case 33: case 41:
		PC(92); PC(34); break;  /*  "  */
	case 12: case 34:
		PC(92); PC(94); break;  /*  ^  */
	default:
		PC(92); PC('v'); PC(32); /* hacek */
 }
 PC(abcAll[0][i]);
}


void prologLatex(void)
/*==================*/
{
 PR"\\documentstyle{report}%s",LINE_END);
 PR"%%-----------------------%s",LINE_END);
 PR"%%%% for LTR format:%s",LINE_END);
 PR"\\oddsidemargin 0.45cm%s",LINE_END);
 PR"\\evensidemargin 0.45cm%s",LINE_END);
 PR"\\textheight 20.0cm%s",LINE_END);
 PR"\\topmargin 0.3cm%s",LINE_END);
 PR"%%-----------------------%s",LINE_END);
 PR"%%%% for A4 format:%s",LINE_END);
 PR"%%\\oddsidemargin 0.0cm%s",LINE_END);
 PR"%%\\evensidemargin 0.0cm%s",LINE_END);
 PR"%%\\textheight 22.0cm%s",LINE_END);
 PR"%%\\topmargin -0.4cm%s",LINE_END);
 PR"%%-----------------------%s",LINE_END);
 PR"\\textwidth 15.9cm%s",LINE_END);
 PR"\\renewcommand{\\baselinestretch}{1.2}%s",LINE_END);
 PR"%%------------- t', d', l', L', u^o, U^o, i'%s",LINE_END);
 PR"\\def\\TT{\\hbox{t\\hspace{-.19em}\\char'047\\hspace{-.02em}}}%s",LINE_END);
 PR"\\def\\dd{\\hbox{d\\hspace{-.165em}\\char'047\\hspace{-.02em}}}%s",LINE_END);
 PR"\\newcommand{\\uu}{\\accent'27u}%s",LINE_END);
 PR"\\newcommand{\\UU}{\\accent'27U}%s",LINE_END);
 PR"\\newcommand{\\ii}{\\'\\i}%s",LINE_END);
 PR"\\def\\LL{\\hbox{L\\hspace{-.30em}\\char'047\\hspace{.02em}}}%s",LINE_END);
 PR"\\def\\ll{\\hbox{l\\hspace{-.13em}\\char'047\\hspace{-.03em}}}%s",LINE_END);
 PR"\\raggedright%s\\begin{document}%s",LINE_END,LINE_END);
}


char *matchStrHeadUpp(char *s1, char *s2)
/*=====================================*/
/* if *s2 matches the head of *s1 converted to iupper case,
   returns pointer to the character following that match in s1;
   otherwise returns NULL pointer.
   (Can be successful only for *s2 all upper case)	 */
{
 register int i,l;

 l = strlen(s2);
 for(i=0; i<l; i++,s1++) if(toupper(*s1) != s2[i]) break;
 if(i == l) return s1;
 else return NULL;
}


#define SKIPWH	  while(isspace(*p)) p++;
#define IFSTR(x)  SKIPWH if((p3=matchStrHeadUpp(p,x)) == NULL) continue; p=p3;
#define IFCHR(x)  SKIPWH if(*(p++) != x) continue;

void convCharset(void)
/*==================*/
{
register char *p1, *p2, *p3, *p;
register int shift;
p=BUFF;
while((p=strchr(p,'<')) != NULL) {
 p1= p; /* p1 points to '<' */
 p++;
 IFSTR("META")
 IFSTR("HTTP-EQUIV")
 IFCHR('=')
 IFCHR('"')
 IFSTR("CONTENT-TYPE")
 IFCHR('"')
 IFSTR("CONTENT")
 IFCHR('=')
 IFCHR('"')
 IFSTR("TEXT/HTML")
 IFCHR(';')
 IFSTR("CHARSET")
 IFCHR('=')
 while(*(p++) != '"') if(*p == '\0') return;
 while(*p != '>') if(*(++p) == '\0') return;
 p2= p; /* p2 points to '>' */
 p++; SKIPWH
 p3= p; /* points to 1st nowhite space after '>', or to the terminal '\0' */
 shift= (p1 - p2) + 61 + strlen(outChrstName);
 PE"Retezec:\n  ");
 for(p=p1; p<=p2; p++) PE"%c", *p);
 if(*p3 != '\0') {
	if(shift) {
		p3= (char*)(BUFF + strlen(BUFF));
		if(shift<0) {
			for(p=p2; p<=p3; p++) *(p+shift) = *p;
			*(++p) = '\0';
		} else if(shift>0) {
			*(p3+shift+1) = '\0';
			for(p=p3; p>=p2; p--) *(p+shift) = *p;
		}
		p2 += shift;
	}
 } else {
	p2 += shift;
#ifdef IS_1310
	*(p2+3) = '\0';
	*(p2+2) = '\n';
	*(p2+1) = '\r';
#else
	*(p2+2) = '\0';
	*(p2+1) = '\n';
#endif
 }
 p3=p1;
 for(p=p1; p<p1+60; p++) *p = *(meta+(p-p1));
 p1= p;
 *p2 = '>';
 *(--p2) = '"';
 for( ; p<p2; p++) *p = *(outChrstName+(p-p1));
 PE"\nnahrazen retezcem:\n  ");
 p2++;
 for(p=p3; p<=p2; p++) PE"%c", *p);
 PE"\n");
 charsetTest=0;
 break;
}
}


void noWork(char *mess)
/*===================*/
{
 PE" %s\n Nevygenerovan zadny vystup.\n", mess);
 exit(1);
}

