#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); }