Microsoft Visual Studio International Feature Pack 2.0: Yomigana Frameworkを使う 2

前回に引き続き、Microsoft Visual Studio International Feature Pack 2.0に含まれているYomigana Frameworkの機能を紹介します。

SimpleRubyコントロールを使って、ASP.NETでルビ付き文字を表示する

前回は、StringAnnotationsクラスを使ってルビの振られた文字列を作成する方法を紹介しました。その「HTML上のルビを振る」でちょっと紹介した、SimpleRubyコントロールについて説明します。

Yomigana Frameworkに用意されているSimpleRubyコントロールを使うと、ASP.NET Webアプリケーションでルビの振られた文字を表示することが出来ます。具体的に言うと、SimpleRubyコントロールは、ルビ表示制御文字を用いたユニコード上のルビを、Ruby要素を用いたHTML上のルビに変換します。

SimpleRubyコントロールを使うには、YomiganaFramework.dllとSimpleRuby.dllを参照設定に追加する必要があります。

もしSimpleRubyコントロールがツールボックスに表示されていないならば、以下の方法で表示させることができます。

  1. ツールボックスの「全般」タブを右クリックしてメニューを出し、「アイテムの選択」を選択します。(「全般」タブ以外のタブに登録したいときは、そのタブで右クリックします。)
  2. 「ツールボックスアイテムの選択」ダイアログの「.NET Framework コンポーネント」タブで「参照」ボタンをクリックし、「YomiganaFramework.dll」を選択します。
  3. 「.NET Framework コンポーネント」のリストに「YomiganaTextBox」が追加されており、その左側のチェックボックスにチェックが入っていることを確認して、OKボタンをクリックします。

Visual Studioのデザイン画面でSimpleRubyコントロールをWebページに配置し、名前を「SimpleRuby1」にしたとします。このSimpleRuby1に「笑(わら)う門(かど)には福(ふく)来(きた)る」というルビが振られた文字列を表示させてみましょう。

  1. デザイン画面でSimpleRuby1を選択し、「プロパティウィンドウ」のTextプロパティに「笑う門には福来る」と入力します。
    simpleruby1
  2. Textプロパティの右側にある「...」ボタンをクリックします。すると、「読み仮名エディタ」が表示されます。
    simpleruby2
  3. ルビを振る区切りを決めます。デフォルトでは「福」と「来」が繋がってしまっていますので、「福」と「来」の間をクリックして区切りを入れます。なお区切りを削除するには、区切り線をドラッグして、枠の外にドロップします。
    simpleruby3
  4. ルビを振ります。右上にある「オートフィル」ボタンをクリックすると、漢字の上に読み仮名が自動的に入力されます。
    simpleruby4
  5. オートフィルでは「ふく」以外の読み仮名がすべて間違えていますので、正しい読み仮名を自分で入力します。ルビを振りたい箇所の上をクリックすると、入力できるようになります。ルビはひらがなでなくてもOKです。正しく入力し終えたら、OKボタンをクリックします。
    simpleruby5
  6. これで完成です。SimpleRuby1のTextプロパティが「\uFFF9笑\uFFFAわらう\uFFFBう\uFFF9門\uFFFAかど\uFFFBには\uFFF9福\uFFFAふく\uFFFB\uFFF9来\uFFFAきた\uFFFBる」になります。また、デザイン画面でSimpleRuby1に「笑(わら)う門(かど)には福(ふく)来(きた)る」と表示されます。
    simpleruby6
    SimpleRuby1のソースは、以下のようになります。
    <cc1:SimpleRuby ID="SimpleRuby1" runat="server" 
        Text="\uFFF9笑\uFFFAわらう\uFFFBう\uFFF9門\uFFFAかど\uFFFBには\uFFF9福\uFFFAふく\uFFFB\uFFF9来\uFFFAきた\uFFFBる">
    </cc1:SimpleRuby>
    

これを実行した時に生成されるHTMLは、以下のようになります。

<span id="SimpleRuby1"><ruby ><rb>笑</rb><rp >(</rp><rt >わら</rt><rp >)</rp></ruby><ruby ><rb>う</rb><rt></rt></ruby><ruby ><rb>門</rb><rp >(</rp><rt >かど</rt><rp >)</rp></ruby><ruby ><rb>には</rb><rt></rt></ruby><ruby ><rb>福</rb><rp >(</rp><rt >ふく</rt><rp >)</rp></ruby><ruby ><rb>来</rb><rp >(</rp><rt >きた</rt><rp >)</rp></ruby><ruby ><rb>る</rb><rt></rt></ruby></span>

これをruby要素に対応しているWebブラウザで表示すると、次の画像のようにルビが振られます。

simpleruby7

ruby要素に対応していないWebブラウザで表示すると、「笑(わら)う門(かど)には福(ふく)来(きた)る」と表示されます。

Textプロパティの書式

上記の例では「読み仮名エディタ」を使用してTextプロパティを設定しましたが、もちろん読み仮名エディタを使わずに、自分でTextプロパティを設定することもできます。

Textプロパティに指定する文字列は、ユニコード上のルビで記述された文字列です。つまり、親文字開始指定文字にU+FFF9、ルビ開始指定文字にU+FFFA、ルビ終止指定文字にU+FFFBを使います。

Textプロパティにはこのようなルビ表示制御文字そのものを使用する以外に、読み仮名エディタを使用した例のように、代わりにルビ表示制御文字を表した文字列を使用することもできます。例えばU+FFF9文字の代わりに、VB.NETでは"\uFFF9"、C#では@"\uFFF9"や"\\uFFF9"という文字列を使うこともできます。

逆に言えば、"\uFFF9"をそのまま表示したくて"\uFFF9"と書いたとしても、ルビ表示制御文字と解釈されてしまいます。

  1
  2
  3
  4
  5
  6
  7
'下のどちらでもOK
SimpleRuby1.Text = Char.ConvertFromUtf32(&HFFF9) & "笑" & _
    Char.ConvertFromUtf32(&HFFFA) & "わら" & Char.ConvertFromUtf32(&HFFFB) & _
    "う" & Char.ConvertFromUtf32(&HFFF9) & "門" & Char.ConvertFromUtf32(&HFFFA) & _
    "かど" & Char.ConvertFromUtf32(&HFFFB) & "には"
SimpleRuby1.Text = _
    "\uFFF9笑\uFFFAわらう\uFFFBう\uFFF9門\uFFFAかど\uFFFBには"
  1
  2
  3
  4
  5
//下のどちらでもOK
SimpleRuby1.Text =
    "\uFFF9笑\uFFFAわらう\uFFFBう\uFFF9門\uFFFAかど\uFFFBには";
SimpleRuby1.Text =
    @"\uFFF9笑\uFFFAわらう\uFFFBう\uFFF9門\uFFFAかど\uFFFBには";

ruby要素に対応していないブラウザで表示されるルビを囲む括弧を変更する

SimpleRubyでは、ルビの前後にrp要素が必ず入ります。これによって、ruby要素に対応していないWebブラウザで表示したときに、ルビが括弧などで囲まれます。デフォルトではルビは () で囲まれます。

ルビを囲む括弧を変更するには、FallbackLeftParenthesisとFallbackRightParenthesisプロパティを変更します。デフォルトでは、FallbackLeftParenthesisが"("で、FallbackRightParenthesisが")"になっています。

なお、SimpleRubyではrp要素が必ず入り、消す方法が無いようです。FallbackLeftParenthesisとFallbackRightParenthesisを空白にすると、両方とも"("が指定されたことになります。(FallbackRightParenthesisでは")"にならないとおかしいので、バグだと思われます。)

ruby要素とrt要素にクラス名を与える

SimpleRubyでruby要素にクラス名を与えるには、RubyCssClassプロパティを使います。同様に、rtとrp要素にクラス名を与えるには、RubyTextCssClassプロパティを使います。

例えばRubyCssClassプロパティを"kanji"、RubyTextCssClassプロパティを"yomigana"とした時にSimpleRubyが出力するHTMLは、以下のようになります。

<span id="SimpleRuby1"><ruby class = "kanji"><rb>笑</rb><rp class = "yomigana">(</rp><rt class = "yomigana">わらう</rt><rp class = "yomigana">)</rp></ruby><ruby class = "kanji"><rb>う</rb><rt></rt></ruby><ruby class = "kanji"><rb>門</rb><rp class = "yomigana">(</rp><rt class = "yomigana">かど</rt><rp class = "yomigana">)</rp></ruby><ruby class = "kanji"><rb>には</rb><rt></rt></ruby><ruby class = "kanji"><rb>福</rb><rp class = "yomigana">(</rp><rt class = "yomigana">ふく</rt><rp class = "yomigana">)</rp></ruby><ruby class = "kanji"><rb>来</rb><rp class = "yomigana">(</rp><rt class = "yomigana">きた</rt><rp class = "yomigana">)</rp></ruby><ruby class = "kanji"><rb>る</rb><rt></rt></ruby></span>

ruby要素とHTMLのバージョン

ruby要素は、Internet Explorerでは5.0から独自に対応していますが、正式には、XHTML1.1とHTML5からの採用です。

また、HTML5ではrb要素を採用していませんので、rb要素を省略できないSimpleRubyは使用することができません。

つまりSimpleRubyは、正式には、XHTML1.1以上でしか使用できないことになりそうです。

ユーザーが入力した文字列の読み仮名を取得する

Yomigana Frameworkには、ユーザーがIMEで入力した文字列の読み仮名を取得するためのコントロールが用意されています。Windowsフォーム、WPF、Ajaxで使用できるコントロールがそれぞれあります。以下に、表にまとめます。

名前種類DLL名前空間
YomiganaTextBox コントロールWindowsフォームコントロールYomiganaTextBox.dllMicrosoft.International.Windows.Forms
YomiganaWPFTextBox コントロールWPFコントロールYomiganaWPFTextBox.dllMicrosoft.International.Windows.Controls
YomiganaExtender コントロールAjaxエクステンダーコントロールYomiganaExtender.dllMicrosoft.International.AjaxControl

この内ここでは、YomiganaTextBoxとYomiganaExtenderコントロールの使い方を説明します。

YomiganaTextBoxコントロールを使う

YomiganaTextBoxコントロールを使うと、Windowsフォームコントロールで、テキストボックスに入力された文字列の読み仮名を別のコントロールに表示したり、取得したりが簡単にできます。

YomiganaTextBoxコントロールはYomiganaTextBox.dllに含まれていますが、JpnKanaConversion.dll、JpnKanaConvHelper.dll、YomiganaFramework.dllも必要ですので、これらすべてを参照設定に追加します。また、YomiganaTextBoxコントロールをツールボックスに登録するには、ツールボックスの「全般」タブで右クリックして「アイテムの選択」を選択し、「ツールボックスアイテムの選択」ダイアログの「.NET Framework コンポーネント」タブにある「参照」ボタンで「YomiganaTextBox.dll」を選択してください。

YomiganaTextBoxコントロールがツールボックスに登録されたならば、フォームデザイナでYomiganaTextBoxコントロールをフォームに配置します。また、YomiganaTextBoxコントロールに入力された文字列の読み仮名を表示するコントロールも配置します。ここでは、TextBoxを配置します。なお配置したYomiganaTextBoxの名前を「YomiganaTextBox1」、TextBoxの名前を「TextBox1」にしたとします。

YomiganaTextBox1に入力された文字列の読み仮名がTextBox1に表示されるように、YomiganaTextBox1のBindingControlプロパティを「TextBox1」とすれば、それだけで完成です。

出来上がったアプリケーションを実行させてみましょう。YomiganaTextBox1にIMEを使って「わらうかどにはふくきたる。」と打ってから変換して「笑う門には福来る。」と確定します。この時はまだ何も起こりませんが、YomiganaTextBox1以外のコントロールを選択してYomiganaTextBox1がフォーカスを失うと、TextBox1に「わらうかどにはふくきたる。」と表示されます。

YomiganaTextBox2

このように、YomiganaTextBoxがフォーカスを失ったときに、BindingControlプロパティに設定されたコントロールのTextプロパティに読み仮名が設定されます。

YomiganaTextBoxに入力された文字列の読み仮名は、TextCapturedプロパティからも取得できます。

IMEで確定したときに読みを取得する

ユーザーがIMEで入力文字を確定したとき、YomiganaTextBoxのYomiganaChangedイベントが発生します。この時YomiganaTextBoxのTextCapturedプロパティにより、YomiganaTextBoxに入力されている文字列の読み仮名を取得することができます。

  1
  2
  3
  4
  5
  6
'YomiganaTextBox1のYomiganaChangedイベントハンドラ
Private Sub YomiganaTextBox1_YomiganaChanged(ByVal sender As Object, _
                                             ByVal e As EventArgs) _
                                         Handles YomiganaTextBox1.YomiganaChanged
    Console.WriteLine("読み: " + YomiganaTextBox1.TextCaptured)
End Sub
  1
  2
  3
  4
  5
//YomiganaTextBox1のYomiganaChangedイベントハンドラ
private void YomiganaTextBox1_YomiganaChanged(object sender, EventArgs e)
{
    Console.WriteLine("読み: " + YomiganaTextBox1.TextCaptured);
}

読みをひらがな、カタカナ、半角カタカナで取得する

YomiganaTextBoxが取得した読み(TextCapturedプロパティ)は、デフォルトでは、ユーザーが入力したカナの種類になります。これをひらがな、カタカナ、あるいは半角カタカナに強制的に変換して取得するには、TextCapturedPreferredConversionプロパティを変更します。TextCapturedPreferredConversionプロパティに指定できる値(PreferredConversion列挙体のメンバ)は、以下の通りです。

PreferredConversion列挙体のメンバ説明
Noneユーザーが入力したカナのまま。
ToHiraganaカタカナと半角カタカナをひらがなに変換する。
ToKatakanaひらがなと半角カタカナをカタカナに変換する。
ToHalfwidthKatakanaひらがなとカタカナを半角カタカナに変換する。

なおこれらの変換は、.NETプログラミング研究第87号で紹介したKanaConverterクラスを使って行われます。

また、TextCapturedPreferredConversionプロパティがNoneでない時は、TextCapturedプロパティにアクセスするたびに変換が行われるようです。よってTextCapturedプロパティの内容に変化がないならば、TextCapturedプロパティを何度も呼び出さないほうが良いでしょう。

YomiganaTextBoxが読みを取得する仕組みと、不具合

YomiganaTextBoxは、ImmGetCompositionString関数を使ってユーザーがIMEで入力した読み仮名を取得しています。その他の方法は使っていないようです。

そのため、色々な制限(不具合?)があります。例えば、YomiganaTextBoxにIMEで「福来る」と入力してからカーソルを先頭に持ってきて「笑う門には」を挿入したとき、YomiganaTextBoxには「笑う門には福来る」と表示されますが、TextCapturedプロパティ(及び、BindingControlプロパティに指定したコントロールに表示される文字列)は「ふくきたるわらうかどには」となります。つまり挿入位置に関係なく、読み仮名は常に末尾に追加されるようです。

同じように、YomiganaTextBoxにIMEで入力した文字列を数文字削除したとしても、そのことがTextCapturedプロパティに反映されません。

このように、TextCapturedプロパティの値はYomiganaTextBoxに打ち込まれたカナを常に末尾に追加していった結果でしかなく、その文字が打ち込まれた位置や、基の文字列が削除されたかなどは考慮しません。ただし、基の文字列がすべて削除されたときは、TextCapturedプロパティの内容もクリアされます。

その他、コピペで貼りつけた文字列の読み仮名ももちろん取得できません。この場合コピペされた文字列がそのままTextCapturedプロパティになります。

その他の不具合

私が試した限りでは、TextAnnotatedプロパティは常にnullを返すようでした。正しくは、"\ufff9(Textプロパティの値)\ufffa(TextCapturedプロパティの値)\ufffb"という、ユニコード上のルビが振られた文字列が返されることになっているようです。

YomiganaExtenderコントロールを使う

YomiganaExtenderコントロールを使うと、Webアプリケーションで、テキストボックスに入力された文字列の読み仮名を別のコントロールに表示することができます。Ajaxを使用するため、ページ全体を更新することなく、読み仮名を表示できます。

YomiganaExtenderコントロールを使うには、YomiganaFramework.dllとYomiganaExtender.dllが必要ですので、これらを参照設定に追加します。

また、YomiganaExtenderコントロールをツールボックスに登録しておきます。(ツールボックスに登録しないと、後で説明する「エクステンダーの追加」が表示されません。)そのためには、ツールボックスの「全般」タブで右クリックして「アイテムの選択」を選択し、「ツールボックスアイテムの選択」ダイアログの「.NET Framework コンポーネント」タブにある「参照」ボタンで「YomiganaExtender.dll」を選択してください。詳しくは、先に紹介したSimpleRubyコントロールの説明をご覧ください。

それでは、テキストボックスに入力された文字列の読み仮名を別のコントロールに表示するWebページを作ってみましょう。

まずは、以下の手順でWebサービスを作成します。

  1. メニューの「プロジェクト」-「新しい項目の追加」(または、ソリューションエクスプローラでプロジェクトを右クリックしてメニューを出し、「追加」-「新しい項目」)を選択し、ダイアログを表示します。
  2. 「HTMLページ」を選択し、名前に「yomigana.asmx」と入力し、OKボタンをクリックします。(本来は「Webサービス」を選択すべきですが、そうすると無駄なコードファイルが作成されてしまいます。)
  3. yomigana.asmxを開き、内容を次のように書き換えて、保存します。
    <%@ WebService Language="C#"  CodeBehind="~/bin/YomiganaExtender.dll"  Class="Microsoft.International.AjaxControl.YomiganaService" %>
    

次に、Webページを作成します。まずは必要なコントロールを配置します。

  1. デザイナを使用して、WebページにTextBoxコントロールを配置します。ここでは、「TextBox1」という名前にしたものとします。
  2. 同じくWebページにLabelコントロールを配置します。このLabelコントロールに読み仮名を表示します。名前は「Label1」とします。なおLabelコントロール以外のコントロールに読み仮名を表示させることもできます。コントロールのTextプロパティに読み仮名が設定されます。
  3. さらにWebページにScriptManagerコントロールを配置します。名前は「ScriptManager1」とします。
    YomiganaExtender1

次に、テキストボックスにエクステンダーを追加します。

  1. TextBox1をクリックして選択し、スマートタグを表示させます。そこで、「エクステンダーの追加」を選択します。(または、TextBox1のプロパティウィンドウに表示される「エクステンダーの追加」を選択します。)
    YomiganaExtender2
  2. 「エクステンダーウィザード」で「YomiganaExtender」を選択し、IDを「TextBox1_YomiganaExtender」として、OKをクリックします。
    YomiganaExtender3

次に、YomiganaExtenderのプロパティを設定します。

  1. 「プロパティウィンドウ」のドロップダウンリストで「TextBox1_YomiganaExtender」を選択します。(または、「プロパティウィンドウ」でTextBox1のプロパティを表示し、「TextBox1_YomiganaExtender」の項目の左にある三角をクリックします。)
  2. TextBox1_YomiganaExtenderのServicePathプロパティを「yomigana.asmx」、TargetBindingControlプロパティを「Label1」に変更します。なおTextCapturedPreferredConversionプロパティは先に紹介したYomiganaTextBoxと同じで、読み仮名をひらがな、カタカナ、半角カタカナに強制的に変換するかを指定します。
    YomiganaExtender4

これで出来上がりです。ちなみにソースは、以下のようになります。

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<cc1:YomiganaExtender ID="TextBox1_YomiganaExtender" runat="server" 
    ServicePath="yomigana.asmx" TargetBindingControl="Label1" 
    TargetControlID="TextBox1">
</cc1:YomiganaExtender>
<br />
<asp:Label ID="Label1" runat="server"></asp:Label>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>

実際に試してみましょう。TextBox1にIMEを使って「わらうかどにはふくきたる」と打ち込んでから変換し、「笑う門には福来る」と確定します。その後TextBox1からフォーカスが離れると、Label1に「わらうかどにはふくきたる」と表示されます。

YomiganaExtender5

試して気づいたこと

私が試したところでは、Internet Explorer 8では動作しましたが、Firefox 3.6.17では動作しませんでした。Firefoxでは、TextBox1に入力した文字列がそのままLabel1に表示されました。

YomiganaTextBoxでは文字列の一部を削除したり、文字列の途中に挿入したときは正常に動作しませんでしたが、YomiganaExtenderではうまくいきます。ただし、コピペした文字列は、変になりました。

コメント



ページ情報
[ トップ ]   [ 編集 | 凍結 | 差分 | バックアップ | 添付 | 複製 | 名前変更 | リロード ]   [ 新規 | 子ページ作成 | 一覧 | 単語検索 | 最終更新 | ヘルプ ]