#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HEXA_STRING "0123456789abcdef"
#ifdef WIN32
#include <io.h>
#include <ctype.h>
#define MKSTEMP mktemp
#else
#define MKSTEMP mkstemp
#endif
#define BIT(x) (1<<x)
char idx[1024], ind[1024];
int cho=-1, style_used=0;
int to_8bit(void);
int hangul_head(int);
int doublebyte(int, int);
int triplebyte(unsigned int, unsigned int, unsigned int);
int ucs(int);
void fputs_item(char *, FILE *);
main(int argc, char *argv[])
{
int i, outfile_used=0;
char prog[1024], args[1024], cmd[128], idx0[1024];
char *t, *l;
strcpy(prog, argv[0]);
#ifdef WIN32
strcpy(args, "");
strcpy(ind, "");
#else
bzero(args, 1024);
bzero(ind, 1024);
#endif
printf("This is hmakeindex, version 1.0 (makeindex wrapper for Korean support).\n");
for(i=1; i<argc; i++) {
strcat(args, " ");
t=argv[i];
strcat(args, t);
switch(*t) {
case '-':
t++;
switch(*t) {
case 'o':
outfile_used=1;
strcat(args, " ");
strcat(args, argv[++i]);
strcpy(ind, argv[i]);
if((l=strrchr(ind, '.'))&&*(l+1)=='i'&&*(l+2)=='n'&&*(l+3)=='d')
*l=0;
break;
case 'p':
strcat(args, " ");
strcat(args, argv[++i]);
break;
case 's':
strcat(args, " ");
strcat(args, argv[++i]);
style_used=1;
break;
case 't':
strcat(args, " ");
strcat(args, argv[++i]);
break;
default:
break;
}
break;
default:
if((l=strrchr(argv[i], '.'))&&*(l+1)=='i'&&*(l+2)=='d'&&*(l+3)=='x')
*l=0;
strcpy(idx, argv[i]);
strcpy(idx0, argv[i]);
strcat(idx, ".idx");
break;
}
}
i=to_8bit();
sprintf(cmd, "makeindex %s", args);
system(cmd);
if(outfile_used==0) {
strcpy(ind, idx0);
strcat(ind, ".ind");
}
hangul_head(i);
exit(0);
}
int to_8bit() {
FILE *in, *out;
char line[1024], *h1, *h2, tempfile[9];
unsigned char *l;
int x, w=0, utf_seen=0, hangul_enc=0;
in = fopen(idx, "r");
if(!in) {
printf("\tError opening index file \"%s\"!!!\n", idx);
exit(1);
}
strcpy(tempfile, "IDXXXXXXX");
MKSTEMP(tempfile);
out = fopen(tempfile, "w");
if(!out) {
printf("\tError opening temporary file \"%s\"!!!\n", tempfile);
exit(1);
}
while(fgets(line, 1024, in)) {
l=line;
while(*l) {
if(*l=='^'&&*(l+1)=='^'
&&(h1=strchr(HEXA_STRING, *(l+2)))
&&(h2=strchr(HEXA_STRING, *(l+3)))) {
if(*h1>'9') x=*h1-87;
else x=*h1-48;
x*=16;
if(*h2>'9') x+=*h2-87;
else x+=*h2-48;
fputc(x, out);
l+=4;
hangul_enc=1;
if(w<161 || x<161) utf_seen=1;
w=x;
}
else {
if(w>127 && *l>127) {
/* 이미 변환된 .idx 파일의 경우 */
hangul_enc=1;
if(w<161 || *l<161) utf_seen=1;
}
w=*l;
/* 위치 표시 문자 '@'는 '\a'으로 변환하여 makeindex로 처리한 후
나중에 제거한다. \hindexhead{#}의 "#" 처리에서 오류가 발생 */
if(*(l-1)!='"' && *l=='@') fputc('\a', out);
else fputc(*l, out);
l++;
}
}
}
fflush(NULL);
fclose(in);
fclose(out);
rename(tempfile, idx);
return(hangul_enc+utf_seen);
}
int hangul_head(encoding) {
FILE *in, *out;
char tempfile[9];
unsigned char line[1024], *l;
unsigned int cho=20, x;
strcpy(tempfile, "INDXXXXXX");
MKSTEMP(tempfile);
in=fopen(ind, "r");
out=fopen(tempfile, "w");
while(fgets(line, 1024, in)) {
l=line;
while(isspace(*l)) l++;
if(strncmp(l, "\\item", 5)==0) {
l+=5;
while(isspace(*l)) l++;
if(*l<128) {
fputs_item(line, out);
continue;
}
switch(encoding) {
case 1: /* EUC-KR */
x=doublebyte(*l, *(l+1));
break;
case 2: /* UTF-8 */
x=triplebyte(*l, *(l+1), *(l+2));
break;
default:
fprintf(stderr, "Encoding error in the ind file\n");
fputs(line, out);
break;
}
if(x!=cho && x<20) {
cho=x;
fprintf(out, "\n\\hindexhead{%d}\n", cho);
}
fputs_item(line, out);
}
else if(strncmp(l, "\\indexspace", 11)==0) {
if(cho<0 || cho>19) fputs(line, out);
}
else if(!(strncmp(l, "\\indexhead{", 11)==0&&*(l+11)>128)) {
fputs(line, out);
}
}
fflush(NULL);
fclose(in);
fclose(out);
rename(tempfile, ind);
return(1);
}
void fputs_item(char *item, FILE *fp) {
char *s;
if((s=strchr(item, '\a'))) fprintf(fp, " \\item %s", ++s);
else fputs(item, fp);
}
int doublebyte(int first, int second) {
unsigned int ksc;
if(first<0xa1) return(21);
else if(first<0xb1) return(0);
else if(first>0xc8) return(20);
ksc=(first<<8)+second;
if(ksc<0xb1ee) return(1);
else if(ksc<0xb3aa) return(2);
else if(ksc<0xb4d9) return(3);
else if(ksc<0xb5fb) return(4);
else if(ksc<0xb6f3) return(5);
else if(ksc<0xb8b6) return(6);
else if(ksc<0xb9d9) return(7);
else if(ksc<0xbafc) return(8);
else if(ksc<0xbbe7) return(9);
else if(ksc<0xbdce) return(10);
else if(ksc<0xbec6) return(11);
else if(ksc<0xc0da) return(12);
else if(ksc<0xc2a5) return(13);
else if(ksc<0xc2f7) return(14);
else if(ksc<0xc4ab) return(15);
else if(ksc<0xc5b8) return(16);
else if(ksc<0xc6c4) return(17);
else if(ksc<0xc7cf) return(18);
else if(ksc<0xc8ff) return(19);
else return(-1);
}
int triplebyte(unsigned int first, unsigned int second, unsigned int third) {
unsigned int utf;
int i;
if(first<=0x7f) utf=first;
else {
i=0;
while(first & BIT((6-i))) i++;
switch(i) {
case 1:
utf=((first - BIT(7) - BIT(6))<<6);
utf+=(second - BIT(7));
break;
case 2:
utf=((first - BIT(7) - BIT(6) - BIT(5))<<12);
utf+=((second - BIT(7))<<6);
utf+=(third - BIT(7));
break;
default:
break;
}
}
if(0xac00<=utf && utf<=0xd7a3)
return((utf-0xac00)/(21*28)+1);
else if((0x4e00<=utf && utf>=0x9fff) ||
(0xf900<=utf && utf>=0xfaff)) return(20);
else if(utf==first) return(21);
else return(0);
}