About the Site

This weblog is edited and run by members of reallyenglish, a company offering a total English learning solution based in London, Beijing, Shanghai and Tokyo. Visit our corporate site to know more about what we do.

Notes are posted by members from various cultural and geographical backgrounds, and the topics range from education, business and international communication to software development, the internet culture, and more.

Staff

Masatomo Nakano http://twitter.com/masatomon /m/mt-static/support/assets_c/userpics/userpic-2-100x100.png simonl davida jeremyw Go Kameda gavin b No name tomoyukis

 

Recent Comments

  • Tomoyuki Sakurai: we've been using vether(4) successfully since 4.7. http://old.nabble.com/kernel-6318:-arp-cache-problem-bridge%284%29-with-vether%284%29-td27635451.html (the bug read more
  • RofR: Hi everyone Where about to setup serveral OBSD 4.9 or read more
  • Tomoyuki Sakurai: the above configuration has been working fine since 4.6. read more
  • Jean Aumont: Hi Tomoyuki, If you capture the packets with tcpdump and read more
  • Tomoyuki Sakurai: you will not see OSPF packets on physical interface. > read more
  • Jean Aumont: Hi everyone, I have been trying to pass OSPF in read more
  • Anonymous: without any other information, all i can say is doing read more
  • Jean Aumont: I have a similar set-up, but my 2 end points read more
  • illouca: thank you for the patch !! read more
  • Go Kameda: Glad to hear that - im afraid i cannot really read more

Recently in Tips / Tutorials Category

Batch image exporting from .fla

| 4 Comments

Just wanted to post a small .jsfl code snippet to export .png images from each frames in the current timeline (with the currenrt .png export settings).

_ExportImages.jsfl
Download Demo Files

Although the same is possible by "Export" -> "Export Movie..." then choosing "png sequence" as the file format, jsfl can be more flexible as;

  1. It can export images from any (current) timeline
    Correction: It is also possible from "Export Movie", sorry for my ignorance.. orz
  2. It can possibly perform more complex batch processing (with a bit of code modification)
  3. The direct keyboard shortcut (with no dialog) can be assigned to it

Basic Usage

  1. Open the .fla from which you want to export the image (In the Demo, it is "ExportImagesTest.fla").
  2. From the menu, "Commands" -> "Run Command..." and open "_ExportImages.jsfl".

And, here is the Adobe Reference for how to run .jsfl in different ways;
Running JSFL files (Adobe Livedocs)

The image file names or location can be easily modified by editing the line with the comment. It saved me quite a lot of time so hopefully it could help be some help for any of you in any way.

Additional Note (1, June, 2011)

Added a simple example that exports .png files from multiple .fla files in a specified directory (tested on Flash CS4 / CS5.5 on Mac OSX 10.6)

_ExportImagesEX.jsfl
Download Demo Files

現在開いている.flaの各フレームから連番で.pngを書き出す超シンプルな.jsflスニペット、メモとして一応あげておきますね(Flash CS3とCS4で動作確認)。

_ExportImages.jsfl
Download Demo Files

実際"Export" -> "Export Movie"から.pngを連番で書き出せばいい話なのですが、jsflでならどのタイムラインからでも書き出せたり(Export Movieでもできました、知らなかったorz)、名前のコントロールが柔軟だったり、ダイアログなしで一発で終わるようにショートカットをあてがえたり、より複雑なバッチ処理にも使えたりするのがいいんじゃないかと思います。

使い方

  1. イメージ書き出し元の.flaを開く(デモでは "ExportImagesTest.fla")。
  2. "コマンド" -> "コマンドの実行"を選び、"_ExportImages.jsfl"を開く。

あとAdobeのリファレンスにいろんな方法でコマンド(.jsfl)を走らせる方法が書いてあります(一応です)
Running JSFL files (Adobe Livedocs)

超簡単なわりにわりと重宝したのでもし良ければという感じです。(とはいえjsflはしくじるとこわいのでどうぞ前もってお試しの上使ってください。。)

追記 (1, June, 2011)

指定したディレクトリにある複数の.flaから.pngファイルをExportする.jsflのサンプルを追加しました (tested on Flash CS4 / CS5.5 on Mac OSX 10.6)

_ExportImagesEX.jsfl
Download Demo Files

The other day I wanted to emphasize all the numbers in HTML text dynamically with JavaScript for some reason. First it was quite simple enough even to my RegEx-dummy brain. I just wrote something like the following;

(JavaScript)
function emphasizeNumbers(){
  var elmText = document.getElementById("text");
  elmText.innerHTML = elmText.innerHTML.replace(/(\d)/g, "<em>$1</em>");
  return false;
}

(HTML)
<p id="text">You have finished 3 lessons. Your score was 80/100. This is end of Stage 1. Please proceed to Stage 2. (By the way my number is 012-345-6789).</p>

So far it was simple enough. However when I looked at the consequence, I noticed that we did not want to emphasize the numbers followed by the word "Stage", as in "1" in "Stage 1" and "2" in "Stage 2". And I did not know the way how to exclude only these from the RegEx matches to be replaced.

Without too much consideration, first I tried the following;

function emphasizeNumbers(){
  var elmText = document.getElementById("text");
  elmText.innerHTML = elmText.innerHTML.replace(/[^(Stage )](\d)/g, "<em>$1</em>");
  return false;
}

Here I tried to mean "match with any digits which are preceded by anything other than the string 'Stage ' (as well as trying to exclude the grouped characters 'Stage ' from back-references)". However the result was miserable. Honestly I still cannot even explain what exactly happened here. Anyways, I understood that grouping with parenthesis ("()") in character class square bracket("[]") does not work (does it?).

After a while of googling, I found that there is an RegEx expression called "negative lookbehind". It took me about an hour to even vaguely understand the concept, but this seemed to be the answer. So anyways, I tried the following just mimicking the tutorial page;

function emphasizeNumbers(){
  var elmText = document.getElementById("text");
  elmText.innerHTML = elmText.innerHTML.replace(/[^(?<!Stage )(\d)/g, "<em>$1</em>");
  return false;
}

It did not work at all and ended up in a JavaScript error. Soon after that, I found that I missed out one important line in the tutorial page;

Finally, flavors like JavaScript, Ruby and Tcl do not support lookbehind at all, even though they do support lookahead.
OK great, (negative) lookbehind is NOT supported in current JavaScript (as of 2010 Jan, JavaScript 1.8.1) RegEx.

After all, I resolved the problem by doing the following.

function emphasizeNumbers(){
  var elmText = document.getElementById("text");
  elmText.innerHTML = elmText.innerHTML.replace(/(?:Stage\s)?(\d)/g, function(str, p1){
    if(str.indexOf("Stage ")!=-1) return str;
    else return "<em>" + p1 + "</em>";
  });
  return false;
}

This finally worked. I did not know that the String.replace method accepts a function instead of a replacing string as the second parameter.
String.replace (MDC Core JavaScript 1.5 reference) - Specifying a function as a parameter

However I'm not sure if this is the best solution - is there better and easier way to do the same?

前回に引き続き、今回はFreeBSDのJailの簡単な説明と、実際にどのような感じで使えるのか、簡単なサンプルを交え紹介します。

「プログラマのための」について

前回書き忘れてしまったのですが、なぜ「プログラマのための」というのをタイトルに入れたかというと、

  • プログラマは自分の開発環境/テスト環境の構築ぐらい自分ですべし
  • でも、環境構築に時間をかけすぎるのはプログラマとしては本末転倒だよね

この二つをあっさりと解決してくれるのがFreeBSDのJailだと感じているからです。

それと、自分自身そこそこ長いことプログラマをやってますが、Jailは自分にとってなかなか衝撃的だった、というのもこのエントリを書くきっかけになっているというのもあります。

FreeBSDのJailとは

さて、まず基本的なFreeBSDのJailについて簡単に触れておきます。

FreeBSDのJailは仮想環境の一つの実装です。仮想環境にも色々ありますがJailはその中でもとてもシンプルな物です。一つの物理的なサーバ上で動いている一つのFreeBSD(以下Jailホスト)の上で、複数のFreeBSD(以下Jailゲスト)が動いているように見えるようにする仕組です。「見えるようにする」だけというのがポイントで、実際にはJailホスト上のカーネルの上ですべてのプロセスが動いているだけです。

また、Jailとchrootを同じようなもの、と考えている人もいるようですが、chrootがファイルシステムだけが対象なのに対し、Jailはファイルシステムに加えネットワークやプロセスといったものも管理下になるのが違います。Jailゲスト一つが独立したIP addressを持ちます。

外からネットワーク越しに見ると、Jailゲストは一つのFreeBSD OSのように見えます。しかし、実際には、Jailホスト上の1つのカーネルで、Jailゲスト上のすべてのプロセスが動いています。このことは、Jailホスト上のカーネルからJailゲスト上の各プロセスを普通にpsやtopコマンド等で確認することができます。

また、この仕組みがそのままいくつかのJail自体の制限になります。たとえば、違うバージョンのFreeBSDや、違うOSを仮想環境として入れるといったVMWareやXenといった他の仮想環境でできることができません。そして、(今のところ)各Jailゲストで動くプロセスに対してリソースの割当や制限をすることができません。ですので一つのJailゲストがリソースを食い過ぎてしまうと他のJailゲストに大きく影響を与えます。この辺は将来的には何かできるようになるかも、という話です。

実際に動いている環境での例を示します。

host-top

これは、実際に弊社で稼働中のJailホストでtopした結果です。”j”を押すと左から2列目にJID (Jail ID)というものが表示されます。これはそのプロセスがどのJailゲストで動いているかということを示します。このようにJailホストからは、Jailゲストのプロセスが普通に見ることができますし、またJailホスト上からJailゲストのプロセスのkillなどは普通にできます。

では、その中の一つのJailゲストに入り、同じようにtopコマンドを実行してみます。すると、以下のようにそのJailゲストのプロセスのみが表示されます。

guest-top

このJailゲストはPostgreSQL用のものなのでPostgreSQLに関連するプロセスとcronなどの基本的なプロセスだけが走っているのがわかります。Jailゲストの中からは、他のJailゲストやJailホストの情報は見えません。これはプロセスだけではなくてファイルシステムなどもそうです。

とてもシンプルです。そして、シンプルなだけにに仮想環境を動かすこと自体のオーバヘッドが少なく、無駄なく一台のハードウェアの資源を使うことができます。また9年前にリリースされたFreeBSD 4.0Rからの機能なので安定度も非常に高いです。

資源という面では、Jailゲスト同士でFreeBSDのユーザランド部分をファイルレベルで共有するのでディスクスペースもそれほど無駄になりません。どう作るかにもよりますが、大雑把に言うと、/etc, /usr/local, /var あたりはJailゲスト毎ですが、/usr 以下は共有されます。また、もちろんパッケージからインストールしたものはJail毎になります。これにより資源を節約できるだけなく、Jailゲストの数をたくさん増やしたとしてもFreeBSDとしてのベース部分のメンテナンスは1カ所で済むのも楽なところです。

また、Jailゲストで使うファイルもJailホストと同じファイルシステム上にあるので、簡単に直感的に扱うことができます。例えば、あるJailゲスト上で「/etc/pam.d/systemを壊してしまって、仮想環境に入れなくなってしまった」というトラブルが起きたとします。Jailホスト上から見ると、このファイルは、/foo/bar/jails/hogehoge.example.com/etc/pam.d/system にあります。Jailホストにとっても普通のファイルなのでお使いのエディタで簡単に修復できます。

Jailの導入

Jail自体はFreeBSDに標準で組み込まれているのですが、その他にいくつか設定が必要です。また、Jail単体だと管理が大変なので、packageまたはportsから管理ツールであるsysutils/ezjailも導入してください。

さて、普通ならここでJailシステムのインストールの仕方等を紹介するべきなのかもしれませんが、ちょっと大変だし、世の中にあるものより劣化したドキュメントを垂れ流すだけになりそうなので、どこか適当な情報を探してください

また、Jail自体についてはこの辺が詳しいです。

Jailを使用した運用例

以下の例ではJailの管理ツールであるezjailを使っています。私はezjailができる前のJail事情を知らないのですが、その時代は色々と大変だったみたいです。

例1: Jailの新規作成

Jailゲストを新しく作ります。JailゲストはFQDNをディレクトリ名として作成され、その下がそのJailゲストの/(root)ディレクトリになります。

$ sudo ezjail-admin create newjail.example.com 192.168.4.25
/usr/local/jails/newjail.example.com/./bin/usr/local/jails/newjail.example.com/./boot
/usr/local/jails/newjail.example.com/./dev
/usr/local/jails/newjail.example.com/./etc
/usr/local/jails/newjail.example.com/./etc/X11
/usr/local/jails/newjail.example.com/./etc/bluetooth
/usr/local/jails/newjail.example.com/./etc/bluetooth/hcsecd.conf
/usr/local/jails/newjail.example.com/./etc/bluetooth/hosts
/usr/local/jails/newjail.example.com/./etc/bluetooth/protocols
/usr/local/jails/newjail.example.com/./etc/defaults
(中略)
/usr/local/jails/newjail.example.com/./.cshrc
/usr/local/jails/newjail.example.com/./COPYRIGHT
/usr/local/jails/newjail.example.com/./basejail

この例では、192.168.4.25 というIP addressがこのJailゲストに設定されます。(Jailホスト側にも192.168.4.25というIP addressをaliasとしてふる必要もあります。)

作成したJailゲストを起動してみます。

$ sudo ezjail-admin start newjail.example.com
Configuring jails:.
Starting jails: newjail.example.com.

Consoleに入ります。

$ sudo ezjail-admin console newjail.example.com
Copyright (c) 1992-2009 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
     The Regents of the University of California. All rights reserved.

FreeBSD 7.2-STABLE (GENERIC) #0: Fri Aug  7 20:52:37 BST 2009

Welcome to FreeBSD!
(中略)
You may also use sysinstall(8) to re-enter the installation and
configuration utility.  Edit /etc/motd to change this login announcement.

newjail#

ここれでJailゲストが一つ作成され起動しました。newjail# のプロンプトが表示され、この以下の操作はJailゲストの仮想環境内の操作になります。この中からは他のJailゲストやJailホストの情報は全く見えません。この先は普通のFreeBSDと同じように好きなようにパッケージを入れたり設定したりできます。もちろんsshdを起動すれば外から直接newjailに入ってこれます。

このようにコマンド2、3個、所要時間1分未満で簡単に1つの仮想環境を作成することができます。

例2: Jailゲストのコピー

似たような環境を作るときにいちいち0から設定するのは大変です。こういうときは既にあるJailを簡単にコピーできます。

先ほど作成したnewjailをコピーし、newjail2を作成してみましょう。

いったんnewjailを停止。

$ sudo ezjail-admin stop newjail.example.com

コピー

$ sudo cp -a /usr/local/jails/newjail.example.com /usr/local/jails/newjail2.example.com

単純なファイルコピーなので、rsyncでもtarでもお好きなものでどうぞ。(パーミッションとかに気をつけて)

コピーしたファイルを元にnewjail2を作成します。(すでにあるファイルを使う場合は-xをつける)

$ sudo ezjail-admin create -x newjail2.example.com 192.168.4.26

これで、完了です。

先ほどと同じようにコンソールに入りコピーされていることを確認します。(起動していない場合にはconsoleコマンドでstartもします。)

$ sudo ezjail-admin console newjail2.example.com
Configuring jails:.
Starting jails: cms3-build.uk.reallyenglish.com.
Copyright (c) 1992-2009 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
     The Regents of the University of California. All rights reserved.

FreeBSD 7.2-STABLE (GENERIC) #0: Fri Aug  7 20:52:37 BST 2009

Welcome to FreeBSD!
(中略)
You may also use sysinstall(8) to re-enter the installation and
configuration utility.  Edit /etc/motd to change this login announcement.

newjail2#

これでコピーされたJailゲストが動きだしました。

ファイルのコピーにかかる時間は、もちろんその中のファイルの量によるので何とも言えませんが、実作業時間はこちらも数分といったところでしょう。

同じようなやり方で複数のJailホスト間でJailゲストをコピー(または、元のを消せば移動)することもできます。この場合コピー先のJailホストは同一のアーキテクチャのサーバ、同一のFreeBSDのバージョンのものにしておいた方が無難です。

今回のまとめ

とにかくJailは簡単です。よほど深いことをするのでない限りJail自体の知識はあまり必要となりません。普通のUNIX的な知識とFreeBSD的な知識があれば普段使いとしては十分です。

個人的な経験では、他の仮想環境はメンテナンス含め色々と手間がかかります。気づいたら動くなくなってた仮想環境というのも目にします。またメモリやディスクスペースのオーバヘッドも大きいので簡単にいくつも作ったりもできません。Jailはそういう意味でもとても軽いし堅いです。もし何らかの理由で動かなくなったとしても、上記で説明したようにとてもシンプルなのでわりと簡単に修復できますし、仮想環境の中のファイルを外から取り出すのも簡単です。

次回はもう少しだけ運用のTipsなどを紹介して最後にしたいと思っています。

それでは!

On Having Layout

| No Comments

いまさらかもしれんですが感動しました、これを知っているだけでいままで「なぜ?」と戸惑いながらいろいろ思考錯誤してみるしかなかったIE6(と7)のCSSの問題が結構な確率で解決するように思います;  

On Having Layout (http://www.satzansatz.de/cssd/onhavinglayout.html)

ものすごくおおざっぱに理解したところを反芻させてもらうと;

  • IEにおいてはHTMLの要素に専用の「隠し」パラメータ "hasLayout"というものが存在する
  • これがある要素に対してOn(true)になっているかなっていないかで、その要素の挙動が大きく変化する
  • hasLayoutはデフォルトでは決められた少数の要素でしかOnになっていない(詳しくは本文参照)。何といっても、一番よく使われると思われるdiv要素でOnになっていない
  • hasLayoutは特定のCSSのプロパティを指定してやることでOnにできるので、hasLayoutがOffになっている要素でこれを恣意的にやってやることによってIEにおける他のブラウザとの表示不一致の問題の矯正が可能な場合がある(その逆も真)
といった話だと思います。hasLayoutのOn/Offが実際にどのような影響を及ぼすかについては本文にいくつかの例がリストとしてあがっています(まだincompleteな状態とのことです、具体例を全てあげていくのは困難なのではないでしょうか)。自分も良くわからないままに実際に試してみただけなのですが、div要素やp要素のhasLayoutをOnにしてやることで、IE6/7でのFirefox3との表示の不一致の問題の多く(margin, float関連)が解決したので驚きました。今では、CSSの編集時にIEで何か問題が起こると、ひとまずこのhasLayoutのOn/Offを試すようにしています。

reallyenglishでは、開発環境、また一部のプロダクション環境でFreeBSDのJail機能を使っています。このJailを使うことによりシンプルで柔軟な開発環境が構築できます。

“FreeBSD”と聞いて、「ああ、関係ないや」と思われた方へ。

ちょっとだけでも読んでみてください。JailのためだけでもFreeBSDを導入する価値があると思っています。もし、FreeBSDの導入が無理だとしても考え方自体は他のFreeBSDのJail以外の仮想環境でも使えるはずです。

前提

Webシステム開発ではたくさんのサーバソフトウェアが必要です。システムの中心部であるPHPやRuby On Railsといったアプリケーションサーバや、データを格納するデータベースサーバは最低限必要でしょう。またロードバランサやメールサーバといったものも必要なることもあります。

また開発時にはGitやSubversionのようなSCMや、コミュニケーションのためのIRCサーバなども必要かもしれません。同じような環境を開発者やテスター毎、開発拠点毎に設置する必要があることも珍しくないでしょう。さらに、一つのWebアプリケーションでも、プロダクション用や、開発用と複数のバージョンを持ちつつ同時に開発するのもよくあることです。

さらに、予算やスペースの関係で、プロダクションサーバでは多くの物理的なサーバで行っていることを開発環境では少ない台数のサーバで賄わないといけない、ということもよくあることでしょう。

そのような様々なことから、ちょっとしたWebサービスの開発でも、かなりの複雑な環境が必要になることがわかります。

そう言った複雑な環築をなるべくシンプルに構築するためにreallyenglishではFreeBSDのJailを使用した仮想環境を使っています。

基本的な方針

まず、基本的な方針として、1サービス=1仮想環境にします。これはプロダクション環境でも、開発環境でも同じです。つまり、Apacheでも、PostgreSQLでも、Memcacheでも、Postfixでも、Gitでも、とにかくサーバ的なものは必ず一つの仮想環境にしてしまいます。

つまり「このサービスは軽いから、他のサービスと同じところで動かしちゃおう」的なことをやめました。何か新しく必要になったら、仮想環境を新規で作成しそこにインストールします。ちょっとした実験的なサービスを入れる場合でも同じです。「Nginx試したい。じゃー、Jail作ってそこでやろう。」と言った感じです。

また、同じサービスでも、用途が違えば別に仮想環境を作ります。例えば、Apache等のWebサーバはVirtual Host機能を使うことにより1つのWebサーバを複数の用途として使えますが、そういうこともやめました。

狙いは2つです。

  • 設定をシンプルにする。一つのサーバで、あれもこれもしようとすると、どうしても設定ファイルが複雑にいなってしまいます。1サービス1Jailとすると必然的に設定はかなりシンプルになります。また、設定をシンプルにすることでPuppetと言ったツールも導入しやすくなります。
  • ハードウェアとサービス、サービス間を疎結合にする。粗結合にしておくと色々なことがとてもフレキシブルになります。例えば、一つのサービスの負荷が非常に高くなり他のサービスに影響を与え始めた。こういう場合、別のハードウェアを用意し、そのサービスだけ移動する、と言ったことがよく行われます。このときに1サービス = 1 仮想環境ならその仮想環境をコピー(移動)するだけで完了します。同一のネットワーク内で移動するだけなら、仮想環境のIP addressの付け替えさえ必要ありません。

いちいち仮想環境を作る。というのは一見めんどくさいようにも思えますし、リソース的にも無駄が多そうだ、と思われるかもしれません。しかし、FreeBSDのJailとその管理ツールを使用するとその辺は驚くほど問題になりません。

次回、実際にどう使っているかを紹介します。

続く

FAQ for SWFObject is a must-read

| No Comments

SWFObjectのFAQはいけてますね、FlashをHTMLにembedするにあたっての陥りやすい罠が網羅されている印象です。実質、FAQの項目の多くが SWFObject自体の問題というよりはブラウザのバグ等が原因のため、同ライブラリを使う使わないに関わらず起こるもののような気がするのですが、SWFObjectが非常に多くの人達に使われているため、ここにそのあたりの質問とその応答の結果として蓄積されたノウハウが一番端的に集まっているように思います。日々様々な(時にはいわれのない)「おい、これ動かんぞ」の問い合わせに開発者の方やコミュニティーのみなさんが反応してくれている状況を想像するに、様々なライブラリ一般を公開して維持してくれている全てのみなさんへの尊敬の念が深まります。

Learning .mxml (as a .fla guy)

| No Comments

他のActionScriptを(も)書いているtechチームメンバーと違い、.flaファイルを使ったFlash IDEを用いてのコンテンツ制作しかろくにできなかった自分ですが、ここ数日、非常に小さいながらもFlex Framework/.mxmlを使った仕事(.mxmlで書かれたテスティングツールのUIデザイン)をやらせてもらっていて、今更なんとか勉強しているところです。

Flex Builderは稀にASエディタ/デバッガとしてしか使うくらいでしたし(今は主にFDTFlashDevelopをつかってます)、reallyenglishに参加させてもらう前はどちらかというと表現重視のものをつくってきた経緯から、傲慢にも自分がFlexを覚えるメリットは大してないだろうと考えていました(実際.mxml主体の制作方法ではものすごく難しい制作ケースがほとんどだったと思います)。しかし今回Flex Frameworkを実際に少し勉強してみて、逆にこの充実したFrameworkの恩恵をうまく使えばいろいろなことが本当に楽にできそうだ(逆にいうと恩恵をうけないと大変すぎて無理そう)といったケースが多くあるだろうということも実感しました。

このAdobeのチュートリアルなどをみるとおおこれは簡単そう、と感動しましたし、何よりも.mxmlを使えばソースがテキストだけで完結できるケースが増えるので見通しがよくなるのが魅力だと思います。これからは二つの制作方法の使いどころを把握してうまいこと組み合わせて使っていけるようになれたらなと考えています。

(。。という流れからもXFLには超期待しているんですが最近どうなっているのでしょうか? あと最初はなんじゃこりゃと思っていたFlash Catalystも今はぜひ使ってみたいと思っています。)

さて本題です。Flex FrameworkのHTMLライクなレイアウトの仕組みもぱっと見思ったより簡単そうでよかったのですが、Flex用のCSSもちゃんと充実してるんですね。検索したら非常にありがたい参考サイトがあったので、紹介させてもらいます。

追記:
Flex BuilderがFlash Builderと再ブランディングされることになり、ますます用語の使い方に迷いますが、下記の記事はFlexって結局なんだったっけ、と再勉強するにあたって非常に助けになりました。

Highlighting Text in TextField

| No Comments

Manipulating text presentation in a Flash interface is a very common task when developing a interface for learning applications at reallyenglish. "Highlighting" a certain parts of the text in a Flash TextField is just one of them and unlike doing it in HTML, it could be a bit cumbersome task sometimes. This time I tried to modularize the functionality.

View Demo
Source files (.zip, 356KB)

Rough description of how to use (please refer to the demo and the source code as well);

 // Create a TextHiliter class instance, passing references for the TextField and a Sprite to draw hilighting marker;
_textHiliter = new TextHiliter(refTextField, refCanvas);

// Hilight the 1st to 4th letters, with #C4E1FF (100% alpha) marker
_textHiliter.hilite(0, 4, 0xC4E1FF, 1);

// Hilight the letters "unable to stop herself to assist her" between "Margaret, " (please note the spaces)  and ", was involuntarily" with #D3FD2D (100% alpha) marker
// The current implementation hilights the 1st match only
_textHiliter.hiliteByLetters("unable to stop herself to assist her",  0xD3FD2D, 1, "Margaret, ", ", was involuntarily");

Although it's still under improvement, I think that the logic for extracting area of certain part of the text can be applied to some other purposes. (And please enlighten me if you know a better way of doing it..!)

2009/12/20:
Made the following changes.

  • Changed hilite() method so that it does not include the character specified by the argument "end(index)". Now it takes effect to the part specified by start and all characters up to end - 1, just like String.substring() method.
  • Changed the Demo so that the text can be highlighten just by selecting a certain part of it.

reallyenglishに参加してから、ActionScriptでのテキストの加工(特に表示面での加工)を行うことが多くなりました。ダイナミックテキストの特定の複数箇所をハイライト(マーキング)するといった処理もその一つです。HTMLだと楽勝ですが、Flashの場合やってみたらかなりめんどくさい感じだったのでこの機能を切り出したものをつくってみました。

View Demo
Source files (.zip, 356KB)

TextHiliterクラスのおおまかな使い方(詳しくはデモ及びソースコードを参照);

// TextField、及び描画用Spriteの参照を引数にTextHiliterのインスタンスをつくる
_textHiliter = new TextHiliter(refTextField, refCanvas);

// 1文字目から4文字目までを、#C4E1FF、100%アルファでハイライトする場合
_textHiliter.hilite(0, 4, 0xC4E1FF, 1);

// "Margaret, " と ", was involuntarily"(スペースに注意) という文字列に挟まれた "unable to stop herself to assist her" という文字列を、#D3FD2D、100%アルファでハイライトする場合
// (現状の実装では、条件を満たすものが複数あった場合も、一番初めにマッチしたものにしか適用されないです)
_textHiliter.hiliteByLetters("unable to stop herself to assist her",  0xD3FD2D, 1, "Margaret, ", ", was involuntarily");

まだ発展途上ですが、TextField内の文字列のエリアを取得する部分のロジックは他の用途にも応用できると思うので、何かの参考にでもなれば嬉しいです。あともっといいやり方があれば教えてください。。!

2009/12/12 追記:
下記を変更しました。

  • hilite()メソッドをString.substring()メソッドと同様、startで指定したindexからendで指定したindexの一文字前までハイライトするように変更(以前はendで指定したindexの文字を含んでました、ごめんなさい)
  • デモにおいて、テキストをセレクトするとセレクトした部分がハイライトされるよう変更