読者です 読者をやめる 読者になる 読者になる

WikiForme 0.7へ

cho45さんにWikiFormeが改善されているのを発見!
wikiforme の (だいたい) 最小の syntax 定義と部分編集

勝手にブロック引数とって DSL っぽく書けるようにした。(検索しにくくなるのであんまりファイルわけたくない。ファイルわけないとなるとインデントして定義の範囲を明確にしたい。)

CodeReposってすばらしいですねぇ。

セクション編集ができる wiki がほしいなぁとおもって wikiforme だとどうなんかなぁと思いつつ、syntax 定義をもぞもぞ書く (内部でどういう構造になってるのかよくわからないのでためしに)

HTML のセクションから、ソースのその範囲を取得できればいいのだから、トップレベルのセクションを列挙して、番号をふり (直接ふらなくてもいいけど)、それがソースではどの範囲にあたるかをとれればいい。行番号は parse した直後のやつには含まれているけど、それを保存して、構造化 HTML をはく process はないみたいなので自分で書くしかない。


とおもいながら書いていたのだけど、process で行番号がとれないことに気付いた。行番号はエラー表示のためだけにあるみたいだ (assemble.rb L42 あたり)。なおそうと思うと結構広範囲に影響しそうでやりにくい。のでとりあえずやめた。

うーむ。まったくその通りで、行番号はエラー表示のためだけにあります。

というわけで、ガツっとコードを書いて行番号が取れるようにしてみました。行番号が@line変数に入ります。影響範囲が大きいのでブランチを切ってみました。CodeRepos:/lang/ruby/wikiforme/branches/frsyuki


構造化HTMLというのはちょっと良く分からなかったのですが、sectionを<div>で囲ってやるだけなら、既存のsection要素を継承して要素を作るのが良いかもしれません。既存のsection要素は↓こうなっていますが、

# 新ブランチ版
block :section do
  syntax '**'
  contain :@contents, :@blank, :subsection
  def preprocess
    # ... いろいろ ...
  end
  def process_html
    if @anchor
      [[:h3, {:id => @anchor}, @text.process], @children]
    else
      [[:h3, @text.process], @children]
    end
  end
  # ... 他のフォーマット用のコードとかとか ...
end


これを継承して要素が作れます。

# WikiForme 0.5の場合
f = Format.block :structured_section, :section do   # New style by cho45!
  default_syntax '**'
  module_eval {
    def process_html
      XML[:div, super]
    end
  }
end
# 新ブランチ版の場合
block :structured_section, :section do
  syntax '**'  # syntaxは継承されないので再定義
  def process_html
    [:div, super]   # XMLが要らなくなりました。最後に一括して処理します
  end
end

(ちなみに新ブランチ版はRuby 1.9でmodule_evalとブロック付きメソッド呼び出しの回避策を使っていて、Ruby 1.9.0でも動きます)


HTMLに行番号を入れるなら↓こんな感じでしょうか。

block :structured_section, :section do
  syntax '**'
  def process_html
    # 弟ノードの行番号を取得
    me = @parent.children.index(self)
    to_line = @parent.children[me+1].info[:line] rescue -1
    # sys:from属性とsys:to属性に行番号を入れてみる
    [:div, {'sys:from' => @line, 'sys:to' => to_line}, super]
  end
end

block :section do
  syntax nil   # 元のsection要素のsyntaxを無効にしておく
end

block :subsection do
  syntax '**'   # subsectionのsyntaxを'**'に
end