2008年 01月 28日

wikiforme の (だいたい) 最小の syntax 定義と部分編集

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

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


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

#!/usr/bin/env ruby

require "pp"

$LOAD_PATH << "core"

require "wikiforme"

wikiforme = WikiForme.new("foobar.4me")

array =  wikiforme.parse(DATA)

params    = {}
root      = :page
root_text = "test"

pp array

p array.assemble(params, root, root_text).process(:html)

__END__
** Foobar

aaa

** Baz

bbb
# foobar.4me/foobar.rb

Format.block :page  do
	contain        :section
	module_eval do
		def process_html
			@children
		end
	end
end

Format.block :section do
	default_syntax "**"
	contain        :@contents, :@blank
	module_eval do
		def preprocess
			super
		end

		def process_html
			p self
			XML[
				:div, {:class => "section"},
					[:div, {:class => "heading"}, @text.process],
					@children
			]
		end
	end
end

Format.block :blank do
	default_syntax :blank
	group          :@blank
	module_eval do
		def process_html
			""
		end
	end
end

Format.block :paragraph do
	group          :@contents
	default_syntax :text
	module_eval do
		def process_html
			XML[:p, @text.process]
		end
	end
end

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

Ruby. サブクラスでの定数の再定義

class Foo
	AAA   = "aaa"
	@@foo = "aaa"
	@foo  = "aaa"

	def aaa
		"aaa"
	end

	def c
		AAA
	end

	def cv
		@@foo
	end

	def iv
		self.class.instance_variable_get(:@foo)
	end

	def cg
		self.class.const_get(:AAA)
	end

	def m
		aaa
	end
end

class Bar < Foo
	AAA   = "bbb"
	@@foo = "bbb"
	@foo  = "bbb"

	def aaa
		"bbb"
	end
end

puts
p Foo.new.c  #=> "aaa"
p Bar.new.c  #=> "aaa"

puts
p Foo.new.cv #=> "bbb"
p Bar.new.cv #=> "bbb"

puts
p Foo.new.iv #=> "aaa"
p Bar.new.iv #=> "bbb"

puts
p Foo.new.cg #=> "aaa"
p Bar.new.cg #=> "bbb"

puts
p Foo.new.m  #=> "aaa"
p Bar.new.m  #=> "bbb"

なんか勘違いしてた……クラス変数はサブクラスでうわがきしてもスーパークラスに影響はないとおもってた。

RSpec

RSpec つかうときは、同じようなテストも全部コピペしてずらずら書いたほうがよみやすい (謎のデータ構造がならぶよりはコピペのほうがマシ)

ustream

フォントサイズ 33 でやっとよめる……(全画面にしたターミナルをきりぬいて)