pax_global_header00006660000000000000000000000064117641413100014510gustar00rootroot0000000000000052 comment=674a334be4d17e4cee9eecd60fc11733eccfeeb1 ruby-ejs-1.1.1/000077500000000000000000000000001176414131000132505ustar00rootroot00000000000000ruby-ejs-1.1.1/LICENSE000066400000000000000000000020421176414131000142530ustar00rootroot00000000000000Copyright (c) 2011 Sam Stephenson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ruby-ejs-1.1.1/README.md000066400000000000000000000025041176414131000145300ustar00rootroot00000000000000EJS (Embedded JavaScript) template compiler for Ruby ==================================================== EJS templates embed JavaScript code inside `<% ... %>` tags, much like ERB. This library is a port of [Underscore.js](http://documentcloud.github.com/underscore/)'s [`_.template` function](http://documentcloud.github.com/underscore/#template) to Ruby, and strives to maintain the same syntax and semantics. Pass an EJS template to `EJS.compile` to generate a JavaScript function: EJS.compile("Hello <%= name %>") # => "function(obj){...}" Invoke the function in a JavaScript environment to produce a string value. You can pass an optional object specifying local variables for template evaluation. The EJS tag syntax is as follows: * `<% ... %>` silently evaluates the statement inside the tags. * `<%= ... %>` evaluates the expression inside the tags and inserts its string value into the template output. * `<%- ... %>` behaves like `<%= ... %>` but HTML-escapes its output. If you have the [ExecJS](https://github.com/sstephenson/execjs/) library and a suitable JavaScript runtime installed, you can pass a template and an optional hash of local variables to `EJS.evaluate`: EJS.evaluate("Hello <%= name %>", :name => "world") # => "Hello world" ----- © 2012 Sam Stephenson Released under the MIT license ruby-ejs-1.1.1/Rakefile000066400000000000000000000001651176414131000147170ustar00rootroot00000000000000require "rake/testtask" task :default => :test Rake::TestTask.new do |t| t.libs << "test" t.warning = true end ruby-ejs-1.1.1/ejs.gemspec000066400000000000000000000007121176414131000153760ustar00rootroot00000000000000Gem::Specification.new do |s| s.name = "ejs" s.version = "1.1.1" s.summary = "EJS (Embedded JavaScript) template compiler" s.description = "Compile and evaluate EJS (Embedded JavaScript) templates from Ruby." s.files = Dir["README.md", "LICENSE", "lib/**/*.rb"] s.add_development_dependency "execjs", "~> 0.4" s.authors = ["Sam Stephenson"] s.email = ["sstephenson@gmail.com"] s.homepage = "https://github.com/sstephenson/ruby-ejs/" end ruby-ejs-1.1.1/lib/000077500000000000000000000000001176414131000140165ustar00rootroot00000000000000ruby-ejs-1.1.1/lib/ejs.rb000066400000000000000000000062641176414131000151340ustar00rootroot00000000000000# EJS (Embedded JavaScript) template compiler for Ruby # This is a port of Underscore.js' `_.template` function: # http://documentcloud.github.com/underscore/ module EJS JS_UNESCAPES = { '\\' => '\\', "'" => "'", 'r' => "\r", 'n' => "\n", 't' => "\t", 'u2028' => "\u2028", 'u2029' => "\u2029" } JS_ESCAPES = JS_UNESCAPES.invert JS_UNESCAPE_PATTERN = /\\(#{Regexp.union(JS_UNESCAPES.keys)})/ JS_ESCAPE_PATTERN = Regexp.union(JS_ESCAPES.keys) class << self attr_accessor :evaluation_pattern attr_accessor :interpolation_pattern attr_accessor :escape_pattern # Compiles an EJS template to a JavaScript function. The compiled # function takes an optional argument, an object specifying local # variables in the template. You can optionally pass the # `:evaluation_pattern` and `:interpolation_pattern` options to # `compile` if you want to specify a different tag syntax for the # template. # # EJS.compile("Hello <%= name %>") # # => "function(obj){...}" # def compile(source, options = {}) source = source.dup js_escape!(source) replace_escape_tags!(source, options) replace_interpolation_tags!(source, options) replace_evaluation_tags!(source, options) "function(obj){var __p=[],print=function(){__p.push.apply(__p,arguments);};" + "with(obj||{}){__p.push('#{source}');}return __p.join('');}" end # Evaluates an EJS template with the given local variables and # compiler options. You will need the ExecJS # (https://github.com/sstephenson/execjs/) library and a # JavaScript runtime available. # # EJS.evaluate("Hello <%= name %>", :name => "world") # # => "Hello world" # def evaluate(template, locals = {}, options = {}) require "execjs" context = ExecJS.compile("var evaluate = #{compile(template, options)}") context.call("evaluate", locals) end protected def js_escape!(source) source.gsub!(JS_ESCAPE_PATTERN) { |match| '\\' + JS_ESCAPES[match] } source end def js_unescape!(source) source.gsub!(JS_UNESCAPE_PATTERN) { |match| JS_UNESCAPES[match[1..-1]] } source end def replace_escape_tags!(source, options) source.gsub!(options[:escape_pattern] || escape_pattern) do "',(''+#{js_unescape!($1)})#{escape_function},'" end end def replace_evaluation_tags!(source, options) source.gsub!(options[:evaluation_pattern] || evaluation_pattern) do "'); #{js_unescape!($1)}; __p.push('" end end def replace_interpolation_tags!(source, options) source.gsub!(options[:interpolation_pattern] || interpolation_pattern) do "', #{js_unescape!($1)},'" end end def escape_function ".replace(/&/g, '&')" + ".replace(//g, '>')" + ".replace(/\"/g, '"')" + ".replace(/'/g, ''')" + ".replace(/\\//g,'/')" end end self.evaluation_pattern = /<%([\s\S]+?)%>/ self.interpolation_pattern = /<%=([\s\S]+?)%>/ self.escape_pattern = /<%-([\s\S]+?)%>/ end ruby-ejs-1.1.1/test/000077500000000000000000000000001176414131000142275ustar00rootroot00000000000000ruby-ejs-1.1.1/test/test_ejs.rb000066400000000000000000000153061176414131000164010ustar00rootroot00000000000000require "ejs" require "test/unit" FUNCTION_PATTERN = /^function\s*\(.*?\)\s*\{(.*?)\}$/ BRACE_SYNTAX = { :evaluation_pattern => /\{\{([\s\S]+?)\}\}/, :interpolation_pattern => /\{\{=([\s\S]+?)\}\}/, :escape_pattern => /\{\{-([\s\S]+?)\}\}/ } QUESTION_MARK_SYNTAX = { :evaluation_pattern => /<\?([\s\S]+?)\?>/, :interpolation_pattern => /<\?=([\s\S]+?)\?>/, :escape_pattern => /<\?-([\s\S]+?)\?>/ } module TestHelper def test(name, &block) define_method("test #{name.inspect}", &block) end end class EJSCompilationTest < Test::Unit::TestCase extend TestHelper test "compile" do result = EJS.compile("Hello <%= name %>") assert_match FUNCTION_PATTERN, result assert_no_match(/Hello \<%= name %\>/, result) end test "compile with custom syntax" do standard_result = EJS.compile("Hello <%= name %>") braced_result = EJS.compile("Hello {{= name }}", BRACE_SYNTAX) assert_match FUNCTION_PATTERN, braced_result assert_equal standard_result, braced_result end end class EJSCustomPatternTest < Test::Unit::TestCase extend TestHelper def setup @original_evaluation_pattern = EJS.evaluation_pattern @original_interpolation_pattern = EJS.interpolation_pattern EJS.evaluation_pattern = BRACE_SYNTAX[:evaluation_pattern] EJS.interpolation_pattern = BRACE_SYNTAX[:interpolation_pattern] end def teardown EJS.interpolation_pattern = @original_interpolation_pattern EJS.evaluation_pattern = @original_evaluation_pattern end test "compile" do result = EJS.compile("Hello {{= name }}") assert_match FUNCTION_PATTERN, result assert_no_match(/Hello \{\{= name \}\}/, result) end test "compile with custom syntax" do standard_result = EJS.compile("Hello {{= name }}") question_result = EJS.compile("Hello ", QUESTION_MARK_SYNTAX) assert_match FUNCTION_PATTERN, question_result assert_equal standard_result, question_result end end class EJSEvaluationTest < Test::Unit::TestCase extend TestHelper test "quotes" do template = "<%= thing %> is gettin' on my noives!" assert_equal "This is gettin' on my noives!", EJS.evaluate(template, :thing => "This") end test "backslashes" do template = "<%= thing %> is \\ridanculous" assert_equal "This is \\ridanculous", EJS.evaluate(template, :thing => "This") end test "backslashes into interpolation" do template = %q{<%= "Hello \"World\"" %>} assert_equal 'Hello "World"', EJS.evaluate(template) end test "implicit semicolon" do template = "<% var foo = 'bar' %>" assert_equal '', EJS.evaluate(template) end test "iteration" do template = "" result = EJS.evaluate(template, :people => ["Moe", "Larry", "Curly"]) assert_equal "", result end test "without interpolation" do template = "

Just some text. Hey, I know this is silly but it aids consistency.

" assert_equal template, EJS.evaluate(template) end test "two quotes" do template = "It's its, not it's" assert_equal template, EJS.evaluate(template) end test "quote in statement and body" do template = "<% if(foo == 'bar'){ %>Statement quotes and 'quotes'.<% } %>" assert_equal "Statement quotes and 'quotes'.", EJS.evaluate(template, :foo => "bar") end test "newlines and tabs" do template = "This\n\t\tis: <%= x %>.\n\tok.\nend." assert_equal "This\n\t\tis: that.\n\tok.\nend.", EJS.evaluate(template, :x => "that") end test "braced iteration" do template = "" result = EJS.evaluate(template, { :people => ["Moe", "Larry", "Curly"] }, BRACE_SYNTAX) assert_equal "", result end test "braced quotes" do template = "It's its, not it's" assert_equal template, EJS.evaluate(template, {}, BRACE_SYNTAX) end test "braced quotes in statement and body" do template = "{{ if(foo == 'bar'){ }}Statement quotes and 'quotes'.{{ } }}" assert_equal "Statement quotes and 'quotes'.", EJS.evaluate(template, { :foo => "bar" }, BRACE_SYNTAX) end test "question-marked iteration" do template = "" result = EJS.evaluate(template, { :people => ["Moe", "Larry", "Curly"] }, QUESTION_MARK_SYNTAX) assert_equal "", result end test "question-marked quotes" do template = "It's its, not it's" assert_equal template, EJS.evaluate(template, {}, QUESTION_MARK_SYNTAX) end test "question-marked quote in statement and body" do template = "Statement quotes and 'quotes'." assert_equal "Statement quotes and 'quotes'.", EJS.evaluate(template, { :foo => "bar" }, QUESTION_MARK_SYNTAX) end test "escaping" do template = "<%- foobar %>" assert_equal "<b>Foo Bar</b>", EJS.evaluate(template, { :foobar => "Foo Bar" }) template = "<%- foobar %>" assert_equal "Foo & Bar", EJS.evaluate(template, { :foobar => "Foo & Bar" }) template = "<%- foobar %>" assert_equal ""Foo Bar"", EJS.evaluate(template, { :foobar => '"Foo Bar"' }) template = "<%- foobar %>" assert_equal "'Foo Bar'", EJS.evaluate(template, { :foobar => "'Foo Bar'" }) end test "braced escaping" do template = "{{- foobar }}" assert_equal "<b>Foo Bar</b>", EJS.evaluate(template, { :foobar => "Foo Bar" }, BRACE_SYNTAX) template = "{{- foobar }}" assert_equal "Foo & Bar", EJS.evaluate(template, { :foobar => "Foo & Bar" }, BRACE_SYNTAX) template = "{{- foobar }}" assert_equal ""Foo Bar"", EJS.evaluate(template, { :foobar => '"Foo Bar"' }, BRACE_SYNTAX) template = "{{- foobar }}" assert_equal "'Foo Bar'", EJS.evaluate(template, { :foobar => "'Foo Bar'" }, BRACE_SYNTAX) end test "question-mark escaping" do template = "" assert_equal "<b>Foo Bar</b>", EJS.evaluate(template, { :foobar => "Foo Bar" }, QUESTION_MARK_SYNTAX) template = "" assert_equal "Foo & Bar", EJS.evaluate(template, { :foobar => "Foo & Bar" }, QUESTION_MARK_SYNTAX) template = "" assert_equal ""Foo Bar"", EJS.evaluate(template, { :foobar => '"Foo Bar"' }, QUESTION_MARK_SYNTAX) template = "" assert_equal "'Foo Bar'", EJS.evaluate(template, { :foobar => "'Foo Bar'" }, QUESTION_MARK_SYNTAX) end end