<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>Chronicle it.</title>
   <link rel="alternate" type="text/html" href="http://www.fourmeisters.com/blog/yoshi/" />
   <link rel="self" type="application/atom+xml" href="http://www.fourmeisters.com/blog/yoshi/atom.xml" />
   <id>tag:www.fourmeisters.com,2008:/blog/yoshi//1</id>
   <updated>2008-06-10T06:27:02Z</updated>
   <subtitle>yoshi@fmscのブログ</subtitle>
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.35</generator>

<entry>
   <title>Scala と specs の簡単なサンプル</title>
   <link rel="alternate" type="text/html" href="http://www.fourmeisters.com/blog/yoshi/2008/06/scala_specs.html" />
   <id>tag:www.fourmeisters.com,2008:/blog/yoshi//1.233</id>
   
   <published>2008-06-10T06:25:28Z</published>
   <updated>2008-06-10T06:27:02Z</updated>
   
   <summary> 暫くぶりに投稿します。 近頃は、時間があればScalaを勉強しています。 Sc...</summary>
   <author>
      <name>yoshi</name>
      
   </author>
         <category term="scala" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="126" label="scala" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="127" label="specs" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.fourmeisters.com/blog/yoshi/">
      <![CDATA[<br/>
<br/>
暫くぶりに投稿します。<br/>
近頃は、時間があればScalaを勉強しています。<br/>
ScalaはJavaにはない興味深い機能が多くあり、それらの内の幾つかを
コードを見ながら、ここで、解説していきたいと思います。<br/>
また勉強の過程で知ったspecsという検証用のフレームワークがなかなか
おもしろかったので、そちらも紹介したいと思います。<br/>

<h1>Scala</h1>

Scalaは特徴の多いプログラミング言語です。<br/>
関数を変数として保持できたり、クロージャ、多重継承やパターンマッチ、
Erlangのような並列処理機構などなど数多くの機能を備えています。<br/>
学習の敷居はそれなりに高い(私は苦戦中...)のですが、言語の表現力の高さや、
パフォーマンス、 Javaライブラリを利用可能など、魅力に富んでいます。<br/>
個人的には構文解析のパーサが気になります。(TODO:後で勉強。)<br/>

<h3>リンク</h3>
<ul>
  <li>
    <a href="http://www.scala-lang.org/">Scala (英語)</a> : 本家
  </li>
  <li>
    <a href="http://www.scala-lang.org/docu/files/ScalaByExample.pdf">Scala By Example (pdf,英語)</a> : Scalaの特徴を体系的に解説している ScalaByExample 
  </li>
  <li>
    <a href="http://www29.atwiki.jp/tmiya/pages/23.html">Scala By Example 和訳</a> : 和訳プロジェクト 
  </li>
</ul>

<h1>specs</h1>

specsはScalaでJUnitのようにテストを実施するためのフレームワークです。<br/>
specsは仕様を書くような感覚で検証コードを書くことをその設計思想としている
ようです。(BDD: Behavior Driven Development )<br/>
人に優しい、プログラムの読みやすさや簡潔さにこだわりを感じるフレームワークです。<br/>

<h3>リンク</h3>
<ul>
  <li>
    <a href="http://code.google.com/p/specs/">specs (英語)</a>
  </li>
</ul>

<h1>Scala - 電話番号っぽい？</h1>

Scalaの構文を勉強しながら、ちょっとしたコードを書きました。<br/>
以下は、文字列が電話番号っぽいかを判定します。<br/>

<div class="code">
object PhoneNumber {
  val phoneNumPtn = """^(\d{2,4}+)\-?(\d{2,4}+)\-?(\d{2,4}+)$""".r

  // 電話番号ぽっい番号の場合はtrueを返す
  def isValid(phoneNumber:String):Boolean = {
    phoneNumber match {
      case phoneNumPtn(s1:String, s2:String, s3:String) => {
        println( "valid : " + s1 + s2 + s3 );
        return true;
      }
      case _ => return false
    }
  }
}
</div>
※ ここでは、Scalaのバージョン 2.7.1.final を使用しています。<br/>
<br/>
<br/>

<h2>コードの解説 / バラバラと</h2>

<div class="code">
object PhoneNumber {
  ...
}
</div>
objectで定義するとPhoneNumberはシングルトンとしてインスタンス化されます。<br/>
class PhoneNumber も別途定義できます。<br/>
<br/>
<br/>

<div class="code">
  val phoneNumPtn = """^(\d{2,4}+)\-?(\d{2,4}+)\-?(\d{2,4}+)$""".r
</div>
これは正規表現パターンを定義します。<br/>
valは変更不可の値を定義します。Javaのfinalのようなものです。 ( 変更可能な値は var で定義します。 )<br/>
<br/>
"fugafuga".rの様に文字列に.r を付与すると、文字列が正規表現として解釈され、scala.util.matching.Regex 型のインスタンスが作られます。<br/>
また、""" で文字列を囲うと、いわゆるヒアドキュメントとして扱われます。<br/>
ヒアドキュメントは、複数行に渡る文字列を定義するときなどに使用します。ここでは、\マークをエスケープせずに記述するために使用しています。<br/>
<br/>
<br/>

<div class="code">
  def isValid(phoneNumber:String):Boolean = { ... }
</div>
def はメソッドを定義するときに使用します。<br/>
このメソッドはString型の引数を1つ受け取ります。<br/>
末尾の :Boolean はこのメソッドが Boolean型 を返すことを意味します。<br/>
<br/>
<br/>

<div class="code">
     phoneNumber match {
      case phoneNumPtn(s1:String, s2:String, s3:String) => {
        println( "valid : " + s1 + s2 + s3 );
        return true;
      }
      case _ => return false
    }
</div>
match { case xxx => { ... } case yyy => { ... } } はパターンマッチングの構文です。case の条件を上から順に評価し、条件にマッチした場合、=> の右辺のブロックが実行されます。<br/>
<br/>
phoneNumPtn(s1:String, s2:String, s3:String) の部分では、phoneNumPtnで定義される正規表現にマッチする場合、正規表現の()で囲>われた値に相当する文字列をs1,s2,s3にセットします。<br/>
<br/>
この例で文字列 11-22-33 でマッチングさせると s1="11" s2="22" s3="33" になります。<br/>
case _ は必ずマッチします。<br/>
<br/>


<h1>specsで検証</h1>

specsを使って先述のコードを検証するコードを用意しました。


<div class="code">
import org.specs._

object PhoneNumberSpec extends Specification {

  "正しい電話番号である" in {
    PhoneNumber.isValid("0120-000-000") mustBe true
    PhoneNumber.isValid("03-0000-0000") mustBe true
    PhoneNumber.isValid("090-0000-0000") mustBe true
    PhoneNumber.isValid("110") mustBe true  // failure
  }

}
</div>
※ ここでは、specsのバージョン 1.2.9 を使用しています。<br/>
<br/>

コードにある通り「正しい電話番号である」ことを検証します。<br/>
specsは簡潔に記述すること、何を行うのかを明瞭におくことを易しくしてくれます。<br/>
<br/>
<h2>検証処理の流れ</h2>
<br/>
<h3>1. 暗黙的型変換 - implicit conversion</h3>
実際に処理がどのように呼び出されるかを確認します。<br/>
上記のコードでは主な検証処理を以下の様な形式で実行しています。<br/>

<div class="code">
  "文字列" in { ..処理.. }
</div>

このコードには若干トリックが含まれています。タネは、継承元のクラスにあります。<br/>
上記のクラスの親の一つにSpecificationStructureクラスがあり、そこに以下のメソッドが定義がされています。<br/>
<div class="code">
  implicit def forExample(desc: String): Example = { ... }
</div>

このコードによって、文字列は暗黙的にExample型のインスタンスに変換されます。<br/>
in メソッドはString型に定義はなく、Example型に定義されているため、Exapmple型へ変換されるのです。<br/>
変換処理が上述のforExampleメソッドです。(メソッドの名前は何でも構いません。引数と返却値の型によって呼び出し先が決定されます。)

<br/>
これは、Scalaの implicit conversion (暗黙の型変換) と呼ばれる機能です。<br/>
<br/>
<br/>

<h3>2. 省略記法、名前渡し</h3>
次に in の部分ですがこれは、in というメソッドを呼び出しています。<br/>
Scalaでは、メソッド呼び出し時にドットや引数の括弧などを省略して記述することができます。<br/>
元のコードの省略記法を利用せずに書き直すと、以下の様になります。<br/>

<div class="code">
  forExample("正しい電話番号である").in( {
    PhoneNumber.isValid("0120-000-000").mustBe(true)
    PhoneNumber.isValid("03-0000-0000").mustBe(true)
    PhoneNumber.isValid("090-0000-0000").mustBe(true)
    PhoneNumber.isValid("110").mustBe(true)  // failure
  } )
</div>
(どちらの書き方が良いかは好みにもよりますね。)<br/>
<br/>
inメソッドは、Any型の値を1つ「名前渡し(call-by-name)」で受け取って、Example型を返すメソッドです。<br/>
メソッドはExampleクラスに定義されています。<br/>
<div class="code">
  def in (test: => Any): Example = { .... }
</div>
引数の型を 「 => Any 」 の様に => を付与して宣言することで、名前渡しにすることができます。<br/>
名前渡しの場合、引数が参照される度に、値が評価されます。<br/>
今回の例では、{}で囲まれたブロックを渡しており、ブロックの中身が in メソッドの中で評価されます。<br/>
結果として、ブロックの中味が実行されて、検証の処理が行われます。<br/>
<br/>
<br/>

<h3>3. 再び implicit conversion</h3>
ブロックの中では mustBe メソッドを呼び出しています。<br/>
これも implicit conversionによって、実際にはAssertクラスに変換されて、mustBe メソッドが
呼び出されます。<br/>
このimplicit conversionは、Specificationの親クラスの一つである、AsserFactoryに定義されています。<br/>
<div class="code">
  implicit def theValue[A](value: =>A) = {
    addAssertion
    new Assert[A](value)
  }
</div>

この処理を明示的にして書き直すとこのようになります。
<div class="code">
  forExample("正しい電話番号である").in( {
    theValue( PhoneNumber.isValid("0120-000-000") ).mustBe(true)
    theValue( PhoneNumber.isValid("03-0000-0000") ).mustBe(true)
    theValue( PhoneNumber.isValid("090-0000-0000") ).mustBe(true)
    theValue( PhoneNumber.isValid("110") ).mustBe(true)  // failure
  } )
</div>
明示的にすることで、処理の流れは分りやすくなりましたが、
コードの意図、即ち何をしようとしているのかが若干分りづらくなったように感じます。
Scalaでコードを書くときには、この辺りのトレードオフを意識しておくとよいかもしれません。

<h2>実行結果</h2>
<div class="code">
> fsc PhoneNumber*.scala
> scala PhoneNumberSpec
Specification "PhoneNumberSpec"
  specifies
valid : 0120000000
valid : 0300000000
valid : 09000000000
  x 正しい電話番号である
    'false' is not the same as 'true' (PhoneNumberSpec.scala:9)

Total for specification "PhoneNumberSpec":
Finished in 0 second, 113 ms
1 example, 4 assertions, 1 failure, 0 error
</div>



<h2>おわりに</h2>
まだ深くは見ていませんが、specsのAPIは良く考えられていて、実用性のある機能が
利用しやすい形で提供されている気がします。<br/>
こういったAPIを見て、簡潔に物事を表現する手段として、 Scalaイケテルヤモ？ と思っている今日この頃です。では。

]]>
      
   </content>
</entry>
<entry>
   <title>プロジェクト管理サービス</title>
   <link rel="alternate" type="text/html" href="http://www.fourmeisters.com/blog/yoshi/2007/11/post_1.html" />
   <id>tag:www.fourmeisters.com,2007:/blog/yoshi//1.130</id>
   
   <published>2007-11-06T18:07:26Z</published>
   <updated>2007-11-06T18:18:36Z</updated>
   
   <summary>最近、プロジェクト管理やタスク管理用のオンラインサービスがかなり充実してきていま...</summary>
   <author>
      <name>yoshi</name>
      
   </author>
         <category term="service" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.fourmeisters.com/blog/yoshi/">
      <![CDATA[最近、プロジェクト管理やタスク管理用のオンラインサービスがかなり充実してきています。<br/>
オンラインのサービスは、情報管理と共有といった目的を達成する手段として、相性の良い組み合わせですよね。<br/>
ただ、多くのサービスがあるのですが、なんとなく、しっくりくるものがない状態です。<br/>
おそらく、今後も数多くの製品・サービスが産まれ、淘汰が進んでいくのではないでしょうか。<br/>
<br/>
ここでは、プロジェクト管理系のサービスで、今私が気になっているものを紹介します。<br/>
<br/>
<br/>
<br/>

<ol>
<li>
<a href="https://www.acunote.com/">Acunote</a>
<ul>
<li>アジャイルソフトウェア開発の思想に基づいている。(スプリント,バックログなど)</li>
<li>タスクの進捗管理に長けていて、担当者単位でグラフ表示できる。</li>
<li>ソースコードを表示してコメントを書ける。</li>
<li>バグトラッカー(Bugzilla, Mantis, Trac)から、バグリストをインポートできる(らしい)。</li>
<li>サンプル画面<br/>
<a href="http://www.fourmeisters.com/blog/yoshi/2007/11/07/Acunote.png"><img alt="Acunote.png" src="http://www.fourmeisters.com/blog/yoshi/2007/11/07/Acunote-thumb.png" width="240" height="234" /></a>
</li>
</ul>
</li>


<li>
<a href="http://lighthouseapp.com/">Lighthouse</a>
<ul>
<li>シンプルなタスク管理。</li>
<li>マイルストーンに紐付くチケット(タスク)を発行し、プロジェクトメンバの中から担当者を決める。</li>
<li>画面構成が綺麗。(若干迷う気もするが)</li>
<li>APIが公開されている。(<a href="http://lighthouseapp.com/api">ドキュメント</a>)</li>
<li>サンプル画面<br/>
<a href="http://www.fourmeisters.com/blog/yoshi/2007/11/07/Lighthouse.png"><img alt="Lighthouse.png" src="http://www.fourmeisters.com/blog/yoshi/2007/11/07/Lighthouse-thumb.png" width="240" height="160" /></a>
</li>
</ul>
</li>


<li>
<a href="http://www.myquire.com/">MyQuire</a></li>
<ul>
<li>プロジェクト管理だけでなく、SNS色もある。</li>
<li>メッセージやチャットなどのコミュニケーション機能が充実。</li>
<li>他にもカレンダーやファイルスペースなどが用意されているオールインワンな環境。</li>
<li>サンプル画面<br/>
<a href="http://www.fourmeisters.com/blog/yoshi/2007/11/07/MyQuire.png"><img alt="MyQuire.png" src="http://www.fourmeisters.com/blog/yoshi/2007/11/07/MyQuire-thumb.png" width="240" height="270" /></a>
</li>
</ul>
</li>
</ol>

<br/>
以上、3点です。<br/>
# いずれも、無料で試せます。

]]>
      
   </content>
</entry>
<entry>
   <title>WYSIWYGエディタに夢中になったときのメモ</title>
   <link rel="alternate" type="text/html" href="http://www.fourmeisters.com/blog/yoshi/2007/09/wysiwyg.html" />
   <id>tag:www.fourmeisters.com,2007:/blog/yoshi//1.89</id>
   
   <published>2007-09-13T16:13:00Z</published>
   <updated>2007-09-13T16:42:49Z</updated>
   
   <summary> javascriptでHTML-WYSIWYGエディタを作ろうとしたときのメモ...</summary>
   <author>
      <name>yoshi</name>
      
   </author>
         <category term="javascript" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.fourmeisters.com/blog/yoshi/">
      <![CDATA[<p>
javascriptでHTML-WYSIWYGエディタを作ろうとしたときのメモを公開します。
</p>

<br/>
<br/>
<h1>1. 編集 - document.designMode</h1>
<p>
 documentオブジェクトにはdesignModeというプロパティがあります。<br/>
 このプロパティをonにすると、そのdocumentは編集可能になります。
</p>

 iframe内のdocumentを編集可能するにはこのようにします。

<div class="code">
var doc, iframe = document.getElementById('xxx');

// IE, Operaの場合
doc = iframe.contentWindow.document;

// FF, Safariの場合
doc = iframe.contentDocument; 

doc.designMode = 'on';
</div>

<br/>
<br/>
<h1>2. 装飾 - document.execCommand()</h1>
<p>
 あるボタンを押すと文字の色が変わる、などの制御を入れたい場合には、
 メソッドexecCommandを使用すると便利です。
</p>

<ul>
<li>太字にする</li>
<div class="code">
document.execCommand( "bold", false, null );
</div>
<li>文字の色を赤くする</li>
<div class="code">
document.execCommand( "forecolor", false, 'red' );
</div>
</ul>

<p>
 execCommandの第一引数には、文字列でコマンドを指定します。<br/>
 コマンドによっては第三引数の、パラメータが必要になります。
</p>

<p>
 コマンドの一覧は以下に記載されています。 ( operaとsafariの資料はどこにあるのでしょう? )<br/>
 Firefoxは、英語ドキュメントの方が、より多くのコマンドが載っています。
 <ul>
  <li><a href="http://msdn2.microsoft.com/en-us/library/ms533049.aspx">IE コマンド一覧(英語) http://msdn2.microsoft.com/en-us/library/ms533049.aspx</a></li>
  <li><a href="http://www.mozilla-japan.org/editor/midas-spec.html">Firefox コマンド一覧(日本語) http://www.mozilla-japan.org/editor/midas-spec.html</a></li>
  <li><a href="http://www.mozilla.org/editor/midas-spec.html">Firefox コマンド一覧(英語) http://www.mozilla.org/editor/midas-spec.html</a></li>
 </ul>
</p>
<br/>
<br/>

<h1>3. 生成されるHTMLの違い</h1>
<p>
 execCommandを使用して生成されるHTMLは、ブラウザによって違います。
</p>
<p>
 この違いから、あるブラウザで生成したHTMLを(サーバ上で保持させ)、別のブラウザで
 編集しようとすると、execCommandが期待通りに動いてくれないときがあります。<br/>
 クロスブラウザの環境をサポートしたい場合には、この違いを吸収してあげなくてはなりません。
</p>
 生成されるHTMLを、手元の環境で確認した結果をまとめてみました。 (少し見づらいですが)

<script type="text/javascript">
$(function(){
  $('#execCommandTbl tr:odd').css('background','#eef3fa');
  $('#execCommandTbl td').hover(
    function(){ 
      for ( var index = 0, node = this.parentNode.firstChild; node; node = node.nextSibling ) {
        if( node == this ){
          break;
        }
        index++;
      }
      if( index ){
        var cmd = this.parentNode.firstChild.innerHTML;
        var browser = $('#execCommandTbl th').get(index).innerHTML;
        $('#tablePoint').html( 'Table Navigation: &nbsp;&nbsp;&nbsp;' + cmd + ' × ' + browser );
        $(this).css('background','#d3e3f3');
      }
    },
    function(){
      $('#tablePoint').html('Table Navigation: ');
      $(this).css('background','');
    }
  );
});
</script>
<div id="tablePoint" style="color:#777777; margin-top:20px;">Table Navigation: </div>
<div style="overflow: scroll; width:100%; height:400px; border:1px solid #444444;">
<table id="execCommandTbl" >
<tr><th>command</th><th>Internet Explorer 6</th><th>Firefox 2.0 (styleWithCSS=false)</th><th>Firefox 2.0 (styleWithCSS=true)</th><th>Safari 3.0.3 (windows版)</th><th>Opera 9.23</th></tr>
<tr><th>backcolor</th><td>&lt;FONT style="BACKGROUND-COLOR: red"&gt;Hello&lt;/FONT&gt;</td><td>Hello</td><td>Hello</td><td>&lt;span class="Apple-style-span" style="background-color: red;"&gt;Hello&lt;/span&gt;</td><td>Hello</td></tr>
<tr><th>bold</th><td>&lt;STRONG&gt;Hello&lt;/STRONG&gt;</td><td>&lt;b&gt;Hello&lt;/b&gt;</td><td>&lt;span style="font-weight: bold;"&gt;Hello&lt;/span&gt;</td><td>&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Hello&lt;/span&gt;</td><td>&lt;STRONG&gt;Hello&lt;/STRONG&gt;</td></tr>
<tr><th>createlink</th><td>&lt;A href="http://www.google.co.jp"&gt;Hello&lt;/A&gt;</td><td>&lt;a href="http://www.google.co.jp"&gt;Hello&lt;/a&gt;</td><td>&lt;a href="http://www.google.co.jp"&gt;Hello&lt;/a&gt;</td><td>&lt;a href="http://www.google.co.jp"&gt;Hello&lt;/a&gt;</td><td>&lt;A href="http://www.google.co.jp"&gt;Hello&lt;/A&gt;</td></tr>
<tr><th>fontname</th><td>&lt;FONT face=sans-serif&gt;Hello&lt;/FONT&gt;</td><td>&lt;font face="sans-serif"&gt;Hello&lt;/font&gt;</td><td>&lt;span style="font-family: sans-serif;"&gt;Hello&lt;/span&gt;</td><td>&lt;span class="Apple-style-span" style="font-family: sans-serif;"&gt;Hello&lt;/span&gt;</td><td>&lt;FONT face="sans-serif"&gt;Hello&lt;/FONT&gt;</td></tr>
<tr><th>fontsize</th><td>&lt;FONT size=2&gt;Hello&lt;/FONT&gt;</td><td>&lt;font size="2"&gt;Hello&lt;/font&gt;</td><td>&lt;font size="2"&gt;Hello&lt;/font&gt;</td><td>&lt;span class="Apple-style-span" style="font-size: small;"&gt;Hello&lt;/span&gt;</td><td>&lt;FONT size="2"&gt;Hello&lt;/FONT&gt;</td></tr>
<tr><th>forecolor</th><td>&lt;FONT color=red&gt;Hello&lt;/FONT&gt;</td><td>&lt;font color="red"&gt;Hello&lt;/font&gt;</td><td>&lt;span style="color: red;"&gt;Hello&lt;/span&gt;</td><td>&lt;span class="Apple-style-span" style="color: red;"&gt;Hello&lt;/span&gt;</td><td>&lt;FONT color="#ff0000"&gt;Hello&lt;/FONT&gt;</td></tr>
<tr><th>formatblock</th><td>&lt;H1&gt;Hello&lt;/H1&gt;</td><td>&lt;h1&gt;Hello&lt;/h1&gt;</td><td>&lt;h1&gt;Hello&lt;/h1&gt;</td><td>&lt;h1&gt;Hello&lt;br&gt;&lt;/h1&gt;</td><td>&lt;H1&gt;Hello&lt;/H1&gt;</td></tr>
<tr><th>indent</th><td>&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt; &lt;P&gt;Hello&lt;/P&gt;&lt;/BLOCKQUOTE&gt;</td><td>&lt;blockquote&gt;Hello&lt;/blockquote&gt;</td><td>&lt;div style="margin-left: 40px;"&gt;Hello&lt;/div&gt;</td><td>&lt;blockquote class="webkit-indent-blockquote"&gt;Hello&lt;br&gt;&lt;/blockquote&gt;</td><td>&lt;BLOCKQUOTE&gt;Hello&lt;/BLOCKQUOTE&gt;</td></tr>
<tr><th>inserthorizontalrule</th><td>&lt;HR&gt;</td><td>&lt;hr size="2" width="100%"&gt;</td><td>&lt;hr style="width: 100%; height: 2px;"&gt;</td><td>&lt;hr id="undefined"&gt;&lt;/hr&gt;</td><td>&lt;HR&gt;</td></tr>
<tr><th>insertimage</th><td>&lt;IMG src="http://www.google.co.jp/intl/ja_jp/images/logo.gif"&gt;</td><td>&lt;img src="http://www.google.co.jp/intl/ja_jp/images/logo.gif"&gt;</td><td>&lt;img src="http://www.google.co.jp/intl/ja_jp/images/logo.gif"&gt;</td><td>&lt;img src="http://www.google.co.jp/intl/ja_jp/images/logo.gif"&gt;&lt;br&gt;</td><td>&lt;IMG src="http://www.google.co.jp/intl/ja_jp/images/logo.gif"&gt;</td></tr>
<tr><th>insertorderedlist</th><td>&lt;OL&gt; &lt;LI&gt;Hello&lt;/LI&gt;&lt;/OL&gt;</td><td>&lt;ol&gt;&lt;li&gt;Hello&lt;/li&gt;&lt;/ol&gt;</td><td>&lt;ol&gt;&lt;li&gt;Hello&lt;/li&gt;&lt;/ol&gt;</td><td>&lt;ol id="undefined"&gt;&lt;li&gt;Hello&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;</td><td>&lt;OL&gt;&lt;LI&gt;Hello&lt;/LI&gt;&lt;/OL&gt;</td></tr>
<tr><th>insertunorderedlist</th><td>&lt;UL&gt; &lt;LI&gt;Hello&lt;/LI&gt;&lt;/UL&gt;</td><td>&lt;ul&gt;&lt;li&gt;Hello&lt;/li&gt;&lt;/ul&gt;</td><td>&lt;ul&gt;&lt;li&gt;Hello&lt;/li&gt;&lt;/ul&gt;</td><td>&lt;ul id="undefined"&gt;&lt;li&gt;Hello&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;</td><td>&lt;UL&gt;&lt;LI&gt;Hello&lt;/LI&gt;&lt;/UL&gt;</td></tr>
<tr><th>italic</th><td>&lt;EM&gt;Hello&lt;/EM&gt;</td><td>&lt;i&gt;Hello&lt;/i&gt;</td><td>&lt;span style="font-style: italic;"&gt;Hello&lt;/span&gt;</td><td>&lt;span class="Apple-style-span" style="font-style: italic;"&gt;Hello&lt;/span&gt;</td><td>&lt;I&gt;Hello&lt;/I&gt;</td></tr>
<tr><th>justifycenter</th><td>&lt;P align=center&gt;Hello&lt;/P&gt;</td><td>&lt;div align="center"&gt;Hello&lt;/div&gt;</td><td>&lt;div style="text-align: center;"&gt;Hello&lt;/div&gt;</td><td></td><td>&lt;DIV align="center"&gt;Hello&lt;/DIV&gt;</td></tr>
<tr><th>justifyfull</th><td>&lt;P align=justify&gt;Hello&lt;/P&gt;</td><td>&lt;div align="justify"&gt;Hello&lt;/div&gt;</td><td>&lt;div style="text-align: justify;"&gt;Hello&lt;/div&gt;</td><td></td><td>&lt;DIV align="justify"&gt;Hello&lt;/DIV&gt;</td></tr>
<tr><th>justifyleft</th><td>&lt;P align=left&gt;Hello&lt;/P&gt;</td><td>&lt;div align="left"&gt;Hello&lt;/div&gt;</td><td>&lt;div style="text-align: left;"&gt;Hello&lt;/div&gt;</td><td></td><td>&lt;DIV align="left"&gt;Hello&lt;/DIV&gt;</td></tr>
<tr><th>justifyright</th><td>&lt;P align=right&gt;Hello&lt;/P&gt;</td><td>&lt;div align="right"&gt;Hello&lt;/div&gt;</td><td>&lt;div style="text-align: right;"&gt;Hello&lt;/div&gt;</td><td></td><td>&lt;DIV align="right"&gt;Hello&lt;/DIV&gt;</td></tr>
<tr><th>strikethrough</th><td>&lt;STRIKE&gt;Hello&lt;/STRIKE&gt;</td><td>&lt;strike&gt;Hello&lt;/strike&gt;</td><td>&lt;span style="text-decoration: line-through;"&gt;Hello&lt;/span&gt;</td><td>&lt;span class="Apple-style-span" style="text-decoration: line-through;"&gt;Hello&lt;/span&gt;</td><td>&lt;STRIKE&gt;Hello&lt;/STRIKE&gt;</td></tr>
<tr><th>subscript</th><td>&lt;SUB&gt;Hello&lt;/SUB&gt;</td><td>&lt;sub&gt;Hello&lt;/sub&gt;</td><td>&lt;sub&gt;Hello&lt;/sub&gt;</td><td>&lt;span class="Apple-style-span" style="vertical-align: sub;"&gt;Hello&lt;/span&gt;</td><td>&lt;SUB&gt;Hello&lt;/SUB&gt;</td></tr>
<tr><th>superscript</th><td>&lt;SUP&gt;Hello&lt;/SUP&gt;</td><td>&lt;sup&gt;Hello&lt;/sup&gt;</td><td>&lt;sup&gt;Hello&lt;/sup&gt;</td><td>&lt;span class="Apple-style-span" style="vertical-align: super;"&gt;Hello&lt;/span&gt;</td><td>&lt;SUP&gt;Hello&lt;/SUP&gt;</td></tr>
<tr><th>underline</th><td>&lt;U&gt;Hello&lt;/U&gt;</td><td>&lt;u&gt;Hello&lt;/u&gt;</td><td>&lt;span style="text-decoration: underline;"&gt;Hello&lt;/span&gt;</td><td>&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;Hello&lt;/span&gt;</td><td>&lt;U&gt;Hello&lt;/U&gt;</td></tr>
</table>
</div>

<p>
 Firefoxでは、 execCommand で styleWithCSS を false にしてあげると、生成されるHTMLが、IE,Operaのものにより近くなります。<br/>
 デフォルトはtrueです。
</p>
<br/>
<br/>

<h1>4. 改行の違い</h1>
<p>
 IE6で改行を入力すると、なぜか2行分改行されているように見えます。<br/>
 これは、改行入力時には、&lt;br&gt;タグではなく、&lt;p&gt;&lt;/p&gt;タグが新たに挿入されるためです。
</p>
<br/>
<blockquote>
 ちなみに、&lt;p&gt;タグ内での改行では&lt;p&gt;が挿入されますし、&lt;div&gt;タグ内の改行なら&lt;div&gt;、&lt;h1&gt;タグ内なら&lt;h1&gt;といった具合に、カーソル位置の親のブロックエレメントタグが挿入されるようです。<br/>
 また、Shiftキーを押しながらEnterキーを押すと、&lt;br&gt;タグを挿入できます。
</blockquote>
<br/>
<p>
 幾つか対策方法を探してみました。

<ul>
 <li>スタイルシートで、pタグのmargin-top と margin-bottom に 0px を指定する。
   <p>これで見た目上の問題はなくなります。</p>

<div class="code">
 p { margin-top: 0px, margin-left:0px }
</div>

 </li>

 <li>独自に&lt;br&gt;タグを挿入し、イベント伝播を停止する。
  <p>
    どうしても&lt;br&gt;タグを使いたい場合には、この方法が良さそうです。<br/>
    下記のfunctionで、keydownイベントをリスンしておくようにします。<br/>

<div class="code">
// IE Only
function keydownHandler(e){
  // Handle Enter Key
  if( e.keyCode == 13 && !e.shiftKey){
    var range = document.selection.createRange();
    range.pasteHTML("&lt;br&gt;");
    e.returnValue = false;
    e.cancelBubble = true;
  }
}
</div>

    </p>
  </li>
</ul>
</p>
<br/>
<br/>

<h1>5. Range</h1>
<p>
 最後に、Range (TextRange)オブジェクトを紹介します。
 execCommandに定義されていない処理を行いたい場合など、何かと便利なオブジェクトです。

 <ul>
  <li><a href="http://msdn2.microsoft.com/en-us/library/ms535872.aspx">IE TextRange(英語) http://msdn2.microsoft.com/en-us/library/ms535872.aspx</a></li>
  <li><a href="http://developer.mozilla.org/ja/docs/DOM:range">Firefox Range(日本語) http://developer.mozilla.org/ja/docs/DOM:range</a></li>
  <li><a href="http://developer.mozilla.org/en/docs/DOM:range">Firefox Range(英語) http://developer.mozilla.org/en/docs/DOM:range</a></li>
 </ul>
</p>
<br/>
<p>
document上の現在のカーソル位置、もしくは、選択されている領域の、Rangeを取得します。
</p>

<div class="code">
// IE
var range = document.selection.createRange();

// IE以外
// 引数に0を指定しているので、先頭のRangeオブジェクトが取得されます。
var range = document.getSelection().getRangeAt(0);

// IE以外でiframeから取得する場合
var range = iframe.contentWindow.getSelection().getRangeAt(0);
</div>


<br/>
<br/>
<p>
 このRange(TextRange)オブジェクトを使うと色々なことができます。<br/>
 ここでは、クロスブラウザを意識した操作を幾つか紹介します。
</p>

<br/>
<ul>
<li>rangeの中に含まれるエレメントに対して共通の親エレメントを取得します。
<div class="code">
// IE
var parent = range.parentElement();

// IE以外
var parent = range.commonAncestorContainer;
</div>
</li>


<li>
 range同士の位置関係を比較します。
<div class="code">
// IE
// targetRange が baserangeより右
(baseRange.compareEndPoints('StartToStart', targetRange) <=0)
// targetRange が baserangeより左
(baseRange.compareEndPoints('EndToEnd', targetRange) >= 0)

// IE以外
// targetRange が baserangeより右
(baseRange.compareBoundaryPoints(Range.START_TO_START, targetRange) <=0)
// targetRange が baserangeより左
(baseRange.compareBoundaryPoints(Range.END_TO_END, targetRange) >=0)
</div>
</li>

<li>
 rangeの始点、終点を、特定のエレメントの位置に移動させます。
<div class="code">
// IE
var startElm = document.getElementById('elm1');
var endElm = document.getElementById('elm2');
var dstRange = document.body.createTextRange();
dstRange.moveToElementText(startElm);
range.setEndPoint( 'StartToStart', dstRange);
dstRange.moveToElementText(endElm);
range.setEndPoint( 'EndToEnd', dstRange );

// IE以外
var startElm = document.getElementById('elm1');
var endElm = document.getElementById('elm2');
range.setStartBefore(startElm);
range.setEndAfter(endElm);
</div>
</li>

<li>
 rangeからHTML文字列を取得します。
<div class="code">
// IE
var html = range.htmlText;

// IE以外
var df = range.cloneContents();
var doc = range.startContainer.ownerDocument;
var div = doc.createElement('div');
div.appendChild(df);
var html = div.innerHTML;
</div>
</li>

<li>
 rangeの位置にHTML文字列を挿入します。
<div class="code">
// IE
var html = '&lt;p&gt;Hello&lt;/p&gt;';
range.pasteHTML( html );

// IE以外 
var html = '&lt;p&gt;Hello&lt;/p&gt;';
document.execCommand('inserthtml', false, html);  // これrange関係ないけど =)
</div>
</li>
</ul>


<br/>
<p>
とりあえずここまで。<br/><br/>

最後に。<br/>
間違ってたらごめんなさい。
</p>
]]>
      
   </content>
</entry>
<entry>
   <title>Javascript 安全なコンストラクタ</title>
   <link rel="alternate" type="text/html" href="http://www.fourmeisters.com/blog/yoshi/2007/07/javascript_1.html" />
   <id>tag:www.fourmeisters.com,2007:/blog/yoshi//1.59</id>
   
   <published>2007-07-20T23:00:00Z</published>
   <updated>2007-07-20T23:00:02Z</updated>
   
   <summary>Javascriptのthisについて。 thisは、呼び出し元のオブジェクトを...</summary>
   <author>
      <name>yoshi</name>
      
   </author>
         <category term="javascript" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.fourmeisters.com/blog/yoshi/">
      <![CDATA[<h2>Javascriptのthisについて。</h2>
thisは、呼び出し元のオブジェクトを参照します。<br/>
<textarea id="cp_yoshi_20070721_1" class="codepress javascript readonly-on" rows="6">
var myObject = {
  toString : function(){ return 'myObject' },
  alertThis : function(){ alert( this.toString() ); }
};
myObject.alertThis();  // myObject
</textarea>
<div class="pre_footer">
  <a onclick="javascript:eval(cp_yoshi_20070721_1.getCode());">実行</a>
</div>

<h2>オブジェクトの外ではどうか。</h2>
thisは厳密にはコンテキストオブジェクトを参照します。 <br/>
(詳しい解説は<a href="http://developer.mozilla.org/ja/docs/Core_JavaScript_1.5_Reference:Operators:Special_Operators:this_Operator">this Operator</a>を参照してください)
オブジェクトのメソッド以外でthisを参照すると、グローバルオブジェクトであるwindowオブジェクトを参照できます。 <br/>
<textarea id="cp_yoshi_20070721_2" class="codepress javascript readonly-on" rows="2">
alert( (this == window) );  // true
</textarea>
<div class="pre_footer">
  <a onclick="javascript:var f=function(){eval(cp_yoshi_20070721_2.getCode());};f.call(window);">実行</a>
</div>

<h2>コンストラクタのthis</h2>
new演算子を使用すると、生成されるインスタンスがthisになります。<br/>
thisに値をセットしておけば、生成後のインスタンスから値を参照することができます。<br/>
<textarea id="cp_yoshi_20070721_3" class="codepress javascript readonly-on" rows="6">
var Book = function(title){
  this.title = title;
};
var book1 = new Book('竜馬がゆく');
alert( book1.title );  // 竜馬がゆく
</textarea>
<div class="pre_footer">
  <a onclick="javascript:eval(cp_yoshi_20070721_3.getCode());">実行</a>
</div>

<h2>何が問題か？</h2>
あ゛new忘れた<br/>
<textarea id="cp_yoshi_20070721_4" class="codepress javascript readonly-on" rows="11">
var Book = function(title){
  this.title = title;
};
var book2 = Book('壬生義士伝');
try{
  alert( book2.title );   // error
} catch(e) {
  alert( "[ERROR]" + e.description );
}
alert( window.title );  // 壬生義士伝
</textarea>
<div class="pre_footer">
  <a onclick="javascript:eval(cp_yoshi_20070721_4.getCode());">実行</a>
</div>
この場合、値を参照するとエラーになります。<br/>
しかも、値は関数内のコンテキストオブジェクトにセットされてしまいます。<br/>

<h2>安全なコンストラクタ</h2>
関数が定義されているオブジェクトとthisが同じであれば、newするようにします。<br/>
<textarea id="cp_yoshi_20070721_5" class="codepress javascript readonly-on" rows="11">
var Dog = function(name){
  if( this == window )
    return new Dog(name);
  this.name = name;
}
var dog1 = new Dog('ジャック');
var dog2 = Dog('ポール');
alert( dog1.name );
alert( dog2.name );
</textarea>
<div class="pre_footer">
  <a onclick="javascript:eval(cp_yoshi_20070721_5.getCode());">実行</a>
</div>
これで安心してnew<del>の存在</del>を忘れられる･･･<br/>

]]>
      
   </content>
</entry>
<entry>
   <title>CodePress - シンタックスハイライト</title>
   <link rel="alternate" type="text/html" href="http://www.fourmeisters.com/blog/yoshi/2007/07/codepress.html" />
   <id>tag:www.fourmeisters.com,2007:/blog/yoshi//1.51</id>
   
   <published>2007-07-11T02:00:00Z</published>
   <updated>2007-07-11T02:07:32Z</updated>
   
   <summary>掲載するソースコードを、シンタックスハイライトして表示するために、CodePre...</summary>
   <author>
      <name>yoshi</name>
      
   </author>
         <category term="javascript" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.fourmeisters.com/blog/yoshi/">
      <![CDATA[掲載するソースコードを、シンタックスハイライトして表示するために、<a href="http://www.codepress.org/">CodePress</a>を用いてみました。

<h2>使い方</h2>
スクリプトをロードして、textareaのclassにcodepressを追加します。
textareaのclaasにはさらに、使用する言語を指定します。
javascriptやhtml, java, ruby等に対応しているようです。
<pre>
&lt;script src="/codepress/codepress.js" type="text/javascript"&gt;&lt;/script&gt;
 ....
&lt;textarea id="ThisIdmustBeUnique" class="codepress javascript"&gt;
   javascriptのコード
&lt;/textarea&gt;
</pre>

<h2>試行</h2>
以下のJavascriptコードで試してみます。
<pre>
// Syntax Highlight Sample...
var f =function(){
  alert('test');
};
f();
</pre>
CodePress適用<br/>
<textarea id="cp_yoshi_20070711_1" class="codepress javascript readonly-on" rows="6" style="width:500px;">
// Syntax Highlight Sample...
var f =function(){
  alert('test');
};
f();
</textarea>

見た目も綺麗でいい感じ。

<h2>動作 (v.0.9.5)</h2>
適用対象の位置に、iframeを追加し、その中でcodepress.htmlを読み込んでいます。
codepress.htmlでは、必要なスクリプトとスタイルシートを読み込み、さらに適用対象の中身をロードして表示しています。 

<h2>Movable Type での使用</h2>
CodePressでは、(textareaの)idが必須であり、他のエレメントのidと重複すると、Javascriptエラーがおきます。
(この辺りはブラウザによっても挙動が変わるようですが…)

Movable Type で使用する場合、検索やアーカイブなどの画面で、他のブログ、エントリが表示されるので、idがユニークになるように注意しておく必要があります。
]]>
      
   </content>
</entry>
<entry>
   <title>背景画像をランダムに変更する</title>
   <link rel="alternate" type="text/html" href="http://www.fourmeisters.com/blog/yoshi/2007/07/post.html" />
   <id>tag:www.fourmeisters.com,2007:/blog/yoshi//1.34</id>
   
   <published>2007-07-02T21:57:28Z</published>
   <updated>2007-07-03T01:06:55Z</updated>
   
   <summary>個人的に最近ホットなjavascriptライブラリ。jQuery。 昨日、新しい...</summary>
   <author>
      <name>yoshi</name>
      
   </author>
         <category term="javascript" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="9" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="8" label="jquery" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.fourmeisters.com/blog/yoshi/">
      <![CDATA[個人的に最近ホットなjavascriptライブラリ。jQuery。
昨日、新しいバージョンが出たのでお試しも兼ねて、このサイトに導入してみました。

画面上部の画像はランダムに移り変わります。

<pre id="moveLogo">

  var x = -parseInt( Math.random() * 500 );
  var y = -parseInt( Math.random() * 200 );
  $('#banner').css('background-position',x+'px '+y+'px');

</pre>
<div class="pre_footer" style="text-align:right;">
  <a onclick="javascript:eval($('#moveLogo').text());">実行</a>
</div>

この写真は三浦海岸の夕暮れ時です。
限られた枠から見る自然というのも、以外と面白い。
]]>
      
   </content>
</entry>

</feed>
