拡張編集と Shift_JIS

PSDToolKit を作っていて「ダメ文字」問題と向き合うことになったので、思い出がてら記録しておく。

拡張編集は多くの箇所で MBCS 文字列を使っていて Lua スクリプトでも Shift_JIS が使われるので、例えば
A = "サシスセソ"
みたいなスクリプトはそのまま記述されると上手く動かないことが容易に予想できる。

ところが、実際にはテキストオブジェクトに
<?mes("サシスセソ")?>
と書くと上手く動き、
<?dofile("test.lua")?>
として、test.lua の中に同じ内容を書くと、こちらは動かない。

内部で何が起きているのかを知るのは簡単で、ダブルクォートの代わりに
<?mes([[サシスセソ]])?>
このようにすると、画面には
サシスセソ\
と表示される。

つまり、拡張編集では拡張編集が用意したダイアログ内に入力されたテキストに対しては独自にダメ文字対策を行っていて、その対策方法は恐らく単純に「ダメ文字を探して \ を足す」という形で行っているので、実際にエスケープする必要があるかどうかに関係なくエスケープしようとした結果、画面に「サシスセソ\」と出た。

この方法は変なことをしようとしなければ概ね上手く動くので大抵のケースでは問題にならないし、誤ってエスケープされたものも余分な \ を消せば復元できるので大きな問題にはならないはずだったが、PSDToolKit の特殊な事情により厄介な問題に発展した。

やりたかったことは、文字列をクリップボードにコピーしておいて、拡張編集のダイアログや *.lua ファイル内に貼り付けて使う、というだけの処理だった。

何が問題なのかというと、コピーした時点ではどちらに貼り付けようとしているのかがわからないので、貼り付けられた場所次第で得られる文字列が変わってしまう。
最初は「こっちからの場合は \ を消して……」みたいな場当たり的な措置でお茶を濁そうとしたのだが、置換処理が結構な回数必要になるし、気をつけて扱わないとすぐ事故る勢いだったのでこれはまずいと思ってアプローチを変えることにした。

対策は単純に「ダメ文字が出てこないようにする」というだけ。

処理の都合上、元々文字列では Unicode の範囲全てを扱える必要がありエスケープ処理を行うロジックを作っていたので、それにダメ文字用の対策も加えることによって事なきを得た。

上手く動くようになってよかったなあ。