summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authormakoto kuwata <kwa@kuwata-lab.com>2006-05-02 09:52:00 +0000
committermakoto kuwata <kwa@kuwata-lab.com>2006-05-02 09:52:00 +0000
commit118f9b3afb9cc26fd64fae6924c8b3b4742eb96f (patch)
tree9fdb507fd2571966973a95e7d8be08202946ea9b /misc
parent4a07bdcfb44988a464a3abaa9e80fc43bbde00a8 (diff)
downloaderubis-118f9b3afb9cc26fd64fae6924c8b3b4742eb96f.tar.gz
- [refactor] Engine#compile() refactored
- [refactor] XxxxXmlEruby classes are removed - [change] PrintStatementEnhancer is renamed to PrintOutEnhancer - [change] add benchmark/erubybench-lib.rb - [change] command-line option '-E' (enhancers) changed to '-e' - [change] README is rewrited in RDoc format - [change] removed FastEnhancer - [change] removed XxxXmlEruby classes - [enhance] new command-line option '-E' (show all enhancers) - [enhance] add XxxEnhancer.desc
Diffstat (limited to 'misc')
-rw-r--r--misc/Rookbook.yaml38
-rw-r--r--misc/eruby.txt835
-rw-r--r--misc/memo.txt4
-rw-r--r--misc/test-eruby.rb331
4 files changed, 1206 insertions, 2 deletions
diff --git a/misc/Rookbook.yaml b/misc/Rookbook.yaml
new file mode 100644
index 0000000..7f04796
--- /dev/null
+++ b/misc/Rookbook.yaml
@@ -0,0 +1,38 @@
+
+properties:
+ - tagfile : html-css_i,euc
+
+variables:
+ #- tagfile : html-css
+ - textfile : eruby.txt
+ - htmlfile : eruby.html
+ - testscript : test-eruby.rb
+
+recipes:
+
+ - product: :html
+ desc: create eruby.html
+ ingreds: [ $(htmlfile) ]
+
+ - product: :test
+ method: |
+ sys "retrieve $(textfile)"
+ (1..5).each do |i|
+ sys "ruby -s $(testscript) -target=eruby#{i}"
+ end
+
+ - product: *.html
+ ingreds: [ $(1).txt ]
+ byprods: [ $(1).toc.html ]
+ method: |
+ sys "retrieve $(1).txt"
+ sys "kwaser -t $(tagfile) -T $(1).txt > $(1).toc.html"
+ sys "kwaser -t $(tagfile) $(1).txt > $(1).html"
+ rm_f "$(1).toc.html"
+
+ - product: :clean
+ method: |
+ list = `retrieve -l $(textfile)`
+ rm_rf list.split
+
+
diff --git a/misc/eruby.txt b/misc/eruby.txt
new file mode 100644
index 0000000..85f8057
--- /dev/null
+++ b/misc/eruby.txt
@@ -0,0 +1,835 @@
+.=title: プログラマーのための eRuby 入門 (車輪の再発明編)
+.?lastupdate: $Date$
+
+.# (setq ed::*ruby-indent-column* 2)
+
+
+●最初の実装
+
+.? eruby1.rb
+.-------------------- eruby1.rb
+##
+## eRuby の実装
+##
+class Eruby
+
+ ## eRuby 形式の文字列を受け取る
+ def initialize(input)
+ @input = input
+ @src = compile(@input)
+ end
+ attr_reader :src
+
+ ## 実行した結果 (文字列) を返す
+ def result(binding=TOPLEVEL_BINDING)
+ filename = '(eruby)'
+ eval @src, binding, filename
+ end
+
+ private
+
+ ## eRuby 形式の文字列を Ruby コードに変換する
+ def compile(input=@input)
+ src = "_out = ''; "
+ regexp = /(.*?)<%(=?)(.*?)%>/m
+ input.scan(regexp) do |text, indicator, code|
+ ## テキストを処理
+ text.each_line do |line|
+ src << "_out << #{line.dump}" << (line[-1] == ?\n ? "\n" : "; ")
+ end
+
+ ## 埋め込み Ruby コードを処理
+ if indicator == '=' # <%= %> の場合
+ src << "_out << (#{code}).to_s; "
+ else # <% %> の場合
+ code.each_line { |line| src << line }
+ src << "; " unless code[-1] == ?\n
+ end
+ end
+
+ ## 残りのテキストを処理
+ rest = $' || input
+ rest.each_line do |line|
+ src << "_out << #{line.dump}" << (line[-1] == ?\n ? "\n" : "; ")
+ end
+
+ src << "_out\n"
+ return src
+ end
+
+end
+.--------------------
+
+
+.? example1.rb
+.-------------------- example1.rb
+list = ['aaa', 'bbb', 'ccc']
+
+input = <<END
+<ul>
+ <% for item in list %>
+ <li><%= item %></li>
+ <% end %>
+</ul>
+.#<table>
+.# <% for item in list %>
+.# <tr>
+.# <td><%= item %></td>
+.# </tr>
+.# <% end %>
+.#</table>
+END
+
+require 'eruby1'
+eruby = Eruby.new(input)
+puts "--- source ---"
+puts eruby.src
+puts "--- result ---"
+puts eruby.result
+.--------------------
+
+
+.? output
+.____________________
+.<<<:! ruby example1.rb
+.____________________
+
+
+
+
+●子クラスでの拡張をしやすくする
+
+.? eruby2.rb
+.-------------------- eruby2.rb
+##
+## eRuby の実装
+##
+class Eruby
+
+ ## eRuby 形式の文字列を受け取る
+ def initialize(input)
+ @input = input
+ @src = compile(@input)
+ end
+ attr_reader :src
+
+ ## 実行した結果 (文字列) を返す
+ def result(binding=TOPLEVEL_BINDING)
+ filename = '(eruby)'
+ eval @src, binding, filename
+ end
+
+ private
+
+ ## eRuby 形式の文字列を Ruby コードに変換する
+ def compile(input=@input)
+ {{*src = ""*}}
+ {{*initialize_src(src)*}}
+ regexp = /(.*?)<%(=?)(.*?)%>/m
+ input.scan(regexp) do |text, indicator, code|
+ ## テキストを処理
+ {{*add_src_text(src, text)*}}
+
+ ## 埋め込み Ruby コードを処理
+ if indicator == '=' # <%= %> の場合
+ {{*add_src_expr(src, code)*}}
+ else # <% %> の場合
+ {{*add_src_code(src, code)*}}
+ end
+ end
+
+ ## 残りのテキストを処理
+ rest = $' || input
+ {{*add_src_text(src, rest)*}}
+
+ {{*finalize_src(src)*}}
+ return src
+ end
+
+ {{*protected*}}
+
+ {{*def initialize_src(src)*}}
+ {{*src << "_out = ''; "*}}
+ {{*end*}}
+
+ {{*def add_src_text(src, text)*}}
+ {{*return if text.empty?*}}
+ {{*text.each_line do |line|*}}
+ {{*src << "_out << #{line.dump}" << (line[-1] == ?\n ? "\n" : "; ")*}}
+ {{*end*}}
+ {{*end*}}
+
+ {{*def add_src_expr(src, code)*}}
+ {{*src << "_out << (#{code}).to_s; "*}}
+ {{*end*}}
+
+ {{*def add_src_code(src, code)*}}
+ {{*code.each_line { |line| src << line }*}}
+ {{*src << "; " unless code[-1] == ?\n*}}
+ {{*end*}}
+
+ {{*def finalize_src(src)*}}
+ {{*src << "_out\n"*}}
+ {{*end*}}
+
+end
+.--------------------
+
+
+.? stdout-eruby.rb : 標準出力を使う Eruby
+.-------------------- stdout-eruby.rb
+##
+## 文字列ではなく標準出力を使う Eruby
+## (「<% print expr %>」が使えるようになる)
+##
+class StdoutEruby < Eruby
+
+ def initialize_src(src)
+ src << "_out = $stdout; " ## 文字列のかわりに標準出力を使う
+ end
+
+ def finalize_src(src)
+ src << "nil\n"
+ end
+
+end
+.--------------------
+
+
+.? fast-eruby.rb : 高速化した Eruby
+.-------------------- fast-eruby.rb
+##
+## 実行速度を高速化した Eruby
+##
+class FastEruby < Eruby
+
+ def add_src_text(src, text)
+ return if text.empty?
+ src << "_out << #{text.dump}" << "; "
+ src << ("\n" * text.count("\n"))
+ end
+
+end
+.--------------------
+
+
+.? example2.rb
+.-------------------- example2.rb
+list = ['aaa', 'bbb', 'ccc']
+
+input = <<END
+.#<ul>
+.# <% for item in list %>
+.# <li><%= item %></li>
+.# <% end %>
+.#</ul>
+<table>
+ <% for item in list %>
+ <tr>
+ <td><%= item %></td>
+ </tr>
+ <% end %>
+</table>
+END
+
+require 'eruby2'
+eruby = Eruby.new(input)
+puts "--- source (Eruby) ---"
+puts eruby.src
+
+require 'fast-eruby'
+fasteruby = FastEruby.new(input)
+puts "--- source (FastEruby) ---"
+puts fasteruby.src
+.--------------------
+
+.? output
+.____________________
+.<<<:! ruby example2.rb
+.____________________
+
+
+
+
+●余分な空白を出力しない
+
+.? eruby3.rb
+.-------------------- eruby3.rb
+##
+## eRuby の実装
+##
+class Eruby
+
+ ## eRuby 形式の文字列を受け取る
+ def initialize(input)
+ @input = input
+ @src = compile(@input)
+ end
+ attr_reader :src
+
+ ## 実行した結果 (文字列) を返す
+ def result(binding=TOPLEVEL_BINDING)
+ filename = '(eruby)'
+ eval @src, binding, filename
+ end
+
+ private
+
+ ## eRuby 形式の文字列を Ruby コードに変換する
+ def compile(input=@input)
+ src = ""
+ initialize_src(src)
+ regexp = /(.*?){{*(^[ \t]*)?*}}<%(=?)(.*?)%>{{*([ \t]*\r?\n)?*}}/m
+ input.scan(regexp) do |text, {{*head_space,*}} indicator, code{{*, tail_space*}}|
+ {{*## * <%= %> のときは、何もしない*}}
+ {{*## * <% %> のときは、*}}
+ {{*## * 前後が空白だけのときは、その空白を削除*}}
+ {{*## * そうでないときは、何もしない(空白を残す)*}}
+ {{*flag_trim = indicator != '=' && head_space && tail_space*}}
+
+ ## テキストを処理
+ add_src_text(src, text)
+
+ {{*## 前の空白を処理*}}
+ {{*unless flag_trim*}}
+ {{*add_src_text(src, head_space) if head_space*}}
+ {{*end*}}
+
+ ## 埋め込み Ruby コードを処理
+ if indicator == '=' # <%= %> の場合
+ add_src_expr(src, code)
+ else # <% %> の場合
+ {{*## 改行を含めた前後の空白をコードに足す*}}
+ {{*code = "#{head_space}#{code}#{tail_space}" if flag_trim*}}
+ add_src_code(src, code)
+ end
+
+ {{*## 後ろの空白を処理*}}
+ {{*unless flag_trim*}}
+ {{*add_src_text(src, tail_space) if tail_space*}}
+ {{*end*}}
+ end
+
+ ## 残りのテキストを処理
+ rest = $' || input
+ add_src_text(src, rest)
+
+ finalize_src(src)
+ return src
+ end
+
+ protected
+
+ def initialize_src(src)
+ src << "_out = ''; "
+ end
+
+ def add_src_text(src, text)
+ return if text.empty?
+ text.each_line do |line|
+ src << "_out << #{line.dump}" << (line[-1] == ?\n ? "\n" : "; ")
+ end
+ end
+
+ def add_src_expr(src, code)
+ src << "_out << (#{code}).to_s; "
+ end
+
+ def add_src_code(src, code)
+ code.each_line { |line| src << line }
+ src << "; " unless code[-1] == ?\n
+ end
+
+ def finalize_src(src)
+ src << "_out\n"
+ end
+
+end
+.--------------------
+
+
+.? example3.rb
+.-------------------- example3.rb
+list = ['aaa', 'bbb', 'ccc']
+
+input = <<END
+<ul>
+ <% for item in list %>
+ <li>
+ <%= item %>
+ </li>
+ <% end %>
+</ul>
+.#<table>
+.# <% for item in list %>
+.# <tr>
+.# <td>
+.# <%= item %>
+.# </td>
+.# </tr>
+.# <% end %>
+.#</table>
+END
+
+require 'eruby3'
+eruby = Eruby.new(input)
+puts "--- source ---"
+puts eruby.src
+puts "--- result ---"
+puts eruby.result
+.--------------------
+
+.? output
+.____________________
+.<<<:! ruby example3.rb
+.____________________
+
+
+
+
+●文字列をエスケープする
+
+.? eruby4.rb
+.-------------------- eruby4.rb
+##
+## eRuby の実装
+##
+class Eruby
+
+ ## eRuby 形式の文字列を受け取る
+ def initialize(input)
+ @input = input
+ @src = compile(@input)
+ end
+ attr_reader :src
+
+ ## 実行した結果 (文字列) を返す
+ def result(binding=TOPLEVEL_BINDING)
+ filename = '(eruby)'
+ eval @src, binding, filename
+ end
+
+ private
+
+ ## eRuby 形式の文字列を Ruby コードに変換する
+ def compile(input=@input)
+ src = ""
+ initialize_src(src)
+ regexp = /(.*?)(^[ \t]*)?<%({{*=**}})(.*?)%>([ \t]*\r?\n)?/m
+ input.scan(regexp) do |text, head_space, indicator, code, tail_space|
+ ## * <%= %> のときは、何もしない
+ ## * <% %> のときは、
+ ## * 前後が空白だけのときは、その空白を削除
+ ## * そうでないときは、何もしない(空白を残す)
+ flag_trim = {{*indicator.empty?*}} && head_space && tail_space
+
+ ## テキストを処理
+ add_src_text(src, text)
+
+ ## 前の空白を処理
+ unless flag_trim
+ add_src_text(src, head_space) if head_space
+ end
+
+ ## 埋め込み Ruby コードを処理
+ if {{*!indicator.empty?*}} # <%= %> の場合
+ add_src_expr(src, code{{*, indicator*}})
+ else # <% %> の場合
+ ## 改行を含めた前後の空白をコードに足す
+ code = "#{head_space}#{code}#{tail_space}" if flag_trim
+ add_src_code(src, code)
+ end
+
+ ## 後ろの空白を処理
+ unless flag_trim
+ add_src_text(src, tail_space) if tail_space
+ end
+ end
+
+ ## 残りのテキストを処理
+ rest = $' || input
+ add_src_text(src, rest)
+
+ finalize_src(src)
+ return src
+ end
+
+ protected
+
+ def initialize_src(src)
+ src << "_out = ''; "
+ end
+
+ def add_src_text(src, text)
+ return if text.empty?
+ text.each_line do |line|
+ src << "_out << #{line.dump}" << (line[-1] == ?\n ? "\n" : "; ")
+ end
+ end
+
+ def add_src_expr(src, code, indicator)
+ src << "_out << (#{code}).to_s; "
+ end
+
+ def add_src_code(src, code)
+ code.each_line { |line| src << line }
+ src << "; " unless code[-1] == ?\n
+ end
+
+ def finalize_src(src)
+ src << "_out\n"
+ end
+
+end
+.--------------------
+
+
+.? xml-eruby.rb
+.-------------------- xml-eruby.rb
+##
+## サニタイズを行う Eruby
+## * <%= %> はサニタイズして出力
+## * <%== %> はサニタイズせずそのまま出力
+##
+class XmlEruby < Eruby
+
+ def self.escape(obj)
+ str = obj.to_s.dup
+ #str = obj.to_s
+ #str = str.dup if obj.__id__ == str.__id__
+ str.gsub!(/&/, '&amp;')
+ str.gsub!(/</, '&lt;')
+ str.gsub!(/>/, '&gt;')
+ str.gsub!(/"/, '&quot;')
+ return str
+ end
+
+ {{*def add_src_expr(src, code, indicator)*}}
+ {{*if indicator == '='*}}
+ {{*src << "_out << XmlEruby.escape(#{code}); "*}}
+ {{*else*}}
+ {{*super*}}
+ {{*end*}}
+ {{*end*}}
+
+end
+.--------------------
+
+
+.? example4.rb
+.-------------------- example4.rb
+list = ['<aaa>', 'b&b', '"ccc"']
+
+input = <<END
+<ul>
+ <% for item in list %>
+ <li><%= item %></li>
+ <li><%== item %></li>
+ <% end %>
+</ul>
+.#<table>
+.# <% for item in list %>
+.# <tr>
+.# <td><%= item %></td>
+.# <td><%== item %></td>
+.# </tr>
+.# <% end %>
+.#</table>
+END
+
+require 'eruby4'
+require 'xml-eruby'
+eruby = XmlEruby.new(input)
+puts "--- source ---"
+puts eruby.src
+puts "--- result ---"
+puts eruby.result
+.--------------------
+
+
+.? output
+.____________________
+.<<<:! ruby example4.rb
+.____________________
+
+
+
+
+●埋め込み用パターンを変更可能にする
+
+
+.? eruby5.rb
+.-------------------- eruby5.rb
+##
+## eRuby の実装
+##
+class Eruby
+
+ ## eRuby 形式の文字列を受け取る
+ def initialize(input{{*, options={}*}})
+ @input = input
+ {{*@options = options*}}
+ {{*@pattern = options[:pattern] || '<% %>'*}}
+ @src = compile(@input)
+ end
+ attr_reader :src
+
+ ## 実行した結果 (文字列) を返す
+ def result(binding=TOPLEVEL_BINDING)
+ filename = '(eruby)'
+ eval @src, binding, filename
+ end
+
+ private
+
+ ## eRuby 形式の文字列を Ruby コードに変換する
+ def compile(input=@input)
+ src = ""
+ initialize_src(src)
+ {{*prefix, postfix = @pattern.split() # 埋め込みパターン*}}
+ regexp = /(.*?)(^[ \t]*)?{{*#{prefix}*}}(=*)(.*?){{*#{postfix}*}}([ \t]*\r?\n)?/m
+ input.scan(regexp) do |text, head_space, indicator, code, tail_space|
+ ## * <%= %> のときは、何もしない
+ ## * <% %> のときは、
+ ## * 前後が空白だけのときは、その空白を削除
+ ## * そうでないときは、何もしない(空白を残す)
+ flag_trim = indicator.empty? && head_space && tail_space
+
+ ## テキストを処理
+ add_src_text(src, text)
+
+ ## 前の空白を処理
+ unless flag_trim
+ add_src_text(src, head_space) if head_space
+ end
+
+ ## 埋め込み Ruby コードを処理
+ if !indicator.empty? # <%= %> の場合
+ add_src_expr(src, code, indicator)
+ else # <% %> の場合
+ ## 改行を含めた前後の空白をコードに足す
+ code = "#{head_space}#{code}#{tail_space}" if flag_trim
+ add_src_code(src, code)
+ end
+
+ ## 後ろの空白を処理
+ unless flag_trim
+ add_src_text(src, tail_space) if tail_space
+ end
+ end
+
+ ## 残りのテキストを処理
+ rest = $' || input
+ add_src_text(src, rest)
+
+ finalize_src(src)
+ return src
+ end
+
+ protected
+
+ def initialize_src(src)
+ src << "_out = ''; "
+ end
+
+ def add_src_text(src, text)
+ return if text.empty?
+ text.each_line do |line|
+ src << "_out << #{line.dump}" << (line[-1] == ?\n ? "\n" : "; ")
+ end
+ end
+
+ def add_src_expr(src, code, indicator)
+ src << "_out << (#{code}).to_s; "
+ end
+
+ def add_src_code(src, code)
+ code.each_line { |line| src << line }
+ src << "; " unless code[-1] == ?\n
+ end
+
+ def finalize_src(src)
+ src << "_out\n"
+ end
+
+end
+.--------------------
+
+
+.? example5.rb
+.-------------------- example5.rb
+list = ['aaa', 'bbb', 'ccc']
+
+input = <<END
+<ul>
+ <!--% for item in list %-->
+ <li><!--%= item %--></li>
+ <!--% end %-->
+</ul>
+.#<table>
+.# <!--% for item in list %-->
+.# <tr>
+.# <td><!--%= item %--></td>
+.# </tr>
+.# <!--% end %-->
+.#</table>
+END
+
+require 'eruby5'
+eruby = Eruby.new(input, :pattern=>'<!--% %-->')
+ # or '<(?:!--)% %(?:--)>'
+puts "--- source ---"
+print eruby.src
+puts "--- result ---"
+print eruby.result()
+.--------------------
+
+
+.? output
+.____________________
+.<<<:! ruby example5.rb
+.____________________
+
+
+
+
+●コンテキストを指定できるようにする
+
+.? eruby6.rb
+.-------------------- eruby6.rb
+##
+## eRuby の実装
+##
+class Eruby
+
+ ## eRuby 形式の文字列を受け取る
+ def initialize(input, options={})
+ @input = input
+ @options = options
+ @pattern = options[:pattern] || '<% %>'
+ @src = compile(@input)
+ end
+ attr_reader :src
+
+ ## 実行した結果 (文字列) を返す
+ def result(binding=TOPLEVEL_BINDING)
+ filename = '(eruby)'
+ eval @src, binding, filename
+ end
+
+ {{*## コンテキストを指定して result() を呼び出す*}}
+ {{*def evaluate(_context={})*}}
+ {{*_evalstr = ''*}}
+ {{*_context.keys.each do |key|*}}
+ {{*_evalstr << "#{key.to_s} = _context[#{key.inspect}]\n"*}}
+ {{*end*}}
+ {{*eval _evalstr*}}
+ {{*return result(binding())*}}
+ {{*end*}}
+
+ private
+
+ ## eRuby 形式の文字列を Ruby コードに変換する
+ def compile(input=@input)
+ src = ""
+ initialize_src(src)
+ prefix, postfix = @pattern.split() # 埋め込みパターン
+ regexp = /(.*?)(^[ \t]*)?#{prefix}(=*)(.*?)#{postfix}([ \t]*\r?\n)?/m
+ input.scan(regexp) do |text, head_space, indicator, code, tail_space|
+ ## * <%= %> のときは、何もしない
+ ## * <% %> のときは、
+ ## * 前後が空白だけのときは、その空白を削除
+ ## * そうでないときは、何もしない(空白を残す)
+ flag_trim = indicator.empty? && head_space && tail_space
+
+ ## テキストを処理
+ add_src_text(src, text)
+
+ ## 前の空白を処理
+ unless flag_trim
+ add_src_text(src, head_space) if head_space
+ end
+
+ ## 埋め込み Ruby コードを処理
+ if !indicator.empty? # <%= %> の場合
+ add_src_expr(src, code, indicator)
+ else # <% %> の場合
+ ## 改行を含めた前後の空白をコードに足す
+ code = "#{head_space}#{code}#{tail_space}" if flag_trim
+ add_src_code(src, code)
+ end
+
+ ## 後ろの空白を処理
+ unless flag_trim
+ add_src_text(src, tail_space) if tail_space
+ end
+ end
+
+ ## 残りのテキストを処理
+ rest = $' || input
+ add_src_text(src, rest)
+
+ finalize_src(src)
+ return src
+ end
+
+ protected
+
+ def initialize_src(src)
+ src << "_out = ''; "
+ end
+
+ def add_src_text(src, text)
+ return if text.empty?
+ text.each_line do |line|
+ src << "_out << #{line.dump}" << (line[-1] == ?\n ? "\n" : "; ")
+ end
+ end
+
+ def add_src_expr(src, code, indicator)
+ src << "_out << (#{code}).to_s; "
+ end
+
+ def add_src_code(src, code)
+ code.each_line { |line| src << line }
+ src << "; " unless code[-1] == ?\n
+ end
+
+ def finalize_src(src)
+ src << "_out\n"
+ end
+
+end
+.--------------------
+
+
+.? example6.rb
+.-------------------- example6.rb
+## eRuby スクリプト
+input = <<END
+<h2><%= title %></h2>
+<ul>
+ <% for item in list %>
+ <li><%= item %></li>
+ <% end %>
+</ul>
+END
+
+## コンテキストオブジェクトを作成する。
+## 変数名は文字列または Symbol で指定する。
+## また YAML ファイルを読み込んでそれをコンテキストとして使ってもよい。
+context = {}
+context['title'] = "Context Example"
+context[:list] = ['aaa', 'bbb', 'ccc']
+
+## eRuby を実行する
+require 'eruby6'
+eruby = Eruby.new(input)
+print eruby.evaluate(context)
+.--------------------
+
+
+.? output
+.____________________
+.<<<:! ruby example6.rb
+.____________________
diff --git a/misc/memo.txt b/misc/memo.txt
index b7dd9c2..30e59e4 100644
--- a/misc/memo.txt
+++ b/misc/memo.txt
@@ -233,7 +233,7 @@ class MyEruby
src << "\n_buf\n"
return src
end
-
+
end
.--------------------
@@ -367,7 +367,7 @@ end
.* httpd, ruby, mod_ruby.soはstripされているか?
.- MacOS Xではstripすると動かないので注意
.* apacheの設定は適切か?
- .-
+ .-
.* 同等の拡張プログラムはないか?
.- Ruby/MySQLよりMySQL/Ruby
.* そのプログラムはほんとうにボトルネックなのか?
diff --git a/misc/test-eruby.rb b/misc/test-eruby.rb
new file mode 100644
index 0000000..cb0ceeb
--- /dev/null
+++ b/misc/test-eruby.rb
@@ -0,0 +1,331 @@
+##
+## usage: ruby -s test-eruby.rb -target=eruby1
+##
+
+# (setq ed::*ruby-indent-column* 2)
+
+currdir = File.dirname(File.expand_path(__FILE__))
+testdir = File.dirname(currdir) + "/test"
+$: << testdir
+
+raise "*** target is required." unless $target
+
+require 'test/unit'
+#require 'test/unit/ui/console/testrunner'
+require 'assert-diff'
+require 'yaml'
+
+require $target
+
+class ErubyTest < Test::Unit::TestCase
+
+ #str = DATA.read()
+ str = File.read(__FILE__)
+ str.gsub!(/.*^__END__$/m, '')
+
+ @@ydocs = {}
+ YAML.load_documents(str) do |ydoc|
+ name = ydoc['name']
+ raise "*** test name '#{name}' is duplicated." if @@ydocs[name]
+ ydoc.each do |key, val|
+ if key[-1] == ?*
+ key = key.sub(/\*\z/, '')
+ val = val[$target]
+ ydoc[key] = val
+ end
+ end
+ target = ydoc['target']
+ next unless target && target.include?($target)
+ @@ydocs[name] = ydoc
+ s = <<-END
+ def test_#{name}
+ @name = #{name.dump}
+ _test()
+ end
+ END
+ eval s
+ end
+
+ def _test()
+ ydoc = @@ydocs[@name]
+ input = ydoc['input']
+ src = ydoc['src'].gsub(/@/, ' ')
+ output = ydoc['output'].gsub(/@/, ' ')
+ options = ydoc['options']
+ #
+ require ydoc['require'] if ydoc['require']
+ klass = eval(ydoc['class'] || 'Eruby')
+ if options
+ eruby = klass.new(input, options)
+ else
+ eruby = klass.new(input)
+ end
+ assert_equal_with_diff(src, eruby.src)
+ list = ['<aaa>', 'b&b', '"ccc"']
+ assert_equal_with_diff(output, eruby.result(binding()))
+ end
+
+end
+
+__END__
+---
+name: basic1
+target: [ eruby1, eruby2 ]
+input: |
+ <ul>
+ <% for item in list %>
+ <li><%= item %></li>
+ <% end %>
+ </ul>
+src: |
+ _out = ''; _out << "<ul>\n"
+ _out << " "; for item in list ; _out << "\n"
+ _out << " <li>"; _out << ( item ).to_s; _out << "</li>\n"
+ _out << " "; end ; _out << "\n"
+ _out << "</ul>\n"
+ _out
+output: |
+ <ul>
+ @
+ <li><aaa></li>
+ @
+ <li>b&b</li>
+ @
+ <li>"ccc"</li>
+ @
+ </ul>
+##
+---
+name: basic2
+target: [ eruby1, eruby2 ]
+input: |
+ <ul>
+ <% i = 0
+ for item in list
+ i += 1
+ %>
+ <li><%= item %></li>
+ <% end %>
+ </ul>
+src: |
+ _out = ''; _out << "<ul>\n"
+ _out << " "; i = 0
+ for item in list
+ i += 1
+ ; _out << "\n"
+ _out << " <li>"; _out << ( item ).to_s; _out << "</li>\n"
+ _out << " "; end ; _out << "\n"
+ _out << "</ul>\n"
+ _out
+output: |
+ <ul>
+ @
+ <li><aaa></li>
+ @
+ <li>b&b</li>
+ @
+ <li>"ccc"</li>
+ @
+ </ul>
+##
+---
+name: basic3
+target: [ eruby1, eruby2, eruby3 ]
+input: |
+ <ul><% i = 0
+ for item in list
+ i += 1 %><li><%= item %></li><% end %>
+ </ul>
+src: |
+ _out = ''; _out << "<ul>"; i = 0
+ for item in list
+ i += 1 ; _out << "<li>"; _out << ( item ).to_s; _out << "</li>"; end ; _out << "\n"
+ _out << "</ul>\n"
+ _out
+output: |
+ <ul><li><aaa></li><li>b&b</li><li>"ccc"</li>
+ </ul>
+##
+---
+name: fast1
+target: [ eruby2 ]
+require: fast-eruby
+class: FastEruby
+input: |
+ <table>
+ <% for item in list %>
+ <tr>
+ <td><%= item %></td>
+ </tr>
+ <% end %>
+ </table>
+src: |
+ _out = ''; _out << "<table>\n ";
+ for item in list ; _out << "\n <tr>\n <td>";
+
+ _out << ( item ).to_s; _out << "</td>\n </tr>\n ";
+
+ end ; _out << "\n</table>\n";
+
+ _out
+output: |
+ <table>
+ @
+ <tr>
+ <td><aaa></td>
+ </tr>
+ @
+ <tr>
+ <td>b&b</td>
+ </tr>
+ @
+ <tr>
+ <td>"ccc"</td>
+ </tr>
+ @
+ </table>
+##
+---
+name: trim1
+target: [ eruby3 ]
+input: |
+ <ul>
+ <% for item in list %>
+ <li>
+ <%= item %>
+ </li>
+ <% end %>
+ </ul>
+src: |
+ _out = ''; _out << "<ul>\n"
+ for item in list
+ _out << " <li>\n"
+ _out << " "; _out << ( item ).to_s; _out << "\n"
+ _out << " </li>\n"
+ end
+ _out << "</ul>\n"
+ _out
+output: |
+ <ul>
+ <li>
+ <aaa>
+ </li>
+ <li>
+ b&b
+ </li>
+ <li>
+ "ccc"
+ </li>
+ </ul>
+##
+---
+name: trim2
+target: [ eruby3 ]
+input: |
+ <ul>
+ <% i = 0
+ for item in list
+ i += 1
+ %>
+ <li><%= item %></li>
+ <% end %>
+ </ul>
+src: |
+ _out = ''; _out << "<ul>\n"
+ i = 0
+ for item in list
+ i += 1
+ @@
+ _out << " <li>"; _out << ( item ).to_s; _out << "</li>\n"
+ end
+ _out << "</ul>\n"
+ _out
+output: |
+ <ul>
+ <li><aaa></li>
+ <li>b&b</li>
+ <li>"ccc"</li>
+ </ul>
+##
+---
+name: escape1
+target: [ eruby4 ]
+input: |
+ <ul>
+ <% for item in list %>
+ <li><%= item %></li>
+ <li><%== item %></li>
+ <% end %>
+ </ul>
+src: |
+ _out = ''; _out << "<ul>\n"
+ for item in list
+ _out << " <li>"; _out << ( item ).to_s; _out << "</li>\n"
+ _out << " <li>"; _out << ( item ).to_s; _out << "</li>\n"
+ end
+ _out << "</ul>\n"
+ _out
+output: |
+ <ul>
+ <li><aaa></li>
+ <li><aaa></li>
+ <li>b&b</li>
+ <li>b&b</li>
+ <li>"ccc"</li>
+ <li>"ccc"</li>
+ </ul>
+##
+---
+name: escape2
+target: [ eruby4 ]
+require: xml-eruby
+class: XmlEruby
+input: |
+ <ul>
+ <% for item in list %>
+ <li><%= item %></li>
+ <li><%== item %></li>
+ <% end %>
+ </ul>
+src: |
+ _out = ''; _out << "<ul>\n"
+ for item in list
+ _out << " <li>"; _out << XmlEruby.escape( item ); _out << "</li>\n"
+ _out << " <li>"; _out << ( item ).to_s; _out << "</li>\n"
+ end
+ _out << "</ul>\n"
+ _out
+output: |
+ <ul>
+ <li>&lt;aaa&gt;</li>
+ <li><aaa></li>
+ <li>b&amp;b</li>
+ <li>b&b</li>
+ <li>&quot;ccc&quot;</li>
+ <li>"ccc"</li>
+ </ul>
+##
+---
+name: pattern1
+target: [ eruby5 ]
+options: { :pattern : '<(?:!--)?% %(?:--)?>' }
+input: |
+ <ul>
+ <!--% for item in list %-->
+ <li><%= item %></li>
+ <!--% end %-->
+ </ul>
+src: |
+ _out = ''; _out << "<ul>\n"
+ for item in list
+ _out << " <li>"; _out << ( item ).to_s; _out << "</li>\n"
+ end
+ _out << "</ul>\n"
+ _out
+output: |
+ <ul>
+ <li><aaa></li>
+ <li>b&b</li>
+ <li>"ccc"</li>
+ </ul>
+##