lib/qed/evaluator.rb in qed-2.1.1 vs lib/qed/evaluator.rb in qed-2.2.0

- old
+ new

@@ -1,107 +1,98 @@ module QED - require 'tilt' - require 'nokogiri' require 'qed/scope' - # = Demo Script Evaluator - # - #-- - # TODO: Currently the Evaluator class uses #traverse to work - # thru the HTML document and trigger events accordingly. This - # works well enough for simple HTML documents --the kind produced - # by typical wiki-markup formats. However, for complex HTML it - # it will not produce ideal output (although the code segements - # should still run just fine). To counter this weakness, we will - # have to swtich to a more complex SAX parser in the future. - #-- + # = Demonstrandum Evaluator class Evaluator # def initialize(script, *observers) @script = script @file = script.file - @root = script.root + @ast = script.parse @scope = script.scope @binding = script.binding @advice = script.advice @observers = observers end # def run - Dir.chdir(File.dirname(@file)) do - advise!(:before_document, @script) - @root.traverse do |element| - call_tag(element) - end - advise!(:after_document, @script) - end + advise!(:before_document, @script) + process + advise!(:after_document, @script) end # - def call_tag(element) - advise!(:tag, element) - __send__("tag_#{element.name}", element) - end - - # T A G S - - # - def tag_a(element) - case element['href'] - when /qed:\/\/(.*?)$/ - file = $1 - case File.extname(file) - when '.rb' - import!(file) - else - Script.new(file, scope).run + def process + @ast.each do |section| + case section.type + when :code + evaluate_code(section) + when :text + evaluate_text(section) end end end # - def tag_pre(element) - advise!(:before_code, element, @file) + def evaluate_code(section) + advise!(:before_code, section, @file) begin - eval(element.text, @binding, @file, element.line) - pass!(element) + advise!(:code, section) + eval(section.text, @binding, @file, section.line) + #@scope.module_eval(section.text, @file, section.line) + pass!(section) rescue Assertion => exception - fail!(element, exception) + fail!(section, exception) rescue Exception => exception - error!(element, exception) + error!(section, exception) end - advise!(:after_code, element, @file) + advise!(:after_code, section, @file) end # - def tag_p(element) - advise!(:when, element.text) + def evaluate_text(section) + advise!(:text, section) + evaluate_links(section) + advise!(:when, section) end # - def method_missing(s, *a) - super(s, *a) unless /^tag/ =~ s.to_s + def evaluate_links(section) + section.text.scan(/\[qed:\/\/(.*?)\]/) do |match| + file = $1 + # relative to demo script + if File.exist?(File.join(@script.directory,file)) + file = File.join(@script.directory,file) + end + # ruby or another demo + case File.extname(file) + when '.rb' + import!(file) + else + Script.new(@script.applique, file, @script.scope).run + end + end end # - def pass!(element) - advise!(:pass, element) + def pass!(section) + advise!(:pass, section) end # - def fail!(element, exception) - advise!(:fail, element, exception) + def fail!(section, exception) + advise!(:fail, section, exception) #raise exception end # - def error!(element, exception) - advise!(:error, element, exception) + def error!(section, exception) + advise!(:error, section, exception) #raise exception end # def import!(file) @@ -112,15 +103,20 @@ # def advise!(signal, *args) @observers.each{ |o| o.update(signal, *args) } #@scope.__advice__.call(signal, *args) - @advice.call(signal, *args) + @advice.call(@scope, signal, *args) end # #def advise_when!(match) # @advice.call_when(match) + #end + + ## + #def method_missing(s, *a) + # super(s, *a) unless /^tag/ =~ s.to_s #end end end