・第14回 エンバカデロ・デベロッパーキャンプ
本日開催ですね。やっぱりコレですよね(何が?)。それはともかく筑木さん、がんばって。
・RAD STUDIO の H2 ヘルプ (HxS) から CHM 形式のヘルプを作る (序文)
DocWiki が "あんな状態" で、RAD STUDIO 2010 のヘルプが (ゲフンゲフン) な状態なため、H2 ヘルプ から CHM を作ってみる事にしました。
ご存知ない方も多いかもしれませんが、実は日本語版の CHM は存在しています。
RAD Studio 2009 (Help Update 1 相当)
・RAD STUDIO の H2 ヘルプ (HxS) から CHM 形式のヘルプを作る (CHM の罠)
CHM 形式のヘルプは HTML から作られますが、実は UTF-8 が使えません。日本語版 Windows だと、Shift-JIS でコンテンツを作る必要があります。<meta> タグの文字コード指定は効くのは効くのですが、インデックスや目次、検索等にはデフォルト ANSI コードページが使われます...これで文字化けしてしまうのです。
・RAD STUDIO の H2 ヘルプ (HxS) から CHM 形式のヘルプを作る (Rad Studio 2007 の CHM を作る)
RAD Studio 2007 の CHM を作るのは比較的簡単です。
・RAD STUDIO の H2 ヘルプ (HxS) から CHM 形式のヘルプを作る (Rad Studio 2009 の CHM を作る)
前述の CHM が使い物にならないので、H2 ヘルプを CHM に変換しなくてはなりません。
・RAD STUDIO の H2 ヘルプ (HxS) から CHM 形式のヘルプを作る (Tips)
使い物になるヘルプを作るにはちょっとした手間が必要です。
・RAD STUDIO の H2 ヘルプ (HxS) から CHM 形式のヘルプを作る (まとめ)
こうして得られた CHM ヘルプですが、ヘルプビューワが ANSI デフォルトコードページに依存するという仕様のため、日本語版以外の Windows やロケールを変更していると正しく日本語で表示されない事になります。H2 ヘルプの優位性はそこにあるのですが、日本人が日本語環境でしか使わないのであれば、CHM 化したヘルプを使うのもアリでしょう。
手元には、2007 / 2009 の CHM ファイル群がありますが、諸事情により公開する事ができません。「CHM がどうしても欲しい」という方がいらっしゃいましたら、公式フォーラム に意見を頂ければ幸いです。
・RAD Studio 2010 スタッフ
・Unicode SynEdit
2009/09/14 に更新されていた。Unicode 版 SynEdit で、IBConsole のエディタ部にも使われている。SynHighlighterJava.pas に 0x80 以降の ANSI 文字が使われているのは直っておらず、DH山本さんの記事 を参考に修正するしかないと思われる。SynEdit.inc は変更になっているので、Delphi 2010 にインストールする事が可能だ。
サロゲートペアが含まれるとキャレットの移動がおかしいが、それ以外では普通に使えるエディタコンポーネントだ...矩形選択なんかも普通にできる。
・MECSUtils 1.30
リリース。山本隆さんのブログの "Windows 2000でWideCharToMultiByte関数を使うと、ISO-2022-JPのバイト数を間違う" の件です(フォーラムにも同様の投稿があります)。それと、"全角チルダ / 波ダッシュ問題" をどうにかするための MecsMappingFixJA() を追加してあります。
・MECSUtils 1.35
リリース。この件では、山本隆さんに大変お世話になった。この場をお借りしてお礼を申し上げたい。
さてさて。一体どういう事かと言うと、よくある "全角チルダ/波ダッシュ問題" なのだが、類似する問題を洗い出していたらイロイロとマズい点があったという事。
"全角チルダ/波ダッシュ問題" は、"どの環境でファイルが作られたか?" によって状況が異なる。JIS X 0208 <-> Unicode へのマッピングが双方向に 1:多 であったり、多:1 だったりするので、環境によってマッピングされる文字が異なるという現象が起きる事となる。同じ文字集合を利用している Shift-JIS / JIS-Code / EUC-JP なのだが、Windows の Shift-JIS (CP932) は、他の文字コードとは違うマッピングの挙動を示す。
ぶっちゃけ Windows だの Unix だの Linux だの Mac だのでおのおの JIS X 0208 <-> Unicode のマッピング方法が異なるという事だ。
よって、Unicode から Shift-JIS へエクスポートする場合には、MecsMappingFix_UnicodeToCP932() を使うべきなのか、MecsMappingFix_UnicodeToJISX0208() を使うべきなのかは 環境に依存する という事になる。逆説的に言えば、Unicode -> Ansi 変換ルーチンに前もって "全角チルダ/波ダッシュ問題" の対処法を組み込んでしまうのは危険だという事になる。
・MacOSX との非互換
MECSUtils に MacOSX 用のマッピング関数を作ろうと思ったがやめている...根本的な解決方法がないように思えたからだ。
MacOSX で作成された Unicode のテキストファイルを Windows に持ってくると、\記号 (U+005C: REVERSE SOLIDUS) が ¥記号 (U+00A5: YEN SIGN) になっている。Windows で Shift-JIS の \記号 (0x5C) を Unicode に変換すると U+005C になる。このテキストファイルを MacOSX に持っていって Shift-JIS に変換すると、U+005C は、0x80 になってしまう...つまり、Windows のソースコードを Unicode で保存し、MacOSX でShift-JIS に変換すると "パスデリミタ全滅" という事になる。
また、MacOSX の Shift-JIS には、© (0xFD)、™ (0xFE) なんて文字があるが、Windows の CP932 にはそんな文字はないため、MacOSX で作られた Shift-JIS ファイルを Windows で Unicode に変換しようとしても正しく変換できない。加えて言えば、Unicode で © (U+00A9)、™ (U+2122) を記述したファイルを Windows で Shift-JIS に変換して MacOSX に持って行っても、当然ながら © (0xFD)、™ (0xFE) にはならない。
さて前置きが長くなったが、この問題を解決するには、"MacOSX の Shift-JIS を Windows 上で Unicode と相互変換できればいい" という事が解る。
|
|
上記コードのように、コードページ 10001 (x-mac-japanese) を使えばこの問題は回避できる (でも、MacOSX の Jis-Code とかはどうなっているのだろうね?)。
Windows で作られた Unicode ファイル を MacOSX に持っていく時には、MecsMappingFix_UnicodeToJISX0208() をやった上で \記号 (U+005C: REVERSE SOLIDUS) を ¥記号 (U+00A5: YEN SIGN) に置換したものを用意すると親切なのかもしれない。こうしてできた Unicode ファイルは MacOSX 上で Shift-JIS に変換しても文字化けを起こさない。
MECSUtils で MacOSX 用の関数を用意しなかったのは、\記号 (U+005C: REVERSE SOLIDUS) を ¥記号 (U+00A5: YEN SIGN) に置換すべき時とそうでない時の区別がつかないからだ (パスデリミタを表したいのか、円記号を表したいのか判断できない)。
Windows で作られた Unicode ファイル を MacOSX で Unicode のまま利用する分には殆ど問題は起きないと思われる (逆もしかり)。Windows であらかじめ x-mac-japanese な Shift-JIS ファイルを用意するのであれば、やはり MECSUtils には、再マッピング関数不要...という事になる。"MacOSX 上で Shift-JIS に変換される事を前提で Unicode ファイルを渡す" 事なんて滅多にないだろうし。
・MECSUtils
1.30~1.36 での変更点を書いていなかったのでちょっと追記。
|
Windows 2000 で WideCharToMultibyte がバッファ容量計算をミスしてしまう件は、MECSUtils だと UTF16ToAnsi() がこの影響を受ける。山本隆さんより
|
という意見を頂いていた。元々この部分は、
|
と漠然とした計算をしていたのだけれど、突き詰めて考えてみると、
|
こういう事になる。
ただしこのままだと文字列が長くなるにつれ、ワーストケースで確保しなくてはならないバッファ量よりもさらに 1割程度多くバッファを確保してしまう。文字数が3文字を超えた場合のワーストケースは、 "全角文字…半角文字…全角文字…の繰り返しで、最後が全角文字で終わる場合" なのだが、
|
が、ワーストケースに於ける "最適なバッファ確保量" となるため、
|
現在ではこのようなロジックで落ち着いている。文字数が3文字を超えた場合のワーストケースは "文字列が全角半角の繰り返しで文字数は奇数となる" ため、単純に文字数を 2 で割ってやれば半角文字の数を導き出す事ができる。
|
本当はこうなのだけれども、厳密に全角文字の数を算出するには一旦 AnsiString への変換等が発生するため、本末転倒な事になってしまう。EAW で調べるのはちょっと危険そうだし。
・念のために...
Windows 2000 に於けるバッファの計算ミスの件は QC を入れておいた。
|
TEncoding とかがモロに影響を受けるので、「Windows のバグではあるけれど、RTL側で修正を入れるべきだ」と思われる方は是非 Vote を。日本人以外はあまり Vote してくれないと思うので、一応。
・ISO-2022 系のバッファサイズ計算
ISO-2022-CN はエスケープシーケンスが4バイトで全角->全角でもエスケープする事があるってか (資料)。うーん、WideString のサイズからバッファサイズを求めようとすると、
|
程度は必要な気がするなぁ...。ま、現実的に使われている ISO-2022 は ISO-2022-JP 及びその亜種だけ (多分) だからどうでもいいって言えばどうでもいいけどね。
・CP50220 / CP50221 / CP50222 の違い
以下の表のようになる
CodePage | エスケープ | 半角カナ |
50220 | 全角文字や半角文字に変化した場合に3バイトのエスケープが発生する | 全角文字に変換される (半角カナは存在しない) |
50221 | 全角文字や半角文字、半角カナに変化した場合に3バイトのエスケープが発生する |
エスケープシーケンスでエスケープされる |
50222 | 全角文字や半角文字に変化した場合に3バイトのエスケープが発生する | <SI>/<SO> でエスケープされる |
最後の文字が ASCII 以外の文字の場合には ASCII へのエスケープが末尾に必要となる。
・Delphi の Tips
ちょっと増えました。
BACK | 古いのを読む | 新しいのを読む |