/ 最近 .rdf 追記 編集 設定 本棚

脳log[20100416] Hatenaスタイル



2010年04月16日 (金) ここまで読んだ。「【コラム】3Dグラフィックス・マニアックス (53) 水面の表現(2)~動的なさざ波 | パソコン | マイコミジャーナル」今や隔世の感があるバーチャファイターや FF7からの道のりを辿れる。

最終更新: 2010-05-01T17:13+0900

[tDiary] Hatenaスタイル

リストをネストしたときだけ生のテキストに<p>タグが付くのがオリジナルのはてなと違うんだそう。ついでに空の<p>タグが生成されるのも気になるけどそれは別。

最初に。<li>はブロック要素もインライン要素も包含可能らしいけど両方を並べて含んでいいのかはわからなかった。読めない(block or inlineの 0以上の繰り返し、だという気はする)。Another HTML-lintが文句を言わなかったのでいいものとしよう。

次に、CodeReposの hatena_style.rbの中を見てみる。Hatena::Blockがなにやら特別な位置を占めてるけど、一応 Hatena::Inlineと同じように振る舞うみたい。ところで、Hatena::Blockはブロック要素の連なり、Hatena::Inlineはインライン要素の連なりを表してるけど、その両方の連なり(<li>の中身とか)を表すクラスがない。

てっとりばやく済ませるために、Hatena::BlockAndorInlineというクラスを用意して Hatena::Blockが行っていた仕事をごっそり移動するそれだけでなく。Hatena::BlockAndorInlineにはインライン要素を含んでいいのかを示すフラグを initializeを通して与え、それにより何が何でも<p>タグで囲むのかそのままにするのかという動作を変えることにした。現状、求められてるのがその違いだけだから。

Hatenaスタイルは使ってないからあからさまなバグがあっても気付かない可能性が大きいです。

suppress_ptag_in_nested_list.patch (7.1KiB, 2010-04-16, r37217との差分)古くなりました。


順序付きリストや定義リストの対応を忘れてる。

<dt>の中はインライン要素の 0以上の繰り返し、<dd>の中はインライン要素とブロック要素の 0以上の繰り返しっぽい。Hatenaスタイルでは定義リストにはインライン要素しか認めていないので対応は必要なし。順序付きリストだけ。

suppress_ptag_in_nested_list.rev2.patch (8.2KiB, 2010-04-16)

svn diffで -x -p (-x <ARG>: diffに渡すオプション, -p: Cの関数名を表示)を初めて付けてみたけど、Rubyスクリプトであってもクラス名は拾ってくれるみたい。


 @2010-04-18 MLに書いた件

次々空いてくる穴をふさぐのはどちらかといえば好きだけど……。

suppress_ptag_in_nested_list.rev3.patch (8.4KiB, 2010-04-18)
r37218に対して。rev2パッチ + (無限ループになっていた例での)段落の分割を防ぐ。
suppress_ptag_in_nested_list.rev3-2.patch (2.9KiB, 2010-04-18)
r37218に対して。(無限ループになっていた例での)段落の分割を防ぐ、だけのパッチ。

 @2010-04-20 「stack level too deep (SystemStackError)」になるらしい。

それはそれとして、

  • Hatena::Block#title_is_dummy?のロジックが反対。(誤:==/正:!=)
  • r37240はリストが必要以上に深くなる。
  • Hatena::Section#bodyは期待通りうごかないかも。(目的がデバッグ出力だったなら OKだけど)

      def body
        @tree.body.to_s
      end

    @treeは以前は Hatena::Blockか Hatena::Inlineだった、俺の変更で Hatena::BlockAndorInlineか Hatena::Inlineになった。カスタマイズされた to_sメソッドを持っているのは Hatena::Blockだけ。

  • 空のサブタイトルでエラー。Hatena::Block#initializeでの配慮が足りなかった。

肝心の深すぎる再帰は再現できない。自分自身を子要素に持ってるなんてことはないはずだから convertメソッドが自分自身を呼び出すしかない。その可能性があったのは Hatena::Block#convertのみ。そのときは if @body == selfでチェックして @body(Hatena::Block).convertを回避していたし、今は @bodyに Hatena::Inlineか Hatena::BlockAndorInlineしか入っていないから自分自身を呼ぶことは考えられない。わからん。キャッシュのせいだったら拍子抜けだなあ。<<<以前は @bodyに Hatena::Blockが入っていたんだから、古いデータと新しいコードの組み合わせで無限再帰は十分ありうる話。.parserキャッシュにはクラス名やインスタンス変数も入ってるし。

 とりあえず
  • fix_c37239.patch (623B, c37239の修正)

    サブタイトルの有無の判断が間違って反対になっていた。

    サブタイトルのみのときにエラーになっていた。

  • fix_c37240.patch (955B, c37240の修正)

    順序付き、順序なしリストの階層が勝手に深くなっていた。

    セクションの分割に失敗していた。


 「<p>はなくなったが空行が……」

たぶん HTMLソースレベルの空行なんだと思う。Hatena::BlockAndorInline#convertでインライン要素の後だけは改行を付加しないようにすればなくせるが、<p>の有無と違って(white-space:preとかしない限り)見た目に関与しないのでこだわらない。(<p>の後ろと</p>の前にも改行が挿入される、だとか考え始めるときりがない)

スレ主は hatena_style.rbを使うことにこだわってはいないという。こちらは楽しんでやってるんだけど、いつまでもデバッグに付き合ってもらうわけにもいかないだろう。はてなはウクレレ記法ができてこそのはてなだと思ってるので、それができない hatena_style.rbから乗り換えるのも悪くないと思う。

「ウクレレ記法」で検索したら主犯が見つかった。最初は Hikiに実装したって書いてるよ。(始めて一か月ほどだったとも書かれていて)つくづくプログラミングは何に使うかが大事だと思う。(英語なんかと一緒でツール)


 @2010-04-25

http://coderepos.org/share/ に書かれている通りにメールを送ってみたが音沙汰がない。スパム判定されたか。comitterってそのページに書かれてるので全てだよね。行動力のある人間なら(というか人並みの人でも) Twitterなり IRCなり blogなりでアクションを起こすんだろうが……。(だから手続きが自動化されてなさそうなのが嫌だったんだ。漏れるし遅れるし。それにサービス自体個人の奉仕に依存してる)

気になる。自分のバグも他人のバグも気になる。


 @2010-05-01: c37240のバグは c37332で本人の手によって修正されたみたい。

Hatena::Section#initializeの部分の修正は、既に行頭の *で分割された文字列が与えられるから問題ないとして先のファイル(fix_c37240.patch)に含めてなかったけど、まあ subが gsubになったって減るもんじゃなし。

それだけでなく 実は一行だけ buffer = '' を buffer = lines.shiftに書き換えた。これがないと無限ループに陥るケース(「>>>」という本文。3文字目は他の文字でもいい)があるみたいなので。