LineNumberWriter – syntaxhighlighter風のJavaScriptを書いてみた

最近いろんなところで見かけるようになったsyntaxhighlighter.js。文法が分かりやすいようにコードがカラーリングされ、行番号が付いてとてもコードが見やすいです。導入を検討しようかと思ったのですが、(X)HTML的に文法違反になるのは許せないなーと思い、違った形のものをJavaScriptで書いてみました。当サイトに導入済みです。次のような見た目になります。

function sample() {
alert("sample");
}

ただし、私が作ったのはSyntaxHighlighterではありません。行番号が付き1行おきに背景色が付くだけのものです。syntaxはhighlightされません。よって、SyntaxHighlighterとは名乗れないので、LineNumberWriterと名乗ることにします(これ、果たして妥当な英語なんでしょうか・・・)。

もし使ってみたいという方がおりましたらご自由に使ってみてくださいまし。下記リンクからzipファイルでダウンロードできます。

linenumberlighter Ver.0.4.1

勢いで作ったものなので、バージョンは0.1ということにします。それから一応、ライセンスはMITライセンスとしておきますね。(2008年4月5日追記)更新履歴を付けるようにしました。

Continue reading

[IE6]ブロック要素を中央寄せにするために、text-alignを使う件

ブロック要素を中央寄せにレイアウトする場合、左右marginをautoに設定するのが正しいCSSの書き方ですが、IE6の過去互換モードではこれが正しく動作しないのは有名です。

スクリーンショット:text-align:centerを使わずに中央寄せしようとすると

そこで、IEのために親ボックスにtext-align:centerを適用し、中央寄せにするというバッドノウハウと呼べなくもないテクニックが当たり前のように使われています。

text-alignプロパティは継承されますから、親ボックスにtext-align:centerを設定した場合、子孫ボックスではtext-align:leftと改めて設定して値を上書きすることがほとんどです。このtext-alignの上書きが面倒なのはもちろんですが、意図しない子孫要素にまで影響が及んでしまうので、できるならこのテクニックは使いたくないなー、というのが私の考えです。そこで、text-align:centerを使わずになんとかしようというアイデアをご紹介します。

親ボックスが div#wrapper で幅400px、中央寄せにしたい子ボックスが div#content で幅300pxという例でコードを考えていきます。次のコードは、text-align:centerを使った一般的なものです。

div#wrapper {
width: 400px;
text-align: center;
}
div#content {
width: 300px;
margin: 0 auto;
text-align: left;
}

これを以下のようにすることで、text-align:centerを使わずに、同じ表現をすることができます。

div#wrapper {
width: 400px;
}
div#content {
width: 300px;
margin: 0 auto 0 50px;
}

実際に中央寄せにした場合に左右に空くmarginを計算し、子ボックスの左marginに設定してやり、右marginはautoにします。これで、text-align:leftのまま、主要なブラウザ全てで中央寄せを実現できます。
このコードをIE6の互換モードで表示したのが、次のスクリーンショットです。(実際は見やすくするためにbackground-colorpaddingも併用しています)

スクリーンショット:text-align:centerを使わずに中央寄せ

ただし、弱点もあります。親ボックスが幅固定のレイアウトに限って有効なテクニックなので、リキッドレイアウトやエラスティックレイアウトでは使えないのはもちろん、body要素が直接含むボックスには使えない(body要素はウィンドウサイズによって幅が変わるため)という点です。
幅固定レイアウトでは絶大な(?)威力を発揮します。

ちょっとしたCSSのアイデアなのですが、あまり使ってる人見かけないな?と思ったのでご紹介しようと思いました。

JavaScriptのオブジェクトシステムについての、現時点での私の理解

JavaScriptでは全てのデータをオブジェクトで表現できる

通常はリテラル(スクリプト文中に直接データを書き込んだもの)で表現するデータを、JavaScriptではオブジェクトとしても表現できるようになっています。(厳密にはリテラルで書いたデータとオブジェクトで書いたデータは異なるものですが、その説明は省略)

リテラルで表現した場合と、オブジェクトとして表現した場合の比較
  リテラルで表現した場合 オブジェクトとして表現した場合
数値 100 new Number(100)
文字列 "fuga" new String("fuga")
真偽値 true new Boolean(true)
配列 ["foo","bar"] new Array("foo","bar")
正規表現 /fuga/ new RegExp("fuga")
オブジェクト {} new Object()
関数 function(foo) {alert(foo)} new Function("foo","alert(foo)")

プロパティについて

オブジェクトはその内部にプロパティを持つことができます。オブジェクト名とプロパティ名をドットで繋げることプロパティを呼び出せます。
例えば Array オブジェクトは length というプロパティを持ち、オブジェクト名.lengthとすることで、この配列オブジェクトの持つ要素の数を取り出すことができます。

var hoge = new Array("foo","bar");
alert(hoge.length) // 2 が表示される

length のようなものは Array オブジェクトに最初から組み込まれているプロパティなので、特に自分で定義しなくてもいきなり使うことができます。もちろん自分でプロパティを作ることもできます。

プロパティを作るには、作成したオブジェクトに .(ドット)を付けてプロパティを定義します。

var hoge = {};
hoge.x = 100;
alert(hoge.x); // 100 が表示される

もしくは、オブジェクトを作成する際にオブジェクトリテラル形式で定義します。

var fuga = {x: 100, y: 50}
alert(fuga.x + fuga.y); // 150 が表示される

コンストラクタとインスタンス

「オブジェクトで表現した」場合、new XXX()という文になりますがこれはXXX()というコンストラクタから新たなオブジェクトを作る、という意味となります。コンストラクタとは新たなオブジェクトを作る雛形のようなものであり、コンストラクタから作られたオブジェクトをインスタンスと呼びます。

JavaScriptでは関数をコンストラクタとして使うことができます。関数を定義する際、this.XXXという書き方でプロパティを定義しておくと、そのプロパティはインスタンスにも引き継がれます。

// hoge()コンストラクタを作成
// hoge()のプロパティとして x=100 を定義
function hoge() {this.x = 100;}
// hoge()コンストラクタからfugaオブジェクトを作る
// fugaオブジェクトはhoge()コンストラクタのインスタンスとなる
var fuga = new hoge()
// hoge()コンストラクタから x=100 プロパティが
// 継承されているので 100 が表示される
alert(fuga.x)

今回はこの辺までで。
prototypeチェーンについてはまだ勉強中・・・。

Continue reading

Unicodeでのバックスラッシュと¥の違い

とても恥ずかしいのですが、今さらバックスラッシュと¥の違いを身をもって体験しました。MacIE対策でバックスラッシュハックを使おうとして、ハマってしまったのです。

調べてみると、色々なことが分かりました。

  • Mac環境のUTF-8では、バックスラッシュは¥とは違う扱いになる。
  • Unicodeで書く場合、Windows環境だと¥はバックスラッシュに変換されるが、Mac環境では変換されず、¥は¥マークとして扱われる。
  • Osakaフォントなどで表示していると、¥もバックスラッシュも同じ「¥」表示になるため、見分けがつかない。(「Courier」フォントなどで表示すると見分けがつく)
  • Mac環境でバックスラッシュを入力するには、日本語入力の状態で「Option + ¥」。

Mac環境でバックスラッシュだと思って¥を入力しておくと、バックスラッシュハックなんかが効かなくなります。UTF-8でサイトを作っている時は要注意ですね。。

ちなみにHTML文書で¥を表示させたい場合は実態参照で¥です。

参考
UTF-8のバックスラッシュは¥ではない (kakitomeru note)
バックスラッシュ問題@MacOSX@KADOYAN.com
Dreamweaver8ハマりどころ 06.09.01 – Memo:hbworks
円記号 – Wikipedia
バックスラッシュ – Wikipedia
日本語環境でのUnicodeの諸問題 | Unicode – Wikipedia

『Javascript で HTMLエスケープを行うPHP関数、htmlspecialchars を実装』に一行追加

phpspot開発日誌さんJavascript で HTMLエスケープを行うPHP関数、htmlspecialchars を実装で紹介されているコードを使ってみたところ、不満な点が出てきたのでちょっぴり改良して使っています。

不満な点とは、既に「&」となっているコードを放り込むと、「&」と二重変換されてしまう点。改良後のコードは以下です。

function htmlspecialchars(ch) {
ch = ch.replace(/&/g,"&");
ch = ch.replace(/&/g,"&");
ch = ch.replace(/"/g,""");
ch = ch.replace(/'/g,"'");
ch = ch.replace(/</g,"&lt;");
ch = ch.replace(/>/g,"&gt;");
return ch;
}

追加したのは3行目。二重変換されちゃったものは元に戻すという、それだけです。