奥村先生がptexでマジックコメント使えないかなぁとか言っていたのを受けて遊んでみた.(あくまで遊びで,あればいいと思っているわけじゃない.)
--- texk_orig/ptexenc/ptexenc.c 2015-10-25 10:16:06.000000000 +0100 +++ texk/ptexenc/ptexenc.c 2016-01-24 16:53:00.166659600 +0100 @@ -550,7 +550,7 @@ static struct unget_st { int size; - int buff[4]; + int buff[100]; } ungetbuff[NOFILE]; static int getc4(FILE *fp) @@ -607,7 +607,7 @@ { struct unget_st *p = &ungetbuff[fileno(fp)]; - if (p->size >= 4) return EOF; + if (p->size >= 100) return EOF; return p->buff[p->size++] = c; } @@ -752,6 +752,35 @@ return true; } +#define MAGICK_LEN 10 +static int read_magick_comment(FILE *fp) +{ + int magick[MAGICK_LEN] = {'%',' ','c','o','d','i','n','g',':',' '}; + char c[100]; + int i; + int enc; + for (i=0; i<MAGICK_LEN; i++) { + c[i] = getc4(fp); + if (c[i] != magick[i]) { + do { ungetc4(c[i], fp); } while (--i>=0); + return ENC_UNKNOWN; + } + } + for (i=MAGICK_LEN; i<100; i++) { + c[i] = getc4(fp); + if (c[i] == '\r' || c[i] == '\n' || c[i] == 0) { + break; + } + } + if (c[i] != 0) ungetc4(c[i], fp); + c[i] = '\0'; + --i; + enc = string_to_enc(c + MAGICK_LEN); + do { ungetc4(c[i], fp); } while (--i>=0); + if (enc > 0) return enc; + else return ENC_UNKNOWN; +} + static int infile_enc[NOFILE]; /* ENC_UNKNOWN (=0): not determined other: determined */ @@ -766,7 +795,9 @@ if (infile_enc[fd] == ENC_UNKNOWN) { /* just after opened */ ungetbuff[fd].size = 0; if (isUTF8Nstream(fp)) infile_enc[fd] = ENC_UTF8; - else infile_enc[fd] = get_file_enc(); + else infile_enc[fd] = read_magick_comment(fp); + + if (infile_enc[fd] == ENC_UNKNOWN) infile_enc[fd] = get_file_enc(); } buffer = buff; first = last = pos;
ちなみに TeXShop や TeXworks などの統合環境は,ファイル冒頭に
返信削除% !TEX TS-program = xelatex
% !TEX encoding = UTF-8 Unicode
と書いて保存すると,次回以降そのファイルを開いたときに自動的に文字コードとコンパイルエンジン(緑の三角ボタンの横)を切り替える仕組みになっています。仮にやるとしてもこれと兼ね合いが難しそうだなあと思っていました。
そういうのを見ると,どこにあるかにこだわらない設計にしたYaTeXの%#はうまいなと思えますね.
返信削除まぁ\XeTeXinputencodingのようにコントロールシークエンスの方が良いのかもしれません.そもそもソース内で文字コードを指定するというのがよいのかという方が疑問ですが.