ソースコードは troncode.trans.txt です。
ネタを使いまわしした ruby 1.9 でオレオレ文字コードを使う法 も参考になるかもしれません。
岸本 誠
BTRON Club 会員発表資料
この問題には踏み込まない(余談だが現在策定中の Ruby の標準仕様では「手続き」という概念が現れるがその定義はしていない)
例にあげた EUC に「日本語」が付いてないところに注意。
ruby 1.9 ではエンコーディングと呼んでいる。文献によっては [塩崎2003]「コードセット」と呼んでいる。(Unicode では文字符号化方式との区別がないなど混乱がある)
まとめ
@1to100pen 氏による超漢字版もある(1.6ですが)
( http://hpcgi2.nifty.com/1to100pen/wiki/wiki.cgi?p=Btron )
バージョン 1.9 では eval が VM モデルに一新され、また、これまで、基本的にバイト列でしかなかった文字列オブジェクトが CSI 方式で多言語に対応した。
M17n (Multilingualization) = 多言語化。国際化 (Internationalization, I18n) の 部分集合。この <文字><文字数><文字> という略語法は DEC 発、というトリビアがある。
参考資料
文字クラス、も検討されたが、どうせバイト列を持たなきゃならないので、だったら文字列でよい、ということになった。(参. CHISE プロジェクト)
Encoding.default_internal を設定すると、ファイルから読み込んでデフォルトでこのエンコードに変換する、という設定ができる。
本来はアプリケーションのプログラマが考慮のうえ設定するはずのものだが、Ruby on Rails は require(ロード)するとこれを勝手に UTF-8 に設定してしまう!
(参考 http://route477.net/d/?date=20110119 )
エンコーディングの追加については「サポートの要望を出すのが原則」となっている。しかし、しかるべき関数を呼び出す拡張ライブラリを作れば登録できてしまう。
以下のようなスクリプトが動く。
require "troncode" open("sample.tad", "rb:TADTextBE") {|file| s = file.read }
構造体
static OnigEncodingType stateless_TADTextBE = { &stateless_TADTextBE_mbc_enc_len, "stateless-TADTextBE", /* name */ 4, /* max byte length */ 4, /* min byte length */ &stateless_TADTextBE_is_mbc_newline, &stateless_TADTextBE_mbc_to_code, &stateless_TADTextBE_code_to_mbclen, &stateless_TADTextBE_code_to_mbc, &stateless_TADTextBE_mbc_case_fold, &stateless_TADTextBE_apply_all_case_fold, &stateless_TADTextBE_get_case_fold_codes_by_str, &stateless_TADTextBE_property_name_to_ctype, &stateless_TADTextBE_is_code_ctype, &stateless_TADTextBE_get_ctype_code_range, &stateless_TADTextBE_left_adjust_char_head, &stateless_TADTextBE_is_allowed_reverse_match };
登録
rb_enc_register("stateless-TADTextBE", &stateless_TADTextBE);
以下、通常の TRONコードから、ステートレスTRONコードに変換するトランスコードを作るプログラム(抜粋)
<% map = { "00{00-20}" => :func_so, # Control "{21-7e}{21-7e}" => :func_so, # A Zone "{80-fd}{21-7e}" => :func_so, # B Zone "{21-7e}{80-fd}" => :func_so, # C Zone "{80-fd}{80-fd}" => :func_so, # D Zone "fe{21-7e,80-fd}" => :func_so, # Script/Language Change "fefe" => :func_si, # Script/Language Escape } transcode_generate_node(ActionMap.parse(map), "TADTextBE_decoder") map = { "{00,fe}{21-7e,80-fd}" => :func_so, # Script/Language Change } transcode_generate_node(ActionMap.parse(map), "TADTextBE_decoder_lang_escape") %> <%= transcode_generated_code %> static const rb_transcoder rb_TADTextBE_decoder = { "TADTextBE", "stateless-TADTextBE", TADTextBE_decoder, TRANSCODE_TABLE_INFO, 2, /* input_unit_length */ 4, /* max_input */ 4, /* max_output */ incompat_converter, /* asciicompat_type */ 2, tadtext_init, tadtext_init, /* state_size, state_init, state_fini */ NULL, &fun_si_TADTextBE_decoder, NULL, &fun_so_TADTextBE_decoder };
構造体 rb_transcoder は今のところソースツリーの中にしかない(インストールされない)ヘッダファイルの中にあるので、コンパイルするにはソースツリーからコピーする必要がある。テンプレートから C コードを生成する ruby スクリプトもソースツリー中にある。
現在のところ、意図的に、トランスコーダーは変換元と変換先の少なくとも片方が ASCII コンパチブルとされている(前出の TRONコードのトランスコーダーはそうなっていないものを無理矢理作っている)。内部的に 2 段階の変換になるエンコーディング変換は透過的にできるので、asciicompat-TRON と、fixed-TRON の 2 種類の内部エンコーディングを作ったうえでまとめて変換する、ということは問題なくできる(はずである)。