Permalink
Browse files

Basic preprocessor now passing first test.

  • Loading branch information...
1 parent e872d1b commit 99f6c2cef19210a50b6aed87f08df747bcb787a3 @raroni raroni committed May 23, 2011
View
@@ -2,4 +2,5 @@ module Reco
VERSION = '0.1.0'
autoload :Scanner, "reco/scanner"
+ autoload :Preprocessor, "reco/preprocessor"
end
View
@@ -0,0 +1,45 @@
+require 'reco/scanner'
+require 'reco/util'
+
+class Reco::Preprocessor
+ def self.preprocess(source)
+ new(source).execute
+ end
+
+ def initialize(source)
+ @scanner = Reco::Scanner.new source
+ @output = ''
+ @level = 0
+ @options = {}
+ @captures = []
+ end
+
+ def execute
+ @scanner.scan { |token| send token.shift, *token } until @scanner.done?
+ @output
+ end
+
+ def record(line)
+ @output += @level.times.collect { ' ' }.join
+ @output += "#{line}\n"
+ end
+
+ def print_string(string)
+ record "__out.push #{Reco::Util.inspect_string(string)}" unless string.empty?
+ end
+
+ def begin_code(options)
+ @options = options
+ end
+
+ def record_code(code)
+ if code != 'end'
+ if @options[:print]
+ record @options[:safe] ? "__out.push #{code}" : "__out.push __sanitize #{code}"
+ else
+ record code
+ end
+ end
+ end
+
+end
View
@@ -27,7 +27,7 @@ def scan(callback = nil, &block)
if @scanner.eos?
@done = true
- yield @mode == :data ? ["print_string", flush] : ["fail", "unexpected end of template"]
+ callback.call @mode == :data ? ["print_string", flush] : ["fail", "unexpected end of template"]
else
advance
@mode == :data ? scan_data(callback) : scan_code(callback)
View
@@ -0,0 +1,24 @@
+module Reco::Util
+ SPECIAL_CHARACTERS = {
+ "\\" => '\\\\',
+ "\b" => '\\b',
+ "\f" => '\\f',
+ "\n" => '\\n',
+ "\r" => '\\r',
+ "\t" => '\\t'
+ }
+
+ def self.inspect_string(string)
+ string.gsub!(/[\x00-\x1f\\]/) do |character|
+ if SPECIAL_CHARACTERS[character]
+ SPECIAL_CHARACTERS[character]
+ else
+ code = character.ord.to_s 16
+ code = "0#{code}" if code.length == 1
+ "\\u00#{code}"
+ end
+ end
+
+ "'" + string.gsub("'", "\\\\'") + "'"
+ end
+end
@@ -0,0 +1,5 @@
+__out.push 'Hello, '
+__out.push __sanitize @name
+__out.push '.\nI\'M SHOUTING AT YOU, '
+__out.push __sanitize @name.toUpperCase()
+__out.push '!\n'
View
@@ -0,0 +1,2 @@
+Hello, <%= @name %>.
+I'M SHOUTING AT YOU, <%= @name.toUpperCase() %>!
View
@@ -1,2 +1,10 @@
require 'test/unit'
require 'reco'
+
+class Reco::TestCase < Test::Unit::TestCase
+ FIXTURE_ROOT = File.expand_path(File.join(File.dirname(__FILE__), "fixtures"))
+
+ def fixture(path)
+ File.read File.join(FIXTURE_ROOT, path)
+ end
+end
@@ -0,0 +1,7 @@
+require 'reco_test'
+
+class PreprocessorTest < Reco::TestCase
+ def test_respond_to_preprocess_class_method
+ assert_equal fixture('hello.coffee'), Reco::Preprocessor.preprocess(fixture('hello.eco'))
+ end
+end

0 comments on commit 99f6c2c

Please sign in to comment.