[ カテゴリー » 開発日誌 ]

UNIXタイムスタンプからハッシュ生成

category-icon

 ppBlogバージョン1.7.7から採用している機能のひとつに、コメント通知のメールからダイレクトでログイン出来てコメント返信できるというのがあります。その際に、リンクのURLに付加する文字列が今いちランダムになっていないので、ちょっとアルゴリズムの見直しをしてみました。時限性を持たせるために、UNIXのタイムスタンプから生成したハッシュをリンクのURLに付加しているのですが、タイムスタンプをチェックしたいので、復元可能なものであることが必要です(一方向で良ければ、sha1関数Link を使えば良いけどニーズに合わない)。

 単純に、UNIXのタイムスタンプをppBlogで用意している暗号化関数my_encrypt()に通すと、タイムスタンプの性質上、最後数桁しか変化せず、それに対応して生成されたハッシュも下数桁しか変化しません。まぁ、これはmy_encrypt()の性能の問題なんですが、この部分はそんな高性能でなくてよいし、過去の資産との互換性も考えると my_encrypt()はいじりたくないです。

$unix_time1 = 1234560000; // 10桁のUNIXタイムスタンプ
$unix_time2 = 1234567890; // 上と下4桁が違うだけ
echo my_encrypt($unix_time1); // 結果は、VwoLV1MOAwhVBg
echo my_encrypt($unix_time2); // 結果は、VwoLV1MOBABcBg

こんな感じでえらく似通った文字列になる(--) なので、このタイムスタンプを逆順にして更に基数変換すればよいかなと。逆順にすれば、大きく数値が変動します。そこで、文字列を逆順にする関数はないかstr_reverseという関数名で探してみましたがなさそうです。なので、

$unix_time_reverse = join("", array_reverse(preg_split("//", time())));

という力技で暫くローカルのテスト環境で動かしていたんですが、いやきっとあるはずだと、もう一度マニュアルを探してみたらありました。

$unix_time_reverse = strrev(time());

strrevLink という名前でしたか・・・。

 実は、単に逆順にしただけでは、my_encrypt()のアルゴリズムからしてそう大きな変化は望めないので、更に base_convert()Link 関数を利用して10進数から2進数に変換します。decbinLink でも行けるかなと思ったんですが、扱える最大の数が10 進数の4294967295とのことで、これは使えない。

$unix_time_binary = base_convert(strrev(time()), 10, 2); // 10進数を2進数に変換

 これで最初に挙げた例だと、

$encoded1 = my_encrypt(base_convert(strrev("1234560000"), 10, 2));
 // 結果は、VwgIUlcJAglUBgEJU1RUUgdRVAk
$encoded2 =  my_encrypt(base_convert(strrev("1234567890"), 10, 2));
 // 結果は、VwkJU1cIAglVBwEJU1VVUgZRVQgJVgIEVFcGAwhT
$encoded3 =  my_encrypt(base_convert(strrev("1235064688"), 10, 2)); // 別の例
 // 結果は、VwgIU1YJAwhVBgAJUlRUUgZQVAgIVgMFVVYHAwhSUAdWCQ

まぁ、最初に比べるとだいぶマシかなと思います。さて、この復元ですが、逆の操作をするだけです。

$decoded = strrev(sprintf("%010s", base_convert(my_decrypt($encoded1), 2, 10)));
 // この場合は、1234560000 を返す

これで、元の10桁のタイムスタンプを取得できます。ひとつ注意する点は、順序を逆にした文字列を戻す際に、元のタイムスタンプによっては逆順にした文字列の先頭がゼロになる場合があるということです(上の例だと反転した0000654321654321と解釈される)。なので、sprintfLink 関数を用いて、ゼロで10桁になるように埋め合わせをしておきます。

sprintf("%010s", "654321"); // この結果は、0000654321

 実際の実装(?)としては、これらとsha1関数を組み合わせたりして、長い文字列を生成してます。

— posted by martin at 02:52 am   commentComment [0]  pingTrackBack [0]

 

動的スタイルシートの作成

category-icon

 こんばんは。だいぶ日も長くなってきましたね。

 さて、小生のブログで、「エクセルデータをHTMLテーブルに変換」というエントリーを書いて、そこでppBlog用に見栄えの良いTABLEを作成してくれるページLink を公開していました。早速、使って下さったユーザーの方から、ppBlogをリスト表示にしていると、テーブルのスタイルシートが有効になっていないとのご指摘がありました。確かに、リスト表示での個別スタイルシート指定はすっかり対応を忘れていました。

 というわけで、ppBlogでは記事毎にスタイルシートやJavaScriptを指定することが可能ですが、あまり知られていない気もするので簡単に使い方を書いておきます。スタイルシート(CSS)を指定したければ、記事のどこでも良いので、[style][/style]で囲った中の記述がCSSとして認識されます。記述はまんまCSSと同じです。具体例を挙げると以下のような感じ。

[style]
.article-content table { border-color: tomato; }
[/style]

とか。.article-contentは、記事内容要素に対するクラス名です。記事の個別表示のときは、記事ボックスはひとつしかないので問題ありませんが、複数の記事が表示されている場合、上の例だと、別の記事にテーブルが含まれていたら(クラス名が同じため)そこにも反映されてしまいます。なので、これを回避するには、指定したい記事の固有IDを利用すると良いです。ppBlogでは、すべての記事にUID1234567890のようなIDが割り振られます。

[style]
#UID1234567890 .article-content table {
  border-color: tomato; /* IDを利用して適応先の .article-content を絞り込む */
} 
[/style]

追記 2009/02/19 18:56:29 考えてみると、このUIDを付加する作業は、ppBlogの方で自動的にやるべきかなぁ。次バージョンではそうしようと思います。

 記事ごとのJavaScript指定も同じように、[script][/script]で囲った中に記述すればOKです。

[script]
alert("Bonjour, tout le monde!"); /* 普通にJavaScriptを記述 */
[/script]

 前置きが長くなりましたが、本題。最初に挙げたリンク先Link のソースを見れば分かりますが、動的にスタイル指定を適応させる処理を入れています。同じような処理は、ppBlogで使っているソースハイライト表示用のsyntax.jsLink でも使っていますが、ここでは、上記エクセルコピペのテーブル変換の部分を抜粋してみます。

var sheet = d.styleSheets && d.styleSheets[0]; /* 最初のスタイルシートを取得 */

var rulesCSS = { /* JSON形式で要素毎のスタイルを指定 */
  'table' : 'border: solid 1px gray; margin: 2em auto; border-collapse: collapse;',
  'table td' : 'border: solid 1px gray; padding: 2px; text-align: right;',
  'table th' : 'border: solid 1px gray; padding: 2px; text-align: center;',
  'thead tr th' : 'background: #eeffff;',
  'tbody tr th' : 'background: #ffeeee;'
};

for (var el in rulesCSS){
 if(sheet.addRule){ /* IE 向け */
  sheet.addRule(el, rulesCSS[el]);
 } else {  /* Firefox, Safari, Opera 向け */
  sheet.insertRule(el + '{' + rulesCSS[el] + '}', sheet.cssRules.length);
 }
}

 このように、予めJSON配列などに適応させたいCSSを記述している時は、こんな感じで動的に変更させることが出来るのですが、「普通のCSSの記述」つまり

<style type="text/css">
  table { border: solid 1px gray; margin: 2em auto; border-collapse: collapse; }
  table td { border: solid 1px gray; padding: 2px; text-align: right; }
  table th { border: solid 1px gray; padding: 2px; text-align: center; }
  thead tr th { background: #eeffff; }
  tbody tr th { background: #ffeeee; }
</style>

を、このまま適応させたいときもあると思います。ppBlogでは、リスト表示モードというのがあり、記事の読み込みにはAjaxを活用しています。この際に、最初の方で紹介した、記事ごとのCSS記述があると、まさにこんな感じで、テキストとしてCSSの記述も読み込みます。で、それを処理するのを忘れていました、という最初の話に戻るのですが、その辺の処理は以下のようにしてみました。lib.jsの256行目あたりからの部分ですが、IEとMozilla系で処理が違うので条件付きコンパイルを使っています。

if(!o("#css4list")){ /* ID#css4list を持つオブジェクトがなければ */
 oParts.create("style#css4list", null, o("head")); /* ID名css4listを持つSTYLE要素をHEAD要素の子要素として追加 */
 newCSS = o("#css4list").$; /* HTMLStyleElementオブジェクトの取得 */
 newCSS.type = "text/css";
} else newCSS = o("#css4list").$;
 /*@cc_on @*//*@if(1) newCSS.styeSheet.cssText = css[1]; @else@*/
 newCSS.textContent = ""; /* 前に適応させたCSSをクリア */
 newCSS.appendChild(d.createTextNode(css[1])); /* 新たにCSSを設定 */
/*@end@*/

 リストモードでは記事は常にひとつしか表示されないので、ひとつ動的スタイルシート用のHTMLStyleElementを用意しておけば十分です。IEとMozilla系では、そこから先の処理が違います。IEでは、スタイルシートオブジェクトから操作。

HTMLStyleElement.styleSheet.cssText = (先に挙げたような素のCSSテキスト);

 Mozilla系では、DOMオブジェクトとして操作。

HTMLStyleElement.appendChild(document.createTextNode(先に挙げたような素のCSSテキスト));

 複数行にわたるCSSテキストを一気に適応させたいときは、こんな感じでしょうか。

ちなみに、[object HTMLStyleElement]から[object CSSStyleSheet]にアクセス?する際もIEとMozilla系では違いますね。IE8では、だいぶ歩み寄りが見られたような気もするけど。

[object HTMLStyleElement].styleSheet = [object CSSStyleSheet] /* IE */
[object HTMLStyleElement].sheet = [object CSSStyleSheet] /* Mozilla */

なので上のスクリプトの例では、IEの処理部分は以下のように書いても同じです。

document.styleSheets[document.styleSheets.length - 1].cssText = css[1];

つまり

newCSS.styleSheet == document.styleSheets[document.styleSheets.length - 1];

まぁこんなとこですかねぇ。そろそろアップデートせねば。。


— posted by martin at 11:48 am   commentComment [12]  pingTrackBack [0]

IE8βでもVMLを使えるように

category-icon

 こんばんは。Windows 7βを試用中ですが、写真をお洒落に見せるスクリプトLink (photoeffect.js)が、IE8βでエラーとなり意図した効果が得られないのを発見。調べてみると、IE8ベータがVMLをサポートしていないのが原因っぽいです。おそらく、正式版ではVMLはサポートされるとは思いますが、確証はないので(Silverlightとかあるし)、現時点での回避策を考えてみました。

 IE8には、3つのレンダリングモードがあり、(紆余曲折ありましたが)デフォルトではフル標準モードでレンダリングされます。じゃ、どんな時にQuirksモード(後方互換[1]の非標準モード)になるかというと、以下の場合です。

  1. 文書中に DOCTYPE宣言がない場合
  2. 文書型が HTML3.0以下の場合
  3. HTML4.0 TransitionalまたはFramesetのDOCTYPE宣言にURLを含まない場合

の3つです。詳しくは、SummerWind - IE8のレンダリングモードに関するまとめLink あたりを参照。

 今どきのブログシステムでは、これらに該当しない可能性が高く、IE8は標準モードで動きます。なので(少なくとも現時点では)VMLのスクリプトが動かないわけです。じゃ、どうするか? 簡単そうなのは、METAスイッチGを使うこと。とりあえずVMLはIE7モードでは問題なく作動するので、以下のようなmetaタグをwebページに追加すれば良いです。

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

 確かに、これは簡単だし現実的な解決法ですが、こうしちゃうと、JavaScriptもIE7モードになっちゃいます。IE8では、querySelectorAllなどのSelectors APIやらDOMオブジェクトに対するgetter/setter APILink など、面白そうなAPIがサポートされるのに、IE7モードで走らせると、それらが使えません。

 出来れば、IE8モードのままでVMLも有効にしたいです。こんなときに使えるのが、インラインフレーム<iframe>。最近、ちっとも更新されていないのが気がかりな Dean EdwardsのエントリーLink が参考になります。

 つまり、IE8なページの中で、sandbox化されたIE後方互換の環境を構築し、その中でVMLを走らせるわけです。実際のデモを見たほうが早いと思うので、IE8βでアクセスしてみて下さい。IE7でも動きます。

  → http://p2b.jp/demo/vml-IE8.htmlLink

 IE8やIE7では、どう見えるかイメージショットも載せておきます。

IE8-VML
画像の回転も簡単に出来る。

 ここでは、単に画像を出力させるVMLを、以下のように関数化しています。

function vmlImg(src, w, h, r){
 /*
 @src: 画像ファイルを指定 
 @  w: 表示させる横幅
 @  h: 縦幅
 @  r: 回転角度(オプション)、-360~360
 */
 var ifr = document.createElement("iframe");
 ifr.marginWidth= "0"; ifr.marginHeight= "0";
 ifr.scrolling = "no"; ifr.frameBorder = "0";
 ifr.style.width = w + "px"; ifr.style.height = h + "px";
 
 document.body.appendChild(ifr);
 var idoc = ifr.contentWindow.document;
 idoc.write(""); idoc.close(); // これがないと document.body は null になる
 if(idoc.namespaces){
  if(!idoc.namespaces.v){
   idoc.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML" );
  }
 }
 idoc.body.style.backgroundColor = document.body.currentStyle.backgroundColor;
 var img = idoc.createElement('<v:image src="'+ src +'" />');
 var imgcss = img.style;
 imgcss.width = w + "px"; imgcss.height = h + "px";
 if(r){
  imgcss.rotation = r;
  ifr.style.width = 2 * w + "px"; ifr.style.height = 2 * h + "px";
 }
 idoc.body.appendChild(img);
}

 IE8版ではVMLが正式にサポートされるのを期待して、深追いはしません。

  • [1] 言葉の問題なので、本文とは関係ないですが、前方互換なのか後方互換なのか、上位互換なのか下位互換なのか訳わかめ。視点をどこに置くかの差ですし。IE8から見て、IE7以下は過去のものだから、それらに対する互換性ということで、後方互換みたいに使いましたが、何か違うような。まぁ、言いたいことが分かれば良いのかなって。[^]

— posted by martin at 09:43 am   commentComment [0]  pingTrackBack [0]

BLOCKQUOTE要素とCITE要素をめぐる考察

category-icon

 大晦日に書いていた記事ですが、なかなか時間が取れずこんな時季になりました。瑞祥新春(ずいしょうしんしゅん) 2009。今年もよろしくお願いします。

 とりあえず、以下の点について、現時点での考えを自分なりに纏めてみました。

  1. BLOCKQUOTE要素とCITE要素のグループ化
  2. CSSによるCITE属性やTITLE属性抽出の問題点
  3. 引用ブックマークレットの活用
  4. 参考リンク

1. BLOCKQUOTE要素とCITE要素のグループ化

 昔から、BLOCKQUOTE要素とCITE要素をどう扱うかについては悩ましい問題です(個人的に)。さて、いきなりですが、ここで簡単なクイズをば。XHTML1.0 Strictの仕様に則ると仮定して、考えてみて下さい。

Q. 以下のXHTML文法の間違いを指摘せよ。

<blockquote
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="いのちの流れ">
 日夜 私の血管を流れる 同じ命の流れが
 この世界を流れ 旋律に合わせて踊る
</blockquote>

 一見すると、BLOCKQUOTE要素に用いられるCITE属性(validなURIのみ可)も適切ですし、TITLE属性も付いてます(これらは必須ではありませんが)。問題は、その引用文です。単なるテキストですが、ブロック要素の直下には、インラインであるテキストは置くことが出来ません。なので、ここは、

<blockquote
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="いのちの流れ">
 <p>日夜 私の血管を流れる 同じ命の流れが
 この世界を流れ 旋律に合わせて踊る</p>
</blockquote>

とP要素などのブロックレベルでテキストを囲む必要があります。では、次はどうでしょうか。

<blockquote
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="いのちの流れ">
<p>日夜 私の血管を流れる 同じ命の流れが
 この世界を流れ 旋律に合わせて踊る</p>
<cite>
 <a href="http://martin.p2b.jp/200812-stream-of-life.html">
 「生命潮流」より抜粋
 </a>
</cite>
</blockquote>

 現時点で、CITE属性に与えられたリンクを適切に処理するブラウザはないようなので(ケータイ除く)、読み手に分かりやすいように、CITE要素を使って、リンクを用意しました。先ず、ここで問題となるのが、BLOCKQUOTE要素の中にCITE要素を含めて良いのか? ですが、これは後で考えるとして、少なくとも、文法エラーではありません。問題は、CITE要素(≠属性)です。CITE要素はインラインレベルなので、これも、最初と同じように、P要素などで囲ってやる必要があります。CITE属性とCITE要素とは、全く別ものであることに留意して下さい。

<blockquote
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="いのちの流れ">
<p>日夜 私の血管を流れる 同じ命の流れが
 この世界を流れ 旋律に合わせて踊る</p>
<p><cite>
 <a href="http://martin.p2b.jp/200812-stream-of-life.html">
 「生命潮流」
 </a>
</cite>より抜粋</p>
</blockquote>

 では、先ほど述べた、BLOCKQUOTE要素の中のCITE要素の扱いですが、色んな意見があるようです。神崎氏は、「引用の方法」についてのセクションで次のように述べています。

引用の方法Link 」より抜粋

出典を示すcite要素の位置は、文法的には特に定められていません。ただし、この例のようにblockquote要素内で引用元を示すと、引用部分をコピー/ペーストする、あるいはスクリプトで引用部分を抽出するといった操作を行う時に、出典が不明にならないというメリットがあります。逆にcite要素を外に置くと、引用部分(blockquote)と出典を直接結びつける方法はなく、プログラムはその関係を単純に理解することはできません。要素をどこにおくべきか判断に迷う時は、どうやって利用されるのかを想像してみると、答えが出てくることがあります。

引用元: The Web KANZAKI: 強調,引用,グループ化,画像などの要素Link

神崎氏は、この実例として、以下のような引用を例示しています。

<p>次に、文学作品を引用する。</p>
<blockquote>
<p>吾輩は猫である。名前はまだない。…</p>
<p><cite>夏目漱石『吾輩は猫である』</cite></p>
</blockquote>
<p>この引用文を読んで、次の設問に答えなさい etc...</p>

引用元: 強調,引用,グループ化,画像などの要素 -- ごく簡単なHTMLの説明Link

 確かに、この場合は BLOCKQUOTE要素の属性であるCITE属性は使えません。出典がWeb上のリソースではないからです。[1]しかしながら、W3Cの定義によれば、BLOCKQUOTE要素は、(ブロックレベルの)引用のために準備されたものLink であって、それ以上の解釈をしないという立場に立てば、BLOCKQUOTE要素の中に、引用への参照を表すCITE要素を含めるのは、何となく落ち着きません。この辺りは、もはや各人の好みの問題ですし、どちらでも良い気もしますが、個人的にはBLOCKQUOTE要素の外にCITE要素を置きたい派です。その際に、神崎氏が懸念しているような 引用部分(blockquote)と出典を直接結びつける方法 を考慮するならば、BLOCKQUOTE要素とCITE要素をひとつのまとまりと見立てるために、更に外側からブロックレベルの要素でラップするというアイデアは悪くないと考えます。正に、神崎氏が同じページで述べている「グループ化Link 」をする訳です。DIV要素を使えば、上記『吾輩は猫である』は以下のように書けるでしょう。

<p>次に、文学作品を引用する。</p>
<div class="quote"> /* 引用に関するセクションのグループ化 */
<blockquote>
 <p>吾輩は猫である。名前はまだない。</p>
</blockquote>
<p><cite>夏目漱石『吾輩は猫である』</cite></p>
</div>          /* グループ化の終わり */
<p>この引用文を読んで、次の設問に答えなさい etc...</p>

 このグループ化の概念をもう少し推し進めて、定義型リストのDL要素Link を用いたグループ化を考えてみます。例えば、上の例は、以下のような感じになります。

/* DL要素を用いたグループ化 その1 */
<dl class="quote">
<dd>
 <blockquote>
  <p>吾輩は猫である。名前はまだない。</p>
 </blockquote>
</dd>
<dt><cite>夏目漱石『吾輩は猫である』</cite></dt>
</dl>

 引用文と、その参照元のセットを、一種の定義型リストと解釈するわけです。定義型リストは、通常は、項目と内容の2つの部分から成り立ち、DT要素に定義する語句を、DD要素にはその語句の説明を記述します。しかしながら、DL要素は、使い方が柔軟で、DD要素あるいはDT要素のいずれか1つ以上を含めばよく、DDとDTの順番は問いません。また、DD要素ひとつに対して、複数のDT要素を含めても良いです。DT要素はインラインレベルの要素のみを含むことが出来て、DD要素は子要素として、ブロックレベルの要素のみを許可します。なので、DD要素の中にBLOCKQUOTE要素が来るのは、何ら問題ありません。上の例では、DT要素がDD要素の後ろに来ていますが、勿論、よく見かけるような形式—DT先行型が好みであれば、以下のような記述になるでしょう。

/* DL要素を用いたグループ化 その2 */
<dl class="quote">
<dt><cite>夏目漱石『吾輩は猫である』</cite>より抜粋</dt>
<dd>
 <blockquote>
  <p>吾輩は猫である。名前はまだない。</p>
 </blockquote>
</dd>
</dl>

 上記例では、引用元は書籍ですが、web上のリソースからの引用であれば、例えば、最初の例を使うと以下のような感じです。読み手に分かりやすいように、DT要素を2箇所で使っています。

<dl class="quote">
<dt>「<cite>いのちの流れ</cite>」より抜粋</dt>
<dd><blockquote
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="生命潮流">
<p>日夜 私の血管を流れる 同じ命の流れが
 この世界を流れ 旋律に合わせて踊る</p>
</blockquote></dd>
<dt class="cite">
 引用元: <a href="http://martin.p2b.jp/200812-stream-of-life.html">
 PPBLOG: 生命潮流
 </a>
</dt>
</dl>

 後は、見栄えを良くするために、これらDL要素などの振る舞いをスタイルシートで指定すればOKです。実際のサンプルは以下。

いのちの流れ」より抜粋

日夜 私の血管を流れる 同じ命の流れが
この世界を流れ 旋律に合わせて踊る

引用元: PPBLOG: 生命潮流 Link

 グループ化している点でHTMLパーサーにも分かりやすく(多分)、また読み手にとっても分かりやすいと思います。また、グループ化のメリットとして、スタイルシートでのデザインが容易くなることが挙げられます。このサイトで使っているBLOCKQUOTEに対するスタイルシートは、以下のようになっています(テーマBasicの場合)。

dl.quote {
  width: 86%;
  background: #fffafa;
  border: solid 1px #aaa;
  margin: 2em auto; padding: 0;
}
dl.quote dt{ padding: 5px 0 0px 10px;}
dl.quote dt cite { font-weight: 600; color: #556b2f; }
blockquote {
  font: 103%/1.7 "メイリオ", "Trebuchet MS", sans-serif;
  color: #484a47;
  margin: 0px auto;
  padding: 15px 15px 15px 48px;
  background: url(Images/quote.png) -5px -5px no-repeat; /* 引用の画像を左上に */
}

 ここでは、BLOCKQUOTE要素の背景に、引用符の画像を固定させていますが、DL要素の背景に、左上の引用符の画像を指定して、BLOCKQUOTE要素の右下にも引用符画像を用意すると以下のような感じになります。

ロマ書 5章3-5節Link より

[...] More than that, we rejoice in our sufferings, knowing that suffering produces endurance, and endurance produces character, and character produces hope, and hope does not disappoint us, [...]

 これに対するスタイルシートは、以下のような感じです。

dl.quote {
  width: 360px;
  background: #fff;
  border: double 4px #2e8b57;
  margin: 2em auto;
}
dl.quote dt {
  padding: 6px 0 0 9px;
}
dl.quote dd {
  background: url(Images/quote-left.png) left top no-repeat;
}
dl.quote blockquote {
  color: #484a47;
  font: italic 105% "Trebuchet MS", sans-serif;
  margin: .7em auto 1em auto;
  padding : 1em 20px 1em 50px;
  background: url(Images/quote-right.png) 97% bottom no-repeat;
}

 この指定では、右下の引用符画像が、BLOCKQUOTEのサイズに応じて、適切な位置に納まるのがポイントでしょうか。これを、グループ化せずに、BLOCKQUOTE要素のみで実現しようとすると、そう簡単には行かないのではないかと思います。[2]

2. CSSによるCITE属性やTITLE属性抽出の問題点

 さて、これまで、BLOCKQUOTE要素とCITE要素のグループ化およびそのメリットについて述べてきました。中には、BLOCKQUOTE要素のCITE属性があるのに、わざわざCITE要素も持ち出して冗長だと感じる方もいるでしょう。しかしながら、前述したように、CITE要素とCITE属性は全く別物です。でも、時々、その中身がほぼ同じという時もあるでしょう。そういう場合は、後述するCSSの指定で、比較的簡単にCITE属性やTITLE属性を抜き出して、読み手に「見せる」ことが可能です。以下に実例を挙げます(IE6,7以外のブラウザでしか意図したように振る舞いません)。

日夜 私の血管を流れる 同じ命の流れが
この世界を流れ 旋律に合わせて踊る

 IE6,7ユーザーの方に、Firefox3.0.5でのスクリーンショットを載せておきます。

Firefox3.0.5-Shot
Firefox3.0.5での見え方

 引用符の画像があって若干見づらいですが、ポイントはそこではなくて、「生命潮流」やら引用元のURIが表示されていることです。IE6,7ユーザー以外の方は、表示されているURL文字列をマウスで選択してみて下さい。このHTMLソースは以下のようです。

<blockquote class="css2compat"
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="生命潮流">
<p>日夜 私の血管を流れる 同じ命の流れが<br />
この世界を流れ 旋律に合わせて踊る</p>
</blockquote>

 BLOCKQUOTE要素のみです。これ以上ないぐらいシンプルですね。これに対するスタイルシートは以下。

blockquote.css2compat {
  background: #f8f8ff;
  border: solid 1px #aaa;
  width: 420px; margin: 2em auto;
  padding: 0 1em 0em 1em;
  font: normal 100%/1.7 'メイリオ';
}
blockquote.css2compat[title]:before {
  content: "¥300C" attr(title) "¥300D¥3088¥308A¥629C¥7C8B";
  display: block;
  padding: 5px;
  margin-left: -1em;
  color: #556b2f;
}
blockquote.css2compat[cite]:after {
  content: "¥5F15¥7528¥5143¥3A¥20" attr(cite);
  display: block;
  font-size: 80%;
  text-align: right;
  color: #777;
  margin-top: 1em;
}

 CSS2.1での:before、:after疑似要素を使って、CITE属性やTITLE属性を抜き出しています。CSS3ならコロン(:)が2つ連続します。モダンなブラウザならダブルコロン(::)でも問題なく作動しますが、IE8βが対応していません(コロン1個なら対応)。なかなか簡単に実装できて便利そうです。しかしながら、問題点が2つあって、ひとつは、ブラウザ最大シェアのIE6,7が未対応なこと。もうひとつは、Operaユーザー以外はそうでしょうが、折角、引用元のURIが表示されているのに、マウスでクリックすることも文字列を選択することも出来ないのです![3] contentの文字列は、文字化けを避けるため、16進数の数値文字参照にしています。多分、日本語のままでも大丈夫でしょうけど。CSSの数値文字変換については、「参考リンク」のセクションにあるサイト(使えない文字)で行いました。

 URIが表示されているのに、それをクリックしてリンクすることも出来ず、それならばと文字列を選択しようにもそれすら出来ない現状では、読み手にやさしい実装とは言えません。何より、IE6,7では全く役に立ちませんし。これならば、JavaScriptで、BLOCKQUOTE要素のCITE属性やTITLE属性を読み出して、リンク表示させた方が読み手には都合が良いでしょう。そういうスクリプトは沢山見つかるでしょうし、ppBlogでも簡単に実装はできます。

 というわけで、この手法はネタとしては魅力的ですが、個人的には、あまりオススメできないかなと思います。

3. 引用ブックマークレットの活用

 そろそろ疲れてきたので、まとめようと思います。読み手にも、(おそらく)解析マシンにも優しい手法として、BLOCKQUOTE要素(+CITE属性)とCITE要素のグループ化が、個人的には、現時点での最適解かなと思います。ただ、このアプローチの弱点は、記述量が増えることです。只のテキストなので、データ量としては大したことはありませんが、ブログなど文章の書き手にとっては、なかなか見過ごせない問題です。そこで、こういうときの引用ブックマークレット。この手の引用ブックマークレットは探せば、いくらでもあると思いますが、自分なりに作成してみました。Firefoxでしか確認してません。他のブラウザ向けに調整が必要かも。

 使い方は、簡単で引用したいwebページの引用箇所を、マウスで選択した状態で、このブックマークレットを発動させると、DL要素でグループ化した状態で、テキストエリアが表示されるので、それをCtrl+Cなどでコピーして「Close」ボタンを押せばOKです。後は、それをブログ作成のテキストエリアなどに貼り付ければ良いわけです。

[quoteIt]

Firefoxなどでは、上記リンクを、ブラウザのリンクバーまでドラッグ&ドロップすれば、そのままブックマークとして登録されます。また、登録しなくても、この記事の適当な部分を選択して上記リンクをクリックすれば、実際にどんな感じか試すことが出来ます。タグを含んだソースなどもコピペ出来るように考慮しています。リンクとかもそのまま有効になるようにしようかなと思いましたが、実際問題としてそこまでの機能は不要かなと思い、それは実装していません。JavaScriptの勉強としては面白そうですが。

4. 参考リンク

 以下、参考になるリンクを挙げておきます。
  • [1] 最も、書籍のISBNが分かっている場合は、有効なURIを示すことも出来ます。
    [参考サイト: URNs, citations in web authoringLink ]
    <blockquote cite="urn:isbn:4-003-10101-4">
    でも、このプロトコルに対応しているブラウザは現時点であまりないと思います。[^]
  • [2] CSS2.1, CSS3のcontentプロパティーを用いて、画像を前後に追加することは出来ますが、如何せんIE6,7が未対応なので、あと数年は実用的ではないかなと思います。[^]
  • [3] 現時点で、手元にあるブラウザで調べたところ、Opera9.63のみが文字列を選択可能で、Firefox3.0.5、Google Chrome1.0.154.36、IE8β、Safari3.2.1では文字列の選択は不可でした。[^]

— posted by martin at 07:54 pm   commentComment [9]  pingTrackBack [0]

T: Y: ALL: Online:
Created in 0.0091 sec.
prev
2017.11
next
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30