tilt-1.4.1/0000755000004100000410000000000012162124415012517 5ustar www-datawww-datatilt-1.4.1/tilt.gemspec0000644000004100000410000000721012162124415015040 0ustar www-datawww-dataGem::Specification.new do |s| s.specification_version = 2 if s.respond_to? :specification_version= s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.name = 'tilt' s.version = '1.4.1' s.date = '2013-05-08' s.description = "Generic interface to multiple Ruby template engines" s.summary = s.description s.license = "MIT" s.authors = ["Ryan Tomayko"] s.email = "r@tomayko.com" # = MANIFEST = s.files = %w[ CHANGELOG.md COPYING Gemfile HACKING README.md Rakefile TEMPLATES.md bin/tilt lib/tilt.rb lib/tilt/asciidoc.rb lib/tilt/builder.rb lib/tilt/coffee.rb lib/tilt/css.rb lib/tilt/csv.rb lib/tilt/erb.rb lib/tilt/etanni.rb lib/tilt/haml.rb lib/tilt/liquid.rb lib/tilt/markaby.rb lib/tilt/markdown.rb lib/tilt/nokogiri.rb lib/tilt/plain.rb lib/tilt/radius.rb lib/tilt/rdoc.rb lib/tilt/string.rb lib/tilt/template.rb lib/tilt/textile.rb lib/tilt/wiki.rb lib/tilt/yajl.rb test/contest.rb test/markaby/locals.mab test/markaby/markaby.mab test/markaby/markaby_other_static.mab test/markaby/render_twice.mab test/markaby/scope.mab test/markaby/yielding.mab test/tilt_asciidoctor_test.rb test/tilt_blueclothtemplate_test.rb test/tilt_buildertemplate_test.rb test/tilt_cache_test.rb test/tilt_coffeescripttemplate_test.rb test/tilt_compilesite_test.rb test/tilt_creoletemplate_test.rb test/tilt_csv_test.rb test/tilt_erbtemplate_test.rb test/tilt_erubistemplate_test.rb test/tilt_etannitemplate_test.rb test/tilt_fallback_test.rb test/tilt_hamltemplate_test.rb test/tilt_kramdown_test.rb test/tilt_lesstemplate_test.less test/tilt_lesstemplate_test.rb test/tilt_liquidtemplate_test.rb test/tilt_markaby_test.rb test/tilt_markdown_test.rb test/tilt_marukutemplate_test.rb test/tilt_nokogiritemplate_test.rb test/tilt_radiustemplate_test.rb test/tilt_rdiscounttemplate_test.rb test/tilt_rdoctemplate_test.rb test/tilt_redcarpettemplate_test.rb test/tilt_redclothtemplate_test.rb test/tilt_sasstemplate_test.rb test/tilt_stringtemplate_test.rb test/tilt_template_test.rb test/tilt_test.rb test/tilt_wikiclothtemplate_test.rb test/tilt_yajltemplate_test.rb tilt.gemspec ] # = MANIFEST = s.executables = ['tilt'] s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/} s.add_development_dependency 'asciidoctor', '>= 0.1.0' s.add_development_dependency 'RedCloth' s.add_development_dependency 'bluecloth' s.add_development_dependency 'builder' s.add_development_dependency 'coffee-script' s.add_development_dependency 'contest' s.add_development_dependency 'creole' s.add_development_dependency 'erubis' s.add_development_dependency 'haml', '>= 2.2.11' s.add_development_dependency 'kramdown' s.add_development_dependency 'less' s.add_development_dependency 'liquid' s.add_development_dependency 'markaby' s.add_development_dependency 'maruku' s.add_development_dependency 'nokogiri' s.add_development_dependency 'radius' s.add_development_dependency 'rdiscount' s.add_development_dependency 'rdoc' s.add_development_dependency 'redcarpet' s.add_development_dependency 'sass' s.add_development_dependency 'wikicloth' s.add_development_dependency 'yajl-ruby' s.add_development_dependency 'rdoc' s.homepage = "http://github.com/rtomayko/tilt/" s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Tilt", "--main", "Tilt"] s.require_paths = %w[lib] s.rubygems_version = '1.1.1' end tilt-1.4.1/test/0000755000004100000410000000000012162124415013476 5ustar www-datawww-datatilt-1.4.1/test/tilt_creoletemplate_test.rb0000644000004100000410000000145312162124415021126 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'creole' class CreoleTemplateTest < Test::Unit::TestCase test "is registered for '.creole' files" do assert_equal Tilt::CreoleTemplate, Tilt['test.creole'] end test "registered for '.wiki' files" do assert Tilt.mappings['wiki'].include?(Tilt::CreoleTemplate) end test "compiles and evaluates the template on #render" do template = Tilt::CreoleTemplate.new { |t| "= Hello World!" } assert_equal "

Hello World!

", template.render end test "can be rendered more than once" do template = Tilt::CreoleTemplate.new { |t| "= Hello World!" } 3.times { assert_equal "

Hello World!

", template.render } end end rescue LoadError => boom warn "Tilt::CreoleTemplate (disabled)" end tilt-1.4.1/test/tilt_lesstemplate_test.less0000644000004100000410000000002512162124415021160 0ustar www-datawww-data@text-color: #ffc0cb;tilt-1.4.1/test/tilt_marukutemplate_test.rb0000644000004100000410000000277312162124415021167 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'maruku' class MarukuTemplateTest < Test::Unit::TestCase test "registered for '.md' files" do assert Tilt.mappings['md'].include?(Tilt::MarukuTemplate) end test "registered for '.mkd' files" do assert Tilt.mappings['mkd'].include?(Tilt::MarukuTemplate) end test "registered for '.markdown' files" do assert Tilt.mappings['markdown'].include?(Tilt::MarukuTemplate) end test "registered below Kramdown" do %w[md mkd markdown].each do |ext| mappings = Tilt.mappings[ext] kram_idx = mappings.index(Tilt::KramdownTemplate) maru_idx = mappings.index(Tilt::MarukuTemplate) assert maru_idx > kram_idx, "#{maru_idx} should be higher than #{kram_idx}" end end test "preparing and evaluating templates on #render" do template = Tilt::MarukuTemplate.new { |t| "# Hello World!" } assert_equal "

Hello World!

", template.render end test "can be rendered more than once" do template = Tilt::MarukuTemplate.new { |t| "# Hello World!" } 3.times { assert_equal "

Hello World!

", template.render } end test "removes HTML when :filter_html is set" do template = Tilt::MarukuTemplate.new(:filter_html => true) { |t| "HELLO WORLD" } assert_equal "

HELLO

", template.render end end rescue LoadError => boom warn "Tilt::MarukuTemplate (disabled)" end tilt-1.4.1/test/tilt_sasstemplate_test.rb0000644000004100000410000000257212162124415020631 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'sass' class SassTemplateTest < Test::Unit::TestCase test "is registered for '.sass' files" do assert_equal Tilt::SassTemplate, Tilt['test.sass'] end test "compiles and evaluates the template on #render" do template = Tilt::SassTemplate.new { |t| "#main\n :background-color #0000f1" } assert_equal "#main {\n background-color: #0000f1; }\n", template.render end test "can be rendered more than once" do template = Tilt::SassTemplate.new { |t| "#main\n :background-color #0000f1" } 3.times { assert_equal "#main {\n background-color: #0000f1; }\n", template.render } end end class ScssTemplateTest < Test::Unit::TestCase test "is registered for '.scss' files" do assert_equal Tilt::ScssTemplate, Tilt['test.scss'] end test "compiles and evaluates the template on #render" do template = Tilt::ScssTemplate.new { |t| "#main {\n background-color: #0000f1;\n}" } assert_equal "#main {\n background-color: #0000f1; }\n", template.render end test "can be rendered more than once" do template = Tilt::ScssTemplate.new { |t| "#main {\n background-color: #0000f1;\n}" } 3.times { assert_equal "#main {\n background-color: #0000f1; }\n", template.render } end end rescue LoadError => boom warn "Tilt::SassTemplate (disabled)" end tilt-1.4.1/test/tilt_stringtemplate_test.rb0000644000004100000410000001215612162124415021165 0ustar www-datawww-datarequire 'contest' require 'tilt' class StringTemplateTest < Test::Unit::TestCase test "registered for '.str' files" do assert_equal Tilt::StringTemplate, Tilt['test.str'] end test "loading and evaluating templates on #render" do template = Tilt::StringTemplate.new { |t| "Hello World!" } assert_equal "Hello World!", template.render end test "can be rendered more than once" do template = Tilt::StringTemplate.new { |t| "Hello World!" } 3.times { assert_equal "Hello World!", template.render } end test "passing locals" do template = Tilt::StringTemplate.new { 'Hey #{name}!' } assert_equal "Hey Joe!", template.render(Object.new, :name => 'Joe') end test "evaluating in an object scope" do template = Tilt::StringTemplate.new { 'Hey #{@name}!' } scope = Object.new scope.instance_variable_set :@name, 'Joe' assert_equal "Hey Joe!", template.render(scope) end test "passing a block for yield" do template = Tilt::StringTemplate.new { 'Hey #{yield}!' } assert_equal "Hey Joe!", template.render { 'Joe' } assert_equal "Hey Moe!", template.render { 'Moe' } end test "multiline templates" do template = Tilt::StringTemplate.new { "Hello\nWorld!\n" } assert_equal "Hello\nWorld!\n", template.render end test "backtrace file and line reporting without locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::StringTemplate.new('test.str', 11) { data } begin template.render fail 'should have raised an exception' rescue => boom assert_kind_of NameError, boom line = boom.backtrace.grep(/^test\.str:/).first assert line, "Backtrace didn't contain test.str" file, line, meth = line.split(":") assert_equal '13', line end end test "backtrace file and line reporting with locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::StringTemplate.new('test.str', 1) { data } begin template.render(nil, :name => 'Joe', :foo => 'bar') fail 'should have raised an exception' rescue => boom assert_kind_of RuntimeError, boom line = boom.backtrace.first file, line, meth = line.split(":") assert_equal 'test.str', file assert_equal '6', line end end end class CompiledStringTemplateTest < Test::Unit::TestCase def teardown GC.start end class Scope end test "compiling template source to a method" do template = Tilt::StringTemplate.new { |t| "Hello World!" } template.render(Scope.new) method = template.send(:compiled_method, []) assert_kind_of UnboundMethod, method end test "loading and evaluating templates on #render" do template = Tilt::StringTemplate.new { |t| "Hello World!" } assert_equal "Hello World!", template.render(Scope.new) end test "passing locals" do template = Tilt::StringTemplate.new { 'Hey #{name}!' } assert_equal "Hey Joe!", template.render(Scope.new, :name => 'Joe') assert_equal "Hey Moe!", template.render(Scope.new, :name => 'Moe') end test "evaluating in an object scope" do template = Tilt::StringTemplate.new { 'Hey #{@name}!' } scope = Scope.new scope.instance_variable_set :@name, 'Joe' assert_equal "Hey Joe!", template.render(scope) scope.instance_variable_set :@name, 'Moe' assert_equal "Hey Moe!", template.render(scope) end test "passing a block for yield" do template = Tilt::StringTemplate.new { 'Hey #{yield}!' } assert_equal "Hey Joe!", template.render(Scope.new) { 'Joe' } assert_equal "Hey Moe!", template.render(Scope.new) { 'Moe' } end test "multiline templates" do template = Tilt::StringTemplate.new { "Hello\nWorld!\n" } assert_equal "Hello\nWorld!\n", template.render(Scope.new) end test "template with '}'" do template = Tilt::StringTemplate.new { "Hello }" } assert_equal "Hello }", template.render end test "backtrace file and line reporting without locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::StringTemplate.new('test.str', 11) { data } begin template.render(Scope.new) fail 'should have raised an exception' rescue => boom assert_kind_of NameError, boom line = boom.backtrace.first line = boom.backtrace.grep(/^test\.str:/).first assert line, "Backtrace didn't contain test.str" file, line, meth = line.split(":") assert_equal '13', line end end test "backtrace file and line reporting with locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::StringTemplate.new('test.str') { data } begin template.render(Scope.new, :name => 'Joe', :foo => 'bar') fail 'should have raised an exception' rescue => boom assert_kind_of RuntimeError, boom line = boom.backtrace.first file, line, meth = line.split(":") assert_equal 'test.str', file assert_equal '6', line end end end __END__

Hey #{name}!

#{fail}

tilt-1.4.1/test/tilt_test.rb0000644000004100000410000000346212162124415016043 0ustar www-datawww-datarequire 'contest' require 'tilt' class TiltTest < Test::Unit::TestCase class MockTemplate attr_reader :args, :block def initialize(*args, &block) @args = args @block = block end end test "registering template implementation classes by file extension" do Tilt.register('mock', MockTemplate) end test "an extension is registered if explicit handle is found" do Tilt.register('mock', MockTemplate) assert Tilt.registered?('mock') end test "registering template classes by symbol file extension" do Tilt.register(:mock, MockTemplate) end test "looking up template classes by exact file extension" do Tilt.register('mock', MockTemplate) impl = Tilt['mock'] assert_equal MockTemplate, impl end test "looking up template classes by implicit file extension" do Tilt.register('mock', MockTemplate) impl = Tilt['.mock'] assert_equal MockTemplate, impl end test "looking up template classes with multiple file extensions" do Tilt.register('mock', MockTemplate) impl = Tilt['index.html.mock'] assert_equal MockTemplate, impl end test "looking up template classes by file name" do Tilt.register('mock', MockTemplate) impl = Tilt['templates/test.mock'] assert_equal MockTemplate, impl end test "looking up non-existant template class" do assert_nil Tilt['none'] end test "accessing template class mappings at Tilt::mappings" do assert Tilt.respond_to?(:mappings) assert Tilt.mappings.respond_to?(:[]) end test "creating new template instance with a filename" do Tilt.register('mock', MockTemplate) template = Tilt.new('foo.mock', 1, :key => 'val') { 'Hello World!' } assert_equal ['foo.mock', 1, {:key => 'val'}], template.args assert_equal 'Hello World!', template.block.call end end tilt-1.4.1/test/tilt_etannitemplate_test.rb0000644000004100000410000001232612162124415021134 0ustar www-datawww-datarequire 'contest' require 'tilt' class EtanniTemplateTest < Test::Unit::TestCase test "registered for '.etn' files" do assert_equal Tilt::EtanniTemplate, Tilt['test.etn'] end test "registered for '.etanni' files" do assert_equal Tilt::EtanniTemplate, Tilt['test.etanni'] end test "loading and evaluating templates on #render" do template = Tilt::EtanniTemplate.new { |t| "Hello World!" } assert_equal "Hello World!", template.render end test "can be rendered more than once" do template = Tilt::EtanniTemplate.new { |t| "Hello World!" } 3.times { assert_equal "Hello World!", template.render } end test "passing locals" do template = Tilt::EtanniTemplate.new { 'Hey #{name}!' } assert_equal "Hey Joe!", template.render(Object.new, :name => 'Joe') end test "evaluating in an object scope" do template = Tilt::EtanniTemplate.new { 'Hey #{@name}!' } scope = Object.new scope.instance_variable_set :@name, 'Joe' assert_equal "Hey Joe!", template.render(scope) end test "passing a block for yield" do template = Tilt::EtanniTemplate.new { 'Hey #{yield}!' } assert_equal "Hey Joe!", template.render { 'Joe' } assert_equal "Hey Moe!", template.render { 'Moe' } end test "multiline templates" do template = Tilt::EtanniTemplate.new { "Hello\nWorld!\n" } assert_equal "Hello\nWorld!", template.render end test "backtrace file and line reporting without locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::EtanniTemplate.new('test.etn', 11) { data } begin template.render fail 'should have raised an exception' rescue => boom assert_kind_of NameError, boom line = boom.backtrace.grep(/^test\.etn:/).first assert line, "Backtrace didn't contain test.etn" file, line, meth = line.split(":") assert_equal '13', line end end test "backtrace file and line reporting with locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::EtanniTemplate.new('test.etn', 1) { data } begin template.render(nil, :name => 'Joe', :foo => 'bar') fail 'should have raised an exception' rescue => boom assert_kind_of RuntimeError, boom line = boom.backtrace.first file, line, meth = line.split(":") assert_equal 'test.etn', file assert_equal '6', line end end end class CompiledEtanniTemplateTest < Test::Unit::TestCase def teardown GC.start end class Scope end test "compiling template source to a method" do template = Tilt::EtanniTemplate.new { |t| "Hello World!" } template.render(Scope.new) method = template.send(:compiled_method, []) assert_kind_of UnboundMethod, method end test "loading and evaluating templates on #render" do template = Tilt::EtanniTemplate.new { |t| "Hello World!" } assert_equal "Hello World!", template.render(Scope.new) end test "passing locals" do template = Tilt::EtanniTemplate.new { 'Hey #{name}!' } assert_equal "Hey Joe!", template.render(Scope.new, :name => 'Joe') assert_equal "Hey Moe!", template.render(Scope.new, :name => 'Moe') end test "evaluating in an object scope" do template = Tilt::EtanniTemplate.new { 'Hey #{@name}!' } scope = Scope.new scope.instance_variable_set :@name, 'Joe' assert_equal "Hey Joe!", template.render(scope) scope.instance_variable_set :@name, 'Moe' assert_equal "Hey Moe!", template.render(scope) end test "passing a block for yield" do template = Tilt::EtanniTemplate.new { 'Hey #{yield}!' } assert_equal "Hey Joe!", template.render(Scope.new) { 'Joe' } assert_equal "Hey Moe!", template.render(Scope.new) { 'Moe' } end test "multiline templates" do template = Tilt::EtanniTemplate.new { "Hello\nWorld!\n" } assert_equal "Hello\nWorld!", template.render(Scope.new) end test "template with '}'" do template = Tilt::EtanniTemplate.new { "Hello }" } assert_equal "Hello }", template.render end test "backtrace file and line reporting without locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::EtanniTemplate.new('test.etn', 11) { data } begin template.render(Scope.new) fail 'should have raised an exception' rescue => boom assert_kind_of NameError, boom line = boom.backtrace.first line = boom.backtrace.grep(/^test\.etn:/).first assert line, "Backtrace didn't contain test.etn" file, line, meth = line.split(":") assert_equal '13', line end end test "backtrace file and line reporting with locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::EtanniTemplate.new('test.etn') { data } begin template.render(Scope.new, :name => 'Joe', :foo => 'bar') fail 'should have raised an exception' rescue => boom assert_kind_of RuntimeError, boom line = boom.backtrace.first file, line, meth = line.split(":") assert_equal 'test.etn', file assert_equal '6', line end end end __END__

Hey #{name}!

#{fail}

tilt-1.4.1/test/tilt_redclothtemplate_test.rb0000644000004100000410000000245712162124415021466 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'redcloth' class RedClothTemplateTest < Test::Unit::TestCase test "is registered for '.textile' files" do assert_equal Tilt::RedClothTemplate, Tilt['test.textile'] end test "compiles and evaluates the template on #render" do template = Tilt::RedClothTemplate.new { |t| "h1. Hello World!" } assert_equal "

Hello World!

", template.render end test "can be rendered more than once" do template = Tilt::RedClothTemplate.new { |t| "h1. Hello World!" } 3.times { assert_equal "

Hello World!

", template.render } end test "ignores unknown options" do template = Tilt::RedClothTemplate.new(:foo => "bar") { |t| "h1. Hello World!" } 3.times { assert_equal "

Hello World!

", template.render } end test "passes in RedCloth options" do template = Tilt::RedClothTemplate.new { |t| "Hard breaks are\ninserted by default." } assert_equal "

Hard breaks are
\ninserted by default.

", template.render template = Tilt::RedClothTemplate.new(:hard_breaks => false) { |t| "But they can be\nturned off." } assert_equal "

But they can be\nturned off.

", template.render end end rescue LoadError => boom warn "Tilt::RedClothTemplate (disabled)" end tilt-1.4.1/test/tilt_kramdown_test.rb0000644000004100000410000000246012162124415017742 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'kramdown' class MarukuTemplateTest < Test::Unit::TestCase test "registered for '.md' files" do assert Tilt.mappings['md'].include?(Tilt::KramdownTemplate) end test "registered for '.mkd' files" do assert Tilt.mappings['mkd'].include?(Tilt::KramdownTemplate) end test "registered for '.markdown' files" do assert Tilt.mappings['markdown'].include?(Tilt::KramdownTemplate) end test "registered above MarukuTemplate" do %w[md mkd markdown].each do |ext| mappings = Tilt.mappings[ext] kram_idx = mappings.index(Tilt::KramdownTemplate) maru_idx = mappings.index(Tilt::MarukuTemplate) assert kram_idx < maru_idx, "#{kram_idx} should be lower than #{maru_idx}" end end test "preparing and evaluating templates on #render" do template = Tilt::KramdownTemplate.new { |t| "# Hello World!" } assert_equal "

Hello World!

", template.render end test "can be rendered more than once" do template = Tilt::KramdownTemplate.new { |t| "# Hello World!" } 3.times { assert_equal "

Hello World!

", template.render } end end rescue LoadError => boom warn "Tilt::KramdownTemplate (disabled)" end tilt-1.4.1/test/tilt_erubistemplate_test.rb0000644000004100000410000001223712162124415021150 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'erubis' class ErubisTemplateTest < Test::Unit::TestCase test "registered for '.erubis' files" do assert_equal Tilt::ErubisTemplate, Tilt['test.erubis'] assert_equal Tilt::ErubisTemplate, Tilt['test.html.erubis'] end test "registered above ERB" do %w[erb rhtml].each do |ext| mappings = Tilt.mappings[ext] erubis_idx = mappings.index(Tilt::ErubisTemplate) erb_idx = mappings.index(Tilt::ERBTemplate) assert erubis_idx < erb_idx, "#{erubis_idx} should be lower than #{erb_idx}" end end test "preparing and evaluating templates on #render" do template = Tilt::ErubisTemplate.new { |t| "Hello World!" } assert_equal "Hello World!", template.render end test "can be rendered more than once" do template = Tilt::ErubisTemplate.new { |t| "Hello World!" } 3.times { assert_equal "Hello World!", template.render } end test "passing locals" do template = Tilt::ErubisTemplate.new { 'Hey <%= name %>!' } assert_equal "Hey Joe!", template.render(Object.new, :name => 'Joe') end test "evaluating in an object scope" do template = Tilt::ErubisTemplate.new { 'Hey <%= @name %>!' } scope = Object.new scope.instance_variable_set :@name, 'Joe' assert_equal "Hey Joe!", template.render(scope) end class MockOutputVariableScope attr_accessor :exposed_buffer end test "exposing the buffer to the template by default" do begin Tilt::ErubisTemplate.default_output_variable = '@_out_buf' template = Tilt::ErubisTemplate.new { '<% self.exposed_buffer = @_out_buf %>hey' } scope = MockOutputVariableScope.new template.render(scope) assert_not_nil scope.exposed_buffer assert_equal scope.exposed_buffer, 'hey' ensure Tilt::ErubisTemplate.default_output_variable = '_erbout' end end test "passing a block for yield" do template = Tilt::ErubisTemplate.new { 'Hey <%= yield %>!' } assert_equal "Hey Joe!", template.render { 'Joe' } end test "backtrace file and line reporting without locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::ErubisTemplate.new('test.erubis', 11) { data } begin template.render fail 'should have raised an exception' rescue => boom assert_kind_of NameError, boom line = boom.backtrace.grep(/^test\.erubis:/).first assert line, "Backtrace didn't contain test.erubis" file, line, meth = line.split(":") assert_equal '13', line end end test "backtrace file and line reporting with locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::ErubisTemplate.new('test.erubis', 1) { data } begin template.render(nil, :name => 'Joe', :foo => 'bar') fail 'should have raised an exception' rescue => boom assert_kind_of RuntimeError, boom line = boom.backtrace.first file, line, meth = line.split(":") assert_equal 'test.erubis', file assert_equal '6', line end end test "erubis template options" do template = Tilt::ErubisTemplate.new(nil, :pattern => '\{% %\}') { 'Hey {%= @name %}!' } scope = Object.new scope.instance_variable_set :@name, 'Joe' assert_equal "Hey Joe!", template.render(scope) end test "using an instance variable as the outvar" do template = Tilt::ErubisTemplate.new(nil, :outvar => '@buf') { "<%= 1 + 1 %>" } scope = Object.new scope.instance_variable_set(:@buf, 'original value') assert_equal '2', template.render(scope) assert_equal 'original value', scope.instance_variable_get(:@buf) end test "using Erubis::EscapedEruby subclass via :engine_class option" do template = Tilt::ErubisTemplate.new(nil, :engine_class => ::Erubis::EscapedEruby) { |t| %(<%= "

Hello World!

" %>) } assert_equal "<p>Hello World!</p>", template.render end test "using :escape_html => true option" do template = Tilt::ErubisTemplate.new(nil, :escape_html => true) { |t| %(<%= "

Hello World!

" %>) } assert_equal "<p>Hello World!</p>", template.render end test "using :escape_html => false option" do template = Tilt::ErubisTemplate.new(nil, :escape_html => false) { |t| %(<%= "

Hello World!

" %>) } assert_equal "

Hello World!

", template.render end test "erubis default does not escape html" do template = Tilt::ErubisTemplate.new { |t| %(<%= "

Hello World!

" %>) } assert_equal "

Hello World!

", template.render end test "does not modify options argument" do options_hash = {:escape_html => true} template = Tilt::ErubisTemplate.new(nil, options_hash) { |t| "Hello World!" } assert_equal({:escape_html => true}, options_hash) end end rescue LoadError => boom warn "Tilt::ErubisTemplate (disabled)" end __END__

Hey <%= name %>!

<% fail %>

tilt-1.4.1/test/markaby/0000755000004100000410000000000012162124415015124 5ustar www-datawww-datatilt-1.4.1/test/markaby/yielding.mab0000644000004100000410000000002312162124415017404 0ustar www-datawww-datatext("Hey ") yield tilt-1.4.1/test/markaby/scope.mab0000644000004100000410000000000712162124415016713 0ustar www-datawww-datali foo tilt-1.4.1/test/markaby/markaby.mab0000644000004100000410000000003312162124415017227 0ustar www-datawww-datatext "hello from markaby!" tilt-1.4.1/test/markaby/render_twice.mab0000644000004100000410000000001312162124415020251 0ustar www-datawww-datatext "foo" tilt-1.4.1/test/markaby/locals.mab0000644000004100000410000000000712162124415017057 0ustar www-datawww-datali foo tilt-1.4.1/test/markaby/markaby_other_static.mab0000644000004100000410000000001512162124415021777 0ustar www-datawww-datatext "_why?" tilt-1.4.1/test/tilt_markdown_test.rb0000644000004100000410000001037612162124415017747 0ustar www-datawww-data# coding: UTF-8 require 'tilt' begin require 'nokogiri' module MarkdownTests def self.included(mod) class << mod def template(t = nil) t.nil? ? @template : @template = t end end end def render(text, options = {}) self.class.template.new(options) { text }.render end def normalize(html) Nokogiri::HTML.fragment(html).to_s.strip end def nrender(text, options = {}) html = render(text, options) html.encode!("UTF-8") if html.respond_to?(:encode) normalize(html) end def test_escape_html html = nrender "Hello World" assert_equal "

Hello World

", html end def test_escape_html_false html = nrender "Hello World", :escape_html => false assert_equal "

Hello World

", html end def test_escape_html_true if self.class.template == Tilt::RedcarpetTemplate flunk "redcarpet doesn't support :escape_html yet" end html = nrender "Hello World", :escape_html => true assert_equal "

Hello <b>World</b>

", html end def test_smart_quotes html = nrender 'Hello "World"' assert_equal '

Hello "World"

', html end def test_smart_quotes_false html = nrender 'Hello "World"', :smartypants => false assert_equal '

Hello "World"

', html end def test_smart_quotes_true html = nrender 'Hello "World"', :smartypants => true assert_equal '

Hello “World”

', html end def test_smarty_pants html = nrender "Hello ``World'' -- This is --- a test ..." assert_equal "

Hello ``World'' -- This is --- a test ...

", html end def test_smarty_pants_false html = nrender "Hello ``World'' -- This is --- a test ...", :smartypants => false assert_equal "

Hello ``World'' -- This is --- a test ...

", html end def test_smarty_pants_true html = nrender "Hello ``World'' -- This is --- a test ...", :smartypants => true assert_equal "

Hello “World” — This is —– a test …

", html end end begin require 'rdiscount' class MarkdownRDiscountTest < Test::Unit::TestCase include MarkdownTests template Tilt::RDiscountTemplate end rescue LoadError => boom # It should already be warned in the main tests end begin require 'redcarpet' class MarkdownRedcarpetTest < Test::Unit::TestCase include MarkdownTests template Tilt::RedcarpetTemplate # Doesn't support escaping undef test_escape_html_true def test_smarty_pants_true html = nrender "Hello ``World'' -- This is --- a test ...", :smartypants => true assert_equal "

Hello “World'' – This is — a test …

", html end def test_fenced_code_blocks_with_lang code = <<-COD.gsub(/^\s+/,"") ```ruby puts "hello world" ``` COD html = nrender code, :fenced_code_blocks => true assert_equal %Q{
puts "hello world"\n
}, html end end rescue LoadError => boom # It should already be warned in the main tests end begin require 'bluecloth' class MarkdownBlueClothTest < Test::Unit::TestCase include MarkdownTests template Tilt::BlueClothTemplate end rescue LoadError => boom # It should already be warned in the main tests end begin require 'kramdown' class MarkdownKramdownTest < Test::Unit::TestCase include MarkdownTests template Tilt::KramdownTemplate # Doesn't support escaping undef test_escape_html_true # Smarty Pants is *always* on, but doesn't support it fully undef test_smarty_pants undef test_smarty_pants_false undef test_smarty_pants_true end rescue LoadError => boom # It should already be warned in the main tests end begin require 'maruku' class MarkdownMarukuTest < Test::Unit::TestCase include MarkdownTests template Tilt::MarukuTemplate # Doesn't support escaping undef test_escape_html_true # Doesn't support Smarty Pants, and even fails on ``Foobar'' undef test_smarty_pants undef test_smarty_pants_false undef test_smarty_pants_true # Smart Quotes is always on undef test_smart_quotes undef test_smart_quotes_false end rescue LoadError => boom # It should already be warned in the main tests end rescue LoadError warn "Markdown tests need Nokogiri" end tilt-1.4.1/test/tilt_template_test.rb0000644000004100000410000002202312162124415017730 0ustar www-datawww-data# coding: utf-8 require 'contest' require 'tilt' require 'tempfile' class TiltTemplateTest < Test::Unit::TestCase class MockTemplate < Tilt::Template def prepare end end test "needs a file or block" do assert_raise(ArgumentError) { Tilt::Template.new } end test "initializing with a file" do inst = MockTemplate.new('foo.erb') {} assert_equal 'foo.erb', inst.file end test "initializing with a file and line" do inst = MockTemplate.new('foo.erb', 55) {} assert_equal 'foo.erb', inst.file assert_equal 55, inst.line end test "initializing with a tempfile" do tempfile = Tempfile.new('tilt_template_test') inst = MockTemplate.new(tempfile) assert_equal File.basename(tempfile.path), inst.basename end class SillyHash < Hash def path(arg) end end test "initialize with hash that implements #path" do options = SillyHash[:key => :value] inst = MockTemplate.new(options) {} assert_equal :value, inst.options[:key] end test "uses correct eval_file" do inst = MockTemplate.new('foo.erb', 55) {} assert_equal 'foo.erb', inst.eval_file end test "uses a default filename for #eval_file when no file provided" do inst = MockTemplate.new { 'Hi' } assert_not_nil inst.eval_file assert !inst.eval_file.include?("\n") end test "calculating template's #basename" do inst = MockTemplate.new('/tmp/templates/foo.html.erb') {} assert_equal 'foo.html.erb', inst.basename end test "calculating the template's #name" do inst = MockTemplate.new('/tmp/templates/foo.html.erb') {} assert_equal 'foo', inst.name end test "initializing with a data loading block" do MockTemplate.new { |template| "Hello World!" } end class InitializingMockTemplate < Tilt::Template @@initialized_count = 0 def self.initialized_count @@initialized_count end def initialize_engine @@initialized_count += 1 end def prepare end end test "one-time template engine initialization" do assert_nil InitializingMockTemplate.engine_initialized assert_equal 0, InitializingMockTemplate.initialized_count InitializingMockTemplate.new { "Hello World!" } assert InitializingMockTemplate.engine_initialized assert_equal 1, InitializingMockTemplate.initialized_count InitializingMockTemplate.new { "Hello World!" } assert_equal 1, InitializingMockTemplate.initialized_count end class PreparingMockTemplate < Tilt::Template include Test::Unit::Assertions def prepare assert !data.nil? @prepared = true end def prepared? ; @prepared ; end end test "raises NotImplementedError when #prepare not defined" do assert_raise(NotImplementedError) { Tilt::Template.new { |template| "Hello World!" } } end test "raises NotImplementedError when #evaluate or #template_source not defined" do inst = PreparingMockTemplate.new { |t| "Hello World!" } assert_raise(NotImplementedError) { inst.render } assert inst.prepared? end class SimpleMockTemplate < PreparingMockTemplate include Test::Unit::Assertions def evaluate(scope, locals, &block) assert prepared? assert !scope.nil? assert !locals.nil? "#{@data}" end end test "prepares and evaluates the template on #render" do inst = SimpleMockTemplate.new { |t| "Hello World!" } assert_equal "Hello World!", inst.render assert inst.prepared? end class SourceGeneratingMockTemplate < PreparingMockTemplate def precompiled_template(locals) "foo = [] ; foo << %Q{#{data}} ; foo.join" end end test "template_source with locals" do inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{name}!' } assert_equal "Hey Joe!", inst.render(Object.new, :name => 'Joe') assert inst.prepared? end test "template_source with locals of strings" do inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{name}!' } assert_equal "Hey Joe!", inst.render(Object.new, 'name' => 'Joe') assert inst.prepared? end test "template_source with locals having non-variable keys raises error" do inst = SourceGeneratingMockTemplate.new { |t| '1 + 2 = #{_answer}' } err = assert_raise(RuntimeError) { inst.render(Object.new, 'ANSWER' => 3) } assert_equal "invalid locals key: \"ANSWER\" (keys must be variable names)", err.message assert_equal "1 + 2 = 3", inst.render(Object.new, '_answer' => 3) end class CustomGeneratingMockTemplate < PreparingMockTemplate def precompiled_template(locals) data end def precompiled_preamble(locals) options.fetch(:preamble) end def precompiled_postamble(locals) options.fetch(:postamble) end end test "supports pre/postamble" do inst = CustomGeneratingMockTemplate.new( :preamble => 'buf = []', :postamble => 'buf.join' ) { 'buf << 1' } assert_equal "1", inst.render end # Special-case for Haml # https://github.com/rtomayko/tilt/issues/193 test "supports Array pre/postambles" do inst = CustomGeneratingMockTemplate.new( :preamble => ['buf = ', '[]'], :postamble => ['buf.', 'join'] ) { 'buf << 1' } # TODO: Use assert_output when we swicth to MiniTest warns = <<-EOF precompiled_preamble should return String (not Array) precompiled_postamble should return String (not Array) EOF begin require 'stringio' $stderr = StringIO.new assert_equal "1", inst.render assert_equal warns, $stderr.string ensure $stderr = STDERR end end class Person CONSTANT = "Bob" attr_accessor :name def initialize(name) @name = name end end test "template_source with an object scope" do inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{@name}!' } scope = Person.new('Joe') assert_equal "Hey Joe!", inst.render(scope) end test "template_source with a block for yield" do inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{yield}!' } assert_equal "Hey Joe!", inst.render(Object.new){ 'Joe' } end test "template which accesses a constant" do inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{CONSTANT}!' } assert_equal "Hey Bob!", inst.render(Person.new("Joe")) end ## # Encodings class DynamicMockTemplate < MockTemplate def precompiled_template(locals) options[:code] end end class UTF8Template < MockTemplate def default_encoding Encoding::UTF_8 end end if ''.respond_to?(:encoding) original_encoding = Encoding.default_external setup do @file = Tempfile.open('template') @file.puts "stuff" @file.close @template = @file.path end teardown do Encoding.default_external = original_encoding Encoding.default_internal = nil @file.delete end test "reading from file assumes default external encoding" do Encoding.default_external = 'Big5' inst = MockTemplate.new(@template) assert_equal 'Big5', inst.data.encoding.to_s end test "reading from file with a :default_encoding overrides default external" do Encoding.default_external = 'Big5' inst = MockTemplate.new(@template, :default_encoding => 'GBK') assert_equal 'GBK', inst.data.encoding.to_s end test "reading from file with default_internal set does no transcoding" do Encoding.default_internal = 'utf-8' Encoding.default_external = 'Big5' inst = MockTemplate.new(@template) assert_equal 'Big5', inst.data.encoding.to_s end test "using provided template data verbatim when given as string" do Encoding.default_internal = 'Big5' inst = MockTemplate.new(@template) { "blah".force_encoding('GBK') } assert_equal 'GBK', inst.data.encoding.to_s end test "uses the template from the generated source code" do tmpl = "ふが" code = tmpl.inspect.encode('Shift_JIS') inst = DynamicMockTemplate.new(:code => code) { '' } res = inst.render assert_equal 'Shift_JIS', res.encoding.to_s assert_equal tmpl, res.encode(tmpl.encoding) end test "uses the magic comment from the generated source code" do tmpl = "ふが" code = ("# coding: Shift_JIS\n" + tmpl.inspect).encode('Shift_JIS') # Set it to an incorrect encoding code.force_encoding('UTF-8') inst = DynamicMockTemplate.new(:code => code) { '' } res = inst.render assert_equal 'Shift_JIS', res.encoding.to_s assert_equal tmpl, res.encode(tmpl.encoding) end test "uses #default_encoding instead of default_external" do Encoding.default_external = 'Big5' inst = UTF8Template.new(@template) assert_equal 'UTF-8', inst.data.encoding.to_s end test "uses #default_encoding instead of current encoding" do tmpl = "".force_encoding('Big5') inst = UTF8Template.new(@template) { tmpl } assert_equal 'UTF-8', inst.data.encoding.to_s end test "raises error if the encoding is not valid" do assert_raises(Encoding::InvalidByteSequenceError) do UTF8Template.new(@template) { "\xe4" } end end end end tilt-1.4.1/test/tilt_fallback_test.rb0000644000004100000410000000604012162124415017655 0ustar www-datawww-datarequire 'contest' require 'tilt' class TiltFallbackTest < Test::Unit::TestCase class FailTemplate < Tilt::Template def self.engine_initialized?; false end def prepare; end def initialize_engine raise LoadError, "can't load #{self.class}" end end class WinTemplate < Tilt::Template def self.engine_initialized?; true end def prepare; end end FailTemplate2 = Class.new(FailTemplate) WinTemplate2 = Class.new(WinTemplate) def set_ivar(obj, name, value) obj.instance_variable_set("@#{name}", value) end def clear_ivar(obj, name) ivar = "@#{name}" value = obj.instance_variable_get(ivar) ensure obj.instance_variable_set(ivar, value.dup.clear) end setup do # Make sure every test have no mappings. @p = clear_ivar(Tilt, :preferred_mappings) @t = clear_ivar(Tilt, :template_mappings) end teardown do set_ivar(Tilt, :preferred_mappings, @p) set_ivar(Tilt, :template_mappings, @t) end test "returns nil on unregistered extensions" do template = Tilt["md"] assert_equal nil, template end test "returns the last registered template" do Tilt.register("md", WinTemplate) Tilt.register("md", WinTemplate2) template = Tilt["md"] assert_equal WinTemplate2, template end test "returns the last registered working template" do Tilt.register("md", WinTemplate) Tilt.register("md", FailTemplate) template = Tilt["md"] assert_equal WinTemplate, template end test "if every template fails, raise the exception from the first template" do Tilt.register("md", FailTemplate) Tilt.register("md", FailTemplate2) exc = assert_raise(LoadError) { Tilt["md"] } assert_match /FailTemplate2/, exc.message end test ".prefer should also register the template" do Tilt.prefer(WinTemplate, "md") assert Tilt.registered?("md") end test ".prefer always win" do Tilt.register("md", FailTemplate) Tilt.register("md", WinTemplate) Tilt.prefer(FailTemplate, "md") template = Tilt["md"] assert_equal FailTemplate, template end test ".prefer accepts multiple extensions" do extensions = %w[md mkd markdown] Tilt.prefer(FailTemplate, *extensions) extensions.each do |ext| template = Tilt[ext] assert_equal FailTemplate, template end end test ".prefer with no extension should use already registered extensions" do extensions = %w[md mkd markdown] extensions.each do |ext| Tilt.register(ext, FailTemplate) Tilt.register(ext, WinTemplate) end Tilt.prefer(FailTemplate) extensions.each do |ext| template = Tilt[ext] assert_equal FailTemplate, template end end test ".prefer should only override extensions the preferred library is registered for" do Tilt.register("md", WinTemplate) Tilt.register("mkd", FailTemplate) Tilt.register("mkd", WinTemplate) Tilt.prefer(FailTemplate) assert_equal FailTemplate, Tilt["mkd"] assert_equal WinTemplate, Tilt["md"] end end tilt-1.4.1/test/tilt_yajltemplate_test.rb0000644000004100000410000000655712162124415020626 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'yajl' class YajlTemplateTest < Test::Unit::TestCase test "is registered for '.yajl' files" do assert_equal Tilt::YajlTemplate, Tilt['test.yajl'] end test "compiles and evaluates the template on #render" do template = Tilt::YajlTemplate.new { "json = { :integer => 3, :string => 'hello' }" } output = template.render result = Yajl::Parser.parse(output) expect = {"integer" => 3,"string" => "hello"} assert_equal expect, result end test "can be rendered more than once" do template = Tilt::YajlTemplate.new { "json = { :integer => 3, :string => 'hello' }" } expect = {"integer" => 3,"string" => "hello"} 3.times do output = template.render result = Yajl::Parser.parse(output) assert_equal expect, result end end test "evaluating ruby code" do template = Tilt::YajlTemplate.new { "json = { :integer => (3 * 2) }" } assert_equal '{"integer":6}', template.render end test "evaluating in an object scope" do template = Tilt::YajlTemplate.new { "json = { :string => 'Hey ' + @name + '!' }" } scope = Object.new scope.instance_variable_set :@name, 'Joe' assert_equal '{"string":"Hey Joe!"}', template.render(scope) end test "passing locals" do template = Tilt::YajlTemplate.new { "json = { :string => 'Hey ' + name + '!' }" } assert_equal '{"string":"Hey Joe!"}', template.render(Object.new, :name => 'Joe') end test "passing a block for yield" do template = Tilt::YajlTemplate.new { "json = { :string => 'Hey ' + yield + '!' }" } assert_equal '{"string":"Hey Joe!"}', template.render { 'Joe' } assert_equal '{"string":"Hey Moe!"}', template.render { 'Moe' } end test "template multiline" do template = Tilt::YajlTemplate.new { %Q{ json = { :string => "hello" } } } assert_equal '{"string":"hello"}', template.render end test "template can reuse existing json buffer" do template = Tilt::YajlTemplate.new { "json.merge! :string => 'hello'" } assert_equal '{"string":"hello"}', template.render end test "template can end with any statement" do template = Tilt::YajlTemplate.new { %Q{ json = { :string => "hello" } four = 2 * 2 json[:integer] = four nil } } result = template.render assert( (result == '{"string":"hello","integer":4}') || (result == '{"integer":4,"string":"hello"}') ) end test "option callback" do options = { :callback => 'foo' } template = Tilt::YajlTemplate.new(nil, options) { "json = { :string => 'hello' }" } assert_equal 'foo({"string":"hello"});', template.render end test "option variable" do options = { :variable => 'output' } template = Tilt::YajlTemplate.new(nil, options) { "json = { :string => 'hello' }" } assert_equal 'var output = {"string":"hello"};', template.render end test "option callback and variable" do options = { :callback => 'foo', :variable => 'output' } template = Tilt::YajlTemplate.new(nil, options) { "json = { :string => 'hello' }" } assert_equal 'var output = {"string":"hello"}; foo(output);', template.render end end rescue LoadError warn "Tilt::YajlTemplateTest (disabled)" end tilt-1.4.1/test/tilt_markaby_test.rb0000644000004100000410000000542712162124415017554 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'markaby' class MarkabyTiltTest < Test::Unit::TestCase def setup @block = lambda do |t| File.read(File.dirname(__FILE__) + "/#{t.file}") end end test "should be able to render a markaby template with static html" do tilt = Tilt::MarkabyTemplate.new("markaby/markaby.mab", &@block) assert_equal "hello from markaby!", tilt.render end test "should use the contents of the template" do tilt = ::Tilt::MarkabyTemplate.new("markaby/markaby_other_static.mab", &@block) assert_equal "_why?", tilt.render end test "should render from a string (given as data)" do tilt = ::Tilt::MarkabyTemplate.new { "html do; end" } assert_equal "", tilt.render end test "can be rendered more than once" do tilt = ::Tilt::MarkabyTemplate.new { "html do; end" } 3.times { assert_equal "", tilt.render } end test "should evaluate a template file in the scope given" do scope = Object.new def scope.foo "bar" end tilt = ::Tilt::MarkabyTemplate.new("markaby/scope.mab", &@block) assert_equal "
  • bar
  • ", tilt.render(scope) end test "should pass locals to the template" do tilt = ::Tilt::MarkabyTemplate.new("markaby/locals.mab", &@block) assert_equal "
  • bar
  • ", tilt.render(Object.new, { :foo => "bar" }) end test "should yield to the block given" do tilt = ::Tilt::MarkabyTemplate.new("markaby/yielding.mab", &@block) eval_scope = Markaby::Builder.new output = tilt.render(Object.new, {}) do text("Joe") end assert_equal "Hey Joe", output end test "should be able to render two templates in a row" do tilt = ::Tilt::MarkabyTemplate.new("markaby/render_twice.mab", &@block) assert_equal "foo", tilt.render assert_equal "foo", tilt.render end test "should retrieve a Tilt::MarkabyTemplate when calling Tilt['hello.mab']" do assert_equal Tilt::MarkabyTemplate, ::Tilt['./markaby/markaby.mab'] end test "should return a new instance of the implementation class (when calling Tilt.new)" do assert ::Tilt.new(File.dirname(__FILE__) + "/markaby/markaby.mab").kind_of?(Tilt::MarkabyTemplate) end test "should be able to evaluate block style templates" do tilt = Tilt::MarkabyTemplate.new { |t| lambda { h1 "Hello World!" }} assert_equal "

    Hello World!

    ", tilt.render end test "should pass locals to block style templates" do tilt = Tilt::MarkabyTemplate.new { |t| lambda { h1 "Hello #{name}!" }} assert_equal "

    Hello _why!

    ", tilt.render(nil, :name => "_why") end end rescue LoadError => boom warn "Tilt::MarkabyTemplate (disabled)" endtilt-1.4.1/test/tilt_hamltemplate_test.rb0000644000004100000410000001103612162124415020574 0ustar www-datawww-datarequire 'contest' require 'tilt' begin class ::MockError < NameError end require 'haml' class HamlTemplateTest < Test::Unit::TestCase test "registered for '.haml' files" do assert_equal Tilt::HamlTemplate, Tilt['test.haml'] end test "preparing and evaluating templates on #render" do template = Tilt::HamlTemplate.new { |t| "%p Hello World!" } assert_equal "

    Hello World!

    \n", template.render end test "can be rendered more than once" do template = Tilt::HamlTemplate.new { |t| "%p Hello World!" } 3.times { assert_equal "

    Hello World!

    \n", template.render } end test "passing locals" do template = Tilt::HamlTemplate.new { "%p= 'Hey ' + name + '!'" } assert_equal "

    Hey Joe!

    \n", template.render(Object.new, :name => 'Joe') end test "evaluating in an object scope" do template = Tilt::HamlTemplate.new { "%p= 'Hey ' + @name + '!'" } scope = Object.new scope.instance_variable_set :@name, 'Joe' assert_equal "

    Hey Joe!

    \n", template.render(scope) end test "passing a block for yield" do template = Tilt::HamlTemplate.new { "%p= 'Hey ' + yield + '!'" } assert_equal "

    Hey Joe!

    \n", template.render { 'Joe' } end test "backtrace file and line reporting without locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?% template = Tilt::HamlTemplate.new('test.haml', 10) { data } begin template.render fail 'should have raised an exception' rescue => boom assert_kind_of NameError, boom line = boom.backtrace.grep(/^test\.haml:/).first assert line, "Backtrace didn't contain test.haml" file, line, meth = line.split(":") assert_equal '12', line end end test "backtrace file and line reporting with locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?% template = Tilt::HamlTemplate.new('test.haml') { data } begin res = template.render(Object.new, :name => 'Joe', :foo => 'bar') rescue => boom assert_kind_of MockError, boom line = boom.backtrace.first file, line, meth = line.split(":") assert_equal 'test.haml', file assert_equal '5', line end end end class CompiledHamlTemplateTest < Test::Unit::TestCase class Scope end test "compiling template source to a method" do template = Tilt::HamlTemplate.new { |t| "Hello World!" } template.render(Scope.new) method = template.send(:compiled_method, []) assert_kind_of UnboundMethod, method end test "passing locals" do template = Tilt::HamlTemplate.new { "%p= 'Hey ' + name + '!'" } assert_equal "

    Hey Joe!

    \n", template.render(Scope.new, :name => 'Joe') end test "evaluating in an object scope" do template = Tilt::HamlTemplate.new { "%p= 'Hey ' + @name + '!'" } scope = Scope.new scope.instance_variable_set :@name, 'Joe' assert_equal "

    Hey Joe!

    \n", template.render(scope) end test "passing a block for yield" do template = Tilt::HamlTemplate.new { "%p= 'Hey ' + yield + '!'" } assert_equal "

    Hey Joe!

    \n", template.render(Scope.new) { 'Joe' } end test "backtrace file and line reporting without locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?% template = Tilt::HamlTemplate.new('test.haml', 10) { data } begin template.render(Scope.new) fail 'should have raised an exception' rescue => boom assert_kind_of NameError, boom line = boom.backtrace.grep(/^test\.haml:/).first assert line, "Backtrace didn't contain test.haml" file, line, meth = line.split(":") assert_equal '12', line end end test "backtrace file and line reporting with locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?% template = Tilt::HamlTemplate.new('test.haml') { data } begin res = template.render(Scope.new, :name => 'Joe', :foo => 'bar') rescue => boom assert_kind_of MockError, boom line = boom.backtrace.first file, line, meth = line.split(":") assert_equal 'test.haml', file assert_equal '5', line end end end rescue LoadError => boom warn "Tilt::HamlTemplate (disabled)" end __END__ %html %body %h1= "Hey #{name}" = raise MockError %p we never get here tilt-1.4.1/test/tilt_rdoctemplate_test.rb0000644000004100000410000000155312162124415020605 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'rdoc' require 'rdoc/markup' require 'rdoc/markup/to_html' class RDocTemplateTest < Test::Unit::TestCase test "is registered for '.rdoc' files" do assert_equal Tilt::RDocTemplate, Tilt['test.rdoc'] end test "preparing and evaluating the template with #render" do template = Tilt::RDocTemplate.new { |t| "= Hello World!" } result = template.render.strip assert_match /

    Hello World!Hello World! boom warn "Tilt::RDocTemplate (disabled) [#{boom}]" end tilt-1.4.1/test/tilt_blueclothtemplate_test.rb0000644000004100000410000000266612162124415021645 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'bluecloth' class BlueClothTemplateTest < Test::Unit::TestCase test "registered for '.md' files" do assert Tilt.mappings['md'].include?(Tilt::BlueClothTemplate) end test "registered for '.mkd' files" do assert Tilt.mappings['mkd'].include?(Tilt::BlueClothTemplate) end test "registered for '.markdown' files" do assert Tilt.mappings['markdown'].include?(Tilt::BlueClothTemplate) end test "preparing and evaluating templates on #render" do template = Tilt::BlueClothTemplate.new { |t| "# Hello World!" } assert_equal "

    Hello World!

    ", template.render end test "can be rendered more than once" do template = Tilt::BlueClothTemplate.new { |t| "# Hello World!" } 3.times { assert_equal "

    Hello World!

    ", template.render } end test "smartypants when :smart is set" do template = Tilt::BlueClothTemplate.new(:smartypants => true) { |t| "OKAY -- 'Smarty Pants'" } assert_equal "

    OKAY — ‘Smarty Pants’

    ", template.render end test "stripping HTML when :filter_html is set" do template = Tilt::BlueClothTemplate.new(:escape_html => true) { |t| "HELLO WORLD" } assert_equal "

    HELLO <blink>WORLD</blink>

    ", template.render end end rescue LoadError => boom warn "Tilt::BlueClothTemplate (disabled)" end tilt-1.4.1/test/tilt_liquidtemplate_test.rb0000644000004100000410000000457012162124415021147 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'liquid' class LiquidTemplateTest < Test::Unit::TestCase test "registered for '.liquid' files" do assert_equal Tilt::LiquidTemplate, Tilt['test.liquid'] end test "preparing and evaluating templates on #render" do template = Tilt::LiquidTemplate.new { |t| "Hello World!" } assert_equal "Hello World!", template.render end test "can be rendered more than once" do template = Tilt::LiquidTemplate.new { |t| "Hello World!" } 3.times { assert_equal "Hello World!", template.render } end test "passing locals" do template = Tilt::LiquidTemplate.new { "Hey {{ name }}!" } assert_equal "Hey Joe!", template.render(nil, :name => 'Joe') end # Object's passed as "scope" to LiquidTemplate may respond to # #to_h with a Hash. The Hash's contents are merged underneath # Tilt locals. class ExampleLiquidScope def to_h { :beer => 'wet', :whisky => 'wetter' } end end test "combining scope and locals when scope responds to #to_h" do template = Tilt::LiquidTemplate.new { 'Beer is {{ beer }} but Whisky is {{ whisky }}.' } scope = ExampleLiquidScope.new assert_equal "Beer is wet but Whisky is wetter.", template.render(scope) end test "precedence when locals and scope define same variables" do template = Tilt::LiquidTemplate.new { 'Beer is {{ beer }} but Whisky is {{ whisky }}.' } scope = ExampleLiquidScope.new assert_equal "Beer is great but Whisky is greater.", template.render(scope, :beer => 'great', :whisky => 'greater') end # Object's passed as "scope" to LiquidTemplate that do not # respond to #to_h are silently ignored. class ExampleIgnoredLiquidScope end test "handling scopes that do not respond to #to_h" do template = Tilt::LiquidTemplate.new { 'Whisky' } scope = ExampleIgnoredLiquidScope.new assert_equal "Whisky", template.render(scope) end test "passing a block for yield" do template = Tilt::LiquidTemplate.new { 'Beer is {{ yield }} but Whisky is {{ content }}ter.' } assert_equal "Beer is wet but Whisky is wetter.", template.render({}) { 'wet' } end end rescue LoadError => boom warn "Tilt::LiquidTemplate (disabled)" end tilt-1.4.1/test/tilt_rdiscounttemplate_test.rb0000644000004100000410000000342512162124415021670 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'rdiscount' class RDiscountTemplateTest < Test::Unit::TestCase test "registered for '.md' files" do assert Tilt.mappings['md'].include?(Tilt::RDiscountTemplate) end test "registered for '.mkd' files" do assert Tilt.mappings['mkd'].include?(Tilt::RDiscountTemplate) end test "registered for '.markdown' files" do assert Tilt.mappings['markdown'].include?(Tilt::RDiscountTemplate) end test "registered above BlueCloth" do %w[md mkd markdown].each do |ext| mappings = Tilt.mappings[ext] blue_idx = mappings.index(Tilt::BlueClothTemplate) rdis_idx = mappings.index(Tilt::RDiscountTemplate) assert rdis_idx < blue_idx, "#{rdis_idx} should be lower than #{blue_idx}" end end test "preparing and evaluating templates on #render" do template = Tilt::RDiscountTemplate.new { |t| "# Hello World!" } assert_equal "

    Hello World!

    \n", template.render end test "can be rendered more than once" do template = Tilt::RDiscountTemplate.new { |t| "# Hello World!" } 3.times { assert_equal "

    Hello World!

    \n", template.render } end test "smartypants when :smart is set" do template = Tilt::RDiscountTemplate.new(:smart => true) { |t| "OKAY -- 'Smarty Pants'" } assert_equal "

    OKAY — ‘Smarty Pants’

    \n", template.render end test "stripping HTML when :filter_html is set" do template = Tilt::RDiscountTemplate.new(:filter_html => true) { |t| "HELLO WORLD" } assert_equal "

    HELLO <blink>WORLD</blink>

    \n", template.render end end rescue LoadError => boom warn "Tilt::RDiscountTemplate (disabled)" end tilt-1.4.1/test/tilt_radiustemplate_test.rb0000644000004100000410000000441012162124415021140 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'radius' # Disable radius tests under Ruby versions >= 1.9.1 since it's still buggy. # Remove when fixed upstream. raise LoadError if RUBY_VERSION >= "1.9.1" and Radius.version < "0.7" class RadiusTemplateTest < Test::Unit::TestCase test "registered for '.radius' files" do assert_equal Tilt::RadiusTemplate, Tilt['test.radius'] end test "preparing and evaluating templates on #render" do template = Tilt::RadiusTemplate.new { |t| "Hello World!" } assert_equal "Hello World!", template.render end test "can be rendered more than once" do template = Tilt::RadiusTemplate.new { |t| "Hello World!" } 3.times { assert_equal "Hello World!", template.render } end test "passing locals" do template = Tilt::RadiusTemplate.new { "Hey !" } assert_equal "Hey Joe!", template.render(nil, :name => 'Joe') end class ExampleRadiusScope def beer; 'wet'; end def whisky; 'wetter'; end end test "combining scope and locals when scope responds" do template = Tilt::RadiusTemplate.new { 'Beer is but Whisky is .' } scope = ExampleRadiusScope.new assert_equal "Beer is wet but Whisky is wetter.", template.render(scope) end test "precedence when locals and scope define same variables" do template = Tilt::RadiusTemplate.new { 'Beer is but Whisky is .' } scope = ExampleRadiusScope.new assert_equal "Beer is great but Whisky is greater.", template.render(scope, :beer => 'great', :whisky => 'greater') end #test "handles local scope" do # beer = 'wet' # whisky = 'wetter' # # template = Tilt::RadiusTemplate.new { # 'Beer is but Whisky is .' # } # assert_equal "Beer is wet but Whisky is wetter.", template.render(self) #end test "passing a block for yield" do template = Tilt::RadiusTemplate.new { 'Beer is but Whisky is ter.' } assert_equal "Beer is wet but Whisky is wetter.", template.render({}) { 'wet' } end end rescue LoadError => boom warn "Tilt::RadiusTemplate (disabled)" end tilt-1.4.1/test/tilt_csv_test.rb0000644000004100000410000000342212162124415016712 0ustar www-datawww-datarequire 'contest' require 'tilt' begin if RUBY_VERSION >= '1.9.0' require 'csv' else require 'fastercsv' end class CSVTemplateTest < Test::Unit::TestCase test "registered for '.rcsv' files" do assert Tilt.mappings['rcsv'].include?(Tilt::CSVTemplate) end test "compiles and evaluates the template on #render" do template = Tilt::CSVTemplate.new { "csv << ['hello', 'world']" } assert_equal "hello,world\n", template.render end test "can be rendered more than once" do template = Tilt::CSVTemplate.new { "csv << [1,2,3]" } 3.times { assert_equal "1,2,3\n", template.render } end test "can pass locals" do template = Tilt::CSVTemplate.new { 'csv << [1, name]' } assert_equal "1,Joe\n", template.render(Object.new, :name => 'Joe') end test "evaluating in an object scope" do template = Tilt::CSVTemplate.new { 'csv << [1, @name]' } scope = Object.new scope.instance_variable_set :@name, 'Joe' assert_equal "1,Joe\n", template.render(scope) end test "backtrace file and line reporting" do data = File.read(__FILE__).split("\n__END__\n").last template = Tilt::CSVTemplate.new('test.csv') { data } begin template.render fail 'should have raised an exception' rescue => boom assert_kind_of NameError, boom line = boom.backtrace.grep(/^test\.csv:/).first assert line, "Backtrace didn't contain test.csv" file, line, meth = line.split(":") assert_equal '4', line end end end rescue LoadError => boom warn "Tilt::CSVTemplate (disabled) please install 'fastercsv' if using ruby 1.8.x" end __END__ # header csv << ['Type', 'Age'] raise NameError # rows csv << ['Frog', 2] csv << ['Cat', 5]tilt-1.4.1/test/tilt_wikiclothtemplate_test.rb0000644000004100000410000000170112162124415021646 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'wikicloth' class WikiClothTemplateTest < Test::Unit::TestCase test "is registered for '.mediawiki' files" do assert_equal Tilt::WikiClothTemplate, Tilt['test.mediawiki'] end test "is registered for '.mw' files" do assert_equal Tilt::WikiClothTemplate, Tilt['test.mw'] end test "is registered for '.wiki' files" do assert_equal Tilt::WikiClothTemplate, Tilt['test.wiki'] end test "compiles and evaluates the template on #render" do template = Tilt::WikiClothTemplate.new { |t| "= Hello World! =" } assert_match /

    .*Hello World!.*<\/h1>/, template.render end test "can be rendered more than once" do template = Tilt::WikiClothTemplate.new { |t| "= Hello World! =" } 3.times { assert_match /

    .*Hello World!.*<\/h1>/, template.render } end end rescue LoadError => boom warn "Tilt::WikiClothTemplate (disabled)" end tilt-1.4.1/test/tilt_cache_test.rb0000644000004100000410000000210412162124415017156 0ustar www-datawww-datarequire 'contest' require 'tilt' class TiltCacheTest < Test::Unit::TestCase setup { @cache = Tilt::Cache.new } test "caching with single simple argument to #fetch" do template = nil result = @cache.fetch('hello') { template = Tilt::StringTemplate.new {''} } assert_same template, result result = @cache.fetch('hello') { fail 'should be cached' } assert_same template, result end test "caching with multiple complex arguments to #fetch" do template = nil result = @cache.fetch('hello', {:foo => 'bar', :baz => 'bizzle'}) { template = Tilt::StringTemplate.new {''} } assert_same template, result result = @cache.fetch('hello', {:foo => 'bar', :baz => 'bizzle'}) { fail 'should be cached' } assert_same template, result end test "clearing the cache with #clear" do template, other = nil result = @cache.fetch('hello') { template = Tilt::StringTemplate.new {''} } assert_same template, result @cache.clear result = @cache.fetch('hello') { other = Tilt::StringTemplate.new {''} } assert_same other, result end end tilt-1.4.1/test/contest.rb0000644000004100000410000000333312162124415015504 0ustar www-datawww-datarequire "test/unit" # Test::Unit loads a default test if the suite is empty, whose purpose is to # fail. Since having empty contexts is a common practice, we decided to # overwrite TestSuite#empty? in order to allow them. Having a failure when no # tests have been defined seems counter-intuitive. class Test::Unit::TestSuite def empty? false end end # Contest adds +teardown+, +test+ and +context+ as class methods, and the # instance methods +setup+ and +teardown+ now iterate on the corresponding # blocks. Note that all setup and teardown blocks must be defined with the # block syntax. Adding setup or teardown instance methods defeats the purpose # of this library. class Test::Unit::TestCase def self.setup(&block) define_method :setup do super(&block) instance_eval(&block) end end def self.teardown(&block) define_method :teardown do instance_eval(&block) super(&block) end end def self.context(name, &block) subclass = Class.new(self) remove_tests(subclass) subclass.class_eval(&block) if block_given? const_set(context_name(name), subclass) end def self.test(name, &block) define_method(test_name(name), &block) end class << self alias_method :should, :test alias_method :describe, :context end private def self.context_name(name) "Test#{sanitize_name(name).gsub(/(^| )(\w)/) { $2.upcase }}".to_sym end def self.test_name(name) "test_#{sanitize_name(name).gsub(/\s+/,'_')}".to_sym end def self.sanitize_name(name) name.gsub(/\W+/, ' ').strip end def self.remove_tests(subclass) subclass.public_instance_methods.grep(/^test_/).each do |meth| subclass.send(:undef_method, meth.to_sym) end end end tilt-1.4.1/test/tilt_redcarpettemplate_test.rb0000644000004100000410000000455512162124415021634 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'redcarpet' class RedcarpetTemplateTest < Test::Unit::TestCase test "registered for '.md' files" do assert Tilt.mappings['md'].include?(Tilt::RedcarpetTemplate) end test "registered for '.mkd' files" do assert Tilt.mappings['mkd'].include?(Tilt::RedcarpetTemplate) end test "registered for '.markdown' files" do assert Tilt.mappings['markdown'].include?(Tilt::RedcarpetTemplate) end test "registered above BlueCloth" do %w[md mkd markdown].each do |ext| mappings = Tilt.mappings[ext] blue_idx = mappings.index(Tilt::BlueClothTemplate) redc_idx = mappings.index(Tilt::RedcarpetTemplate) assert redc_idx < blue_idx, "#{redc_idx} should be lower than #{blue_idx}" end end test "registered above RDiscount" do %w[md mkd markdown].each do |ext| mappings = Tilt.mappings[ext] rdis_idx = mappings.index(Tilt::RDiscountTemplate) redc_idx = mappings.index(Tilt::RedcarpetTemplate) assert redc_idx < rdis_idx, "#{redc_idx} should be lower than #{rdis_idx}" end end test "redcarpet2 is our default choice" do template = Tilt::RedcarpetTemplate.new {} assert_equal Tilt::RedcarpetTemplate::Redcarpet2, template.prepare.class end test "preparing and evaluating templates on #render" do template = Tilt::RedcarpetTemplate.new { |t| "# Hello World!" } assert_equal "

    Hello World!

    \n", template.render end test "can be rendered more than once" do template = Tilt::RedcarpetTemplate.new { |t| "# Hello World!" } 3.times { assert_equal "

    Hello World!

    \n", template.render } end test "smartypants when :smart is set" do template = Tilt::RedcarpetTemplate.new(:smartypants => true) { |t| "OKAY -- 'Smarty Pants'" } assert_match /

    OKAY – 'Smarty Pants'<\/p>/, template.render end test "smartypants with a rendererer instance" do template = Tilt::RedcarpetTemplate.new(:renderer => Redcarpet::Render::HTML.new(:hard_wrap => true), :smartypants => true) { |t| "OKAY -- 'Smarty Pants'" } assert_match /

    OKAY – 'Smarty Pants'<\/p>/, template.render end end rescue LoadError => boom warn "Tilt::RedcarpetTemplate (disabled)" end tilt-1.4.1/test/tilt_nokogiritemplate_test.rb0000644000004100000410000000565712162124415021510 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'nokogiri' class NokogiriTemplateTest < Test::Unit::TestCase test "registered for '.nokogiri' files" do assert_equal Tilt::NokogiriTemplate, Tilt['test.nokogiri'] assert_equal Tilt::NokogiriTemplate, Tilt['test.xml.nokogiri'] end test "preparing and evaluating the template on #render" do template = Tilt::NokogiriTemplate.new { |t| "xml.em 'Hello World!'" } doc = Nokogiri.XML template.render assert_equal 'Hello World!', doc.root.text assert_equal 'em', doc.root.name end test "can be rendered more than once" do template = Tilt::NokogiriTemplate.new { |t| "xml.em 'Hello World!'" } 3.times do doc = Nokogiri.XML template.render assert_equal 'Hello World!', doc.root.text assert_equal 'em', doc.root.name end end test "passing locals" do template = Tilt::NokogiriTemplate.new { "xml.em('Hey ' + name + '!')" } doc = Nokogiri.XML template.render(Object.new, :name => 'Joe') assert_equal 'Hey Joe!', doc.root.text assert_equal 'em', doc.root.name end test "evaluating in an object scope" do template = Tilt::NokogiriTemplate.new { "xml.em('Hey ' + @name + '!')" } scope = Object.new scope.instance_variable_set :@name, 'Joe' doc = Nokogiri.XML template.render(scope) assert_equal 'Hey Joe!', doc.root.text assert_equal 'em', doc.root.name end test "passing a block for yield" do template = Tilt::NokogiriTemplate.new { "xml.em('Hey ' + yield + '!')" } 3.times do doc = Nokogiri.XML template.render { 'Joe' } assert_equal 'Hey Joe!', doc.root.text assert_equal 'em', doc.root.name end end test "block style templates" do template = Tilt::NokogiriTemplate.new do |t| lambda { |xml| xml.em('Hey Joe!') } end doc = Nokogiri.XML template.render assert_equal 'Hey Joe!', doc.root.text assert_equal 'em', doc.root.name end test "allows nesting raw XML, API-compatible to Builder" do subtemplate = Tilt::NokogiriTemplate.new { "xml.em 'Hello World!'" } template = Tilt::NokogiriTemplate.new { "xml.strong { xml << yield }" } 3.times do options = { :xml => Nokogiri::XML::Builder.new } doc = Nokogiri.XML(template.render(options) { subtemplate.render(options) }) assert_equal 'Hello World!', doc.root.text.strip assert_equal 'strong', doc.root.name end end test "doesn't modify self when template is a string" do template = Tilt::NokogiriTemplate.new { "xml.root { xml.child @hello }" } scope = Object.new scope.instance_variable_set(:@hello, "Hello World!") 3.times do doc = Nokogiri.XML(template.render(scope)) assert_equal "Hello World!", doc.text.strip end end end rescue LoadError warn "Tilt::NokogiriTemplate (disabled)" end tilt-1.4.1/test/tilt_compilesite_test.rb0000644000004100000410000000235312162124415020436 0ustar www-datawww-datarequire 'contest' require 'tilt' require 'thread' class CompileSiteTest < Test::Unit::TestCase def setup GC.start end class CompilingTemplate < Tilt::Template def prepare end def precompiled_template(locals) @data.inspect end end class Scope end test "compiling template source to a method" do template = CompilingTemplate.new { |t| "Hello World!" } template.render(Scope.new) method = template.send(:compiled_method, []) assert_kind_of UnboundMethod, method end # This test attempts to surface issues with compiling templates from # multiple threads. test "using compiled templates from multiple threads" do template = CompilingTemplate.new { 'template' } main_thread = Thread.current 10.times do |i| threads = (1..50).map do |j| Thread.new { begin locals = { "local#{i}" => 'value' } res = template.render(self, locals) thread_id = Thread.current.object_id res = template.render(self, "local#{thread_id.abs.to_s}" => 'value') rescue => boom main_thread.raise(boom) end } end threads.each { |t| t.join } end end end tilt-1.4.1/test/tilt_erbtemplate_test.rb0000644000004100000410000001652512162124415020433 0ustar www-datawww-data# coding: utf-8 require 'contest' require 'tilt' require 'erb' require 'tempfile' class ERBTemplateTest < Test::Unit::TestCase test "registered for '.erb' files" do assert Tilt.mappings['erb'].include?(Tilt::ERBTemplate) end test "registered for '.rhtml' files" do assert Tilt.mappings['rhtml'].include?(Tilt::ERBTemplate) end test "loading and evaluating templates on #render" do template = Tilt::ERBTemplate.new { |t| "Hello World!" } assert_equal "Hello World!", template.render end test "can be rendered more than once" do template = Tilt::ERBTemplate.new { |t| "Hello World!" } 3.times { assert_equal "Hello World!", template.render } end test "passing locals" do template = Tilt::ERBTemplate.new { 'Hey <%= name %>!' } assert_equal "Hey Joe!", template.render(Object.new, :name => 'Joe') end test "evaluating in an object scope" do template = Tilt::ERBTemplate.new { 'Hey <%= @name %>!' } scope = Object.new scope.instance_variable_set :@name, 'Joe' assert_equal "Hey Joe!", template.render(scope) end class MockOutputVariableScope attr_accessor :exposed_buffer end test "exposing the buffer to the template by default" do begin Tilt::ERBTemplate.default_output_variable = '@_out_buf' template = Tilt::ERBTemplate.new { '<% self.exposed_buffer = @_out_buf %>hey' } scope = MockOutputVariableScope.new template.render(scope) assert_not_nil scope.exposed_buffer assert_equal scope.exposed_buffer, 'hey' ensure Tilt::ERBTemplate.default_output_variable = '_erbout' end end test "passing a block for yield" do template = Tilt::ERBTemplate.new { 'Hey <%= yield %>!' } assert_equal "Hey Joe!", template.render { 'Joe' } end test "backtrace file and line reporting without locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::ERBTemplate.new('test.erb', 11) { data } begin template.render fail 'should have raised an exception' rescue => boom assert_kind_of NameError, boom line = boom.backtrace.grep(/^test\.erb:/).first assert line, "Backtrace didn't contain test.erb" file, line, meth = line.split(":") assert_equal '13', line end end test "backtrace file and line reporting with locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::ERBTemplate.new('test.erb', 1) { data } begin template.render(nil, :name => 'Joe', :foo => 'bar') fail 'should have raised an exception' rescue => boom assert_kind_of RuntimeError, boom line = boom.backtrace.first file, line, meth = line.split(":") assert_equal 'test.erb', file assert_equal '6', line end end test "explicit disabling of trim mode" do template = Tilt::ERBTemplate.new('test.erb', 1, :trim => false) { "\n<%= 1 + 1 %>\n" } assert_equal "\n2\n", template.render end test "default stripping trim mode" do template = Tilt::ERBTemplate.new('test.erb', 1) { "\n<%= 1 + 1 %>\n" } assert_equal "\n2", template.render end test "stripping trim mode" do template = Tilt::ERBTemplate.new('test.erb', 1, :trim => '-') { "\n<%= 1 + 1 -%>\n" } assert_equal "\n2", template.render end test "shorthand whole line syntax trim mode" do template = Tilt::ERBTemplate.new('test.erb', :trim => '%') { "\n% if true\nhello\n%end\n" } assert_equal "\nhello\n", template.render end test "using an instance variable as the outvar" do template = Tilt::ERBTemplate.new(nil, :outvar => '@buf') { "<%= 1 + 1 %>" } scope = Object.new scope.instance_variable_set(:@buf, 'original value') assert_equal '2', template.render(scope) assert_equal 'original value', scope.instance_variable_get(:@buf) end end class CompiledERBTemplateTest < Test::Unit::TestCase def teardown GC.start end class Scope end test "compiling template source to a method" do template = Tilt::ERBTemplate.new { |t| "Hello World!" } template.render(Scope.new) method = template.send(:compiled_method, []) assert_kind_of UnboundMethod, method end test "loading and evaluating templates on #render" do template = Tilt::ERBTemplate.new { |t| "Hello World!" } assert_equal "Hello World!", template.render(Scope.new) assert_equal "Hello World!", template.render(Scope.new) end test "passing locals" do template = Tilt::ERBTemplate.new { 'Hey <%= name %>!' } assert_equal "Hey Joe!", template.render(Scope.new, :name => 'Joe') end test "evaluating in an object scope" do template = Tilt::ERBTemplate.new { 'Hey <%= @name %>!' } scope = Scope.new scope.instance_variable_set :@name, 'Joe' assert_equal "Hey Joe!", template.render(scope) scope.instance_variable_set :@name, 'Jane' assert_equal "Hey Jane!", template.render(scope) end test "passing a block for yield" do template = Tilt::ERBTemplate.new { 'Hey <%= yield %>!' } assert_equal "Hey Joe!", template.render(Scope.new) { 'Joe' } assert_equal "Hey Jane!", template.render(Scope.new) { 'Jane' } end test "backtrace file and line reporting without locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::ERBTemplate.new('test.erb', 11) { data } begin template.render(Scope.new) fail 'should have raised an exception' rescue => boom assert_kind_of NameError, boom line = boom.backtrace.grep(/^test\.erb:/).first assert line, "Backtrace didn't contain test.erb" file, line, meth = line.split(":") assert_equal '13', line end end test "backtrace file and line reporting with locals" do data = File.read(__FILE__).split("\n__END__\n").last fail unless data[0] == ?< template = Tilt::ERBTemplate.new('test.erb') { data } begin template.render(Scope.new, :name => 'Joe', :foo => 'bar') fail 'should have raised an exception' rescue => boom assert_kind_of RuntimeError, boom line = boom.backtrace.first file, line, meth = line.split(":") assert_equal 'test.erb', file assert_equal '6', line end end test "default stripping trim mode" do template = Tilt::ERBTemplate.new('test.erb') { "\n<%= 1 + 1 %>\n" } assert_equal "\n2", template.render(Scope.new) end test "stripping trim mode" do template = Tilt::ERBTemplate.new('test.erb', :trim => '-') { "\n<%= 1 + 1 -%>\n" } assert_equal "\n2", template.render(Scope.new) end test "shorthand whole line syntax trim mode" do template = Tilt::ERBTemplate.new('test.erb', :trim => '%') { "\n% if true\nhello\n%end\n" } assert_equal "\nhello\n", template.render(Scope.new) end test "encoding with magic comment" do f = Tempfile.open("template") f.puts('<%# coding: UTF-8 %>') f.puts('ふが <%= @hoge %>') f.close() @hoge = "ほげ" erb = Tilt::ERBTemplate.new(f.path) 3.times { erb.render(self) } f.delete end test "encoding with :default_encoding" do f = Tempfile.open("template") f.puts('ふが <%= @hoge %>') f.close() @hoge = "ほげ" erb = Tilt::ERBTemplate.new(f.path, :default_encoding => 'UTF-8') 3.times { erb.render(self) } f.delete end end __END__

    Hey <%= name %>!

    <% fail %>

    tilt-1.4.1/test/tilt_asciidoctor_test.rb0000644000004100000410000000310412162124415020417 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'asciidoctor' class AsciidoctorTemplateTest < Test::Unit::TestCase HTML5_OUTPUT = "

    Hello World!

    " DOCBOOK_OUTPUT = "
    Hello World!
    " def strip_space(str) str.gsub(/>\s+<').strip end test "registered for '.ad' files" do assert Tilt.mappings['ad'].include?(Tilt::AsciidoctorTemplate) end test "registered for '.adoc' files" do assert Tilt.mappings['adoc'].include?(Tilt::AsciidoctorTemplate) end test "registered for '.asciidoc' files" do assert Tilt.mappings['asciidoc'].include?(Tilt::AsciidoctorTemplate) end test "preparing and evaluating html5 templates on #render" do template = Tilt::AsciidoctorTemplate.new(:attributes => {"backend" => 'html5'}) { |t| "== Hello World!" } assert_equal HTML5_OUTPUT, strip_space(template.render) end test "preparing and evaluating docbook templates on #render" do template = Tilt::AsciidoctorTemplate.new(:attributes => {"backend" => 'docbook'}) { |t| "== Hello World!" } assert_equal DOCBOOK_OUTPUT, strip_space(template.render) end test "can be rendered more than once" do template = Tilt::AsciidoctorTemplate.new(:attributes => {"backend" => 'html5'}) { |t| "== Hello World!" } 3.times { assert_equal HTML5_OUTPUT, strip_space(template.render) } end end rescue LoadError => boom warn "Tilt::AsciidoctorTemplate (disabled)" end tilt-1.4.1/test/tilt_coffeescripttemplate_test.rb0000644000004100000410000000777012162124415022341 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'coffee_script' class CoffeeScriptTemplateTest < Test::Unit::TestCase unless method_defined?(:assert_not_match) # assert_not_match is missing on 1.8.7, which uses assert_no_match def assert_not_match(a, b) unless a.kind_of?(Regexp) a = Regexp.new(Regexp.escape(a)) end assert_no_match(a,b) end end test "is registered for '.coffee' files" do assert_equal Tilt::CoffeeScriptTemplate, Tilt['test.coffee'] end test "bare is disabled by default" do assert_equal false, Tilt::CoffeeScriptTemplate.default_bare end test "compiles and evaluates the template on #render" do template = Tilt::CoffeeScriptTemplate.new { |t| "puts 'Hello, World!'\n" } assert_match "puts('Hello, World!');", template.render end test "can be rendered more than once" do template = Tilt::CoffeeScriptTemplate.new { |t| "puts 'Hello, World!'\n" } 3.times { assert_match "puts('Hello, World!');", template.render } end test "disabling coffee-script wrapper" do str = 'name = "Josh"; puts "Hello #{name}"' template = Tilt::CoffeeScriptTemplate.new { str } assert_match "(function() {", template.render assert_match "puts(\"Hello \" + name);\n", template.render template = Tilt::CoffeeScriptTemplate.new(:bare => true) { str } assert_not_match "(function() {", template.render assert_equal "var name;\n\nname = \"Josh\";\n\nputs(\"Hello \" + name);\n", template.render template2 = Tilt::CoffeeScriptTemplate.new(:no_wrap => true) { str} assert_not_match "(function() {", template.render assert_equal "var name;\n\nname = \"Josh\";\n\nputs(\"Hello \" + name);\n", template.render end context "wrapper globally enabled" do setup do @bare = Tilt::CoffeeScriptTemplate.default_bare Tilt::CoffeeScriptTemplate.default_bare = false end teardown do Tilt::CoffeeScriptTemplate.default_bare = @bare end test "no options" do template = Tilt::CoffeeScriptTemplate.new { |t| 'name = "Josh"; puts "Hello, #{name}"' } assert_match "puts(\"Hello, \" + name);", template.render assert_match "(function() {", template.render end test "overridden by :bare" do template = Tilt::CoffeeScriptTemplate.new(:bare => true) { |t| 'name = "Josh"; puts "Hello, #{name}"' } assert_match "puts(\"Hello, \" + name);", template.render assert_not_match "(function() {", template.render end test "overridden by :no_wrap" do template = Tilt::CoffeeScriptTemplate.new(:no_wrap => true) { |t| 'name = "Josh"; puts "Hello, #{name}"' } assert_match "puts(\"Hello, \" + name);", template.render assert_not_match "(function() {", template.render end end context "wrapper globally disabled" do setup do @bare = Tilt::CoffeeScriptTemplate.default_bare Tilt::CoffeeScriptTemplate.default_bare = true end teardown do Tilt::CoffeeScriptTemplate.default_bare = @bare end test "no options" do template = Tilt::CoffeeScriptTemplate.new { |t| 'name = "Josh"; puts "Hello, #{name}"' } assert_match "puts(\"Hello, \" + name);", template.render assert_not_match "(function() {", template.render end test "overridden by :bare" do template = Tilt::CoffeeScriptTemplate.new(:bare => false) { |t| 'name = "Josh"; puts "Hello, #{name}"' } assert_match "puts(\"Hello, \" + name);", template.render assert_match "(function() {", template.render end test "overridden by :no_wrap" do template = Tilt::CoffeeScriptTemplate.new(:no_wrap => false) { |t| 'name = "Josh"; puts "Hello, #{name}"' } assert_match "puts(\"Hello, \" + name);", template.render assert_match "(function() {", template.render end end end rescue LoadError => boom warn "Tilt::CoffeeScriptTemplate (disabled)" end tilt-1.4.1/test/tilt_lesstemplate_test.rb0000644000004100000410000000253012162124415020620 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'pathname' require 'less' class LessTemplateTest < Test::Unit::TestCase def assert_similar(a, b) assert_equal a.gsub(/\s+/m, ' '), b.gsub(/\s+/m, ' ') end test "is registered for '.less' files" do assert_equal Tilt::LessTemplate, Tilt['test.less'] end test "compiles and evaluates the template on #render" do template = Tilt::LessTemplate.new { |t| ".bg { background-color: #0000ff; } \n#main\n { .bg; }\n" } assert_similar ".bg {\n background-color: #0000ff;\n}\n#main {\n background-color: #0000ff;\n}\n", template.render end test "can be rendered more than once" do template = Tilt::LessTemplate.new { |t| ".bg { background-color: #0000ff; } \n#main\n { .bg; }\n" } 3.times { assert_similar ".bg {\n background-color: #0000ff;\n}\n#main {\n background-color: #0000ff;\n}\n", template.render } end test "can be passed a load path" do template = Tilt::LessTemplate.new({ :paths => [Pathname(__FILE__).dirname] }) { <<-EOLESS @import 'tilt_lesstemplate_test.less'; .bg {background-color: @text-color;} EOLESS } assert_similar ".bg {\n background-color: #ffc0cb;\n}\n", template.render end end rescue LoadError => boom warn "Tilt::LessTemplate (disabled)" end tilt-1.4.1/test/tilt_buildertemplate_test.rb0000644000004100000410000000404412162124415021302 0ustar www-datawww-datarequire 'contest' require 'tilt' begin require 'builder' class BuilderTemplateTest < Test::Unit::TestCase test "registered for '.builder' files" do assert_equal Tilt::BuilderTemplate, Tilt['test.builder'] assert_equal Tilt::BuilderTemplate, Tilt['test.xml.builder'] end test "preparing and evaluating the template on #render" do template = Tilt::BuilderTemplate.new { |t| "xml.em 'Hello World!'" } assert_equal "Hello World!\n", template.render end test "can be rendered more than once" do template = Tilt::BuilderTemplate.new { |t| "xml.em 'Hello World!'" } 3.times { assert_equal "Hello World!\n", template.render } end test "passing locals" do template = Tilt::BuilderTemplate.new { "xml.em('Hey ' + name + '!')" } assert_equal "Hey Joe!\n", template.render(Object.new, :name => 'Joe') end test "evaluating in an object scope" do template = Tilt::BuilderTemplate.new { "xml.em('Hey ' + @name + '!')" } scope = Object.new scope.instance_variable_set :@name, 'Joe' assert_equal "Hey Joe!\n", template.render(scope) end test "passing a block for yield" do template = Tilt::BuilderTemplate.new { "xml.em('Hey ' + yield + '!')" } 3.times { assert_equal "Hey Joe!\n", template.render { 'Joe' }} end test "block style templates" do template = Tilt::BuilderTemplate.new do |t| lambda { |xml| xml.em('Hey Joe!') } end assert_equal "Hey Joe!\n", template.render end test "allows nesting raw XML" do subtemplate = Tilt::BuilderTemplate.new { "xml.em 'Hello World!'" } template = Tilt::BuilderTemplate.new { "xml.strong { xml << yield }" } 3.times do options = { :xml => Builder::XmlMarkup.new } assert_equal "\nHello World!\n\n", template.render(options) { subtemplate.render(options) } end end end rescue LoadError warn "Tilt::BuilderTemplate (disabled)" end tilt-1.4.1/HACKING0000644000004100000410000000045612162124415013513 0ustar www-datawww-dataClone: git clone git://github.com/rtomayko/tilt.git cd tilt Install needed packages under ./vendor and run tests (requires bundler): rake Run tests under your current gem environment. Do not install anything: rake test Only install needed packages under ./vendor: rake setup tilt-1.4.1/README.md0000644000004100000410000002311512162124415014000 0ustar www-datawww-dataTilt [![Build Status](https://secure.travis-ci.org/rtomayko/tilt.png)](http://travis-ci.org/rtomayko/tilt) [![Dependency Status](https://gemnasium.com/rtomayko/tilt.png)](https://gemnasium.com/rtomayko/tilt) ==== Tilt is a thin interface over a bunch of different Ruby template engines in an attempt to make their usage as generic possible. This is useful for web frameworks, static site generators, and other systems that support multiple template engines but don't want to code for each of them individually. The following features are supported for all template engines (assuming the feature is relevant to the engine): * Custom template evaluation scopes / bindings * Ability to pass locals to template evaluation * Support for passing a block to template evaluation for "yield" * Backtraces with correct filenames and line numbers * Template file caching and reloading * Fast, method-based template source compilation The primary goal is to get all of the things listed above right for all template engines included in the distribution. Support for these template engines is included with the package: ENGINE FILE EXTENSIONS REQUIRED LIBRARIES -------------------------- ----------------------- ---------------------------- Asciidoctor .ad, .adoc, .asciidoc asciidoctor (>= 0.1.0) ERB .erb, .rhtml none (included ruby stdlib) Interpolated String .str none (included ruby core) Erubis .erb, .rhtml, .erubis erubis Haml .haml haml Sass .sass haml (< 3.1) or sass (>= 3.1) Scss .scss haml (< 3.1) or sass (>= 3.1) Less CSS .less less Builder .builder builder Liquid .liquid liquid RDiscount .markdown, .mkd, .md rdiscount Redcarpet .markdown, .mkd, .md redcarpet BlueCloth .markdown, .mkd, .md bluecloth Kramdown .markdown, .mkd, .md kramdown Maruku .markdown, .mkd, .md maruku RedCloth .textile redcloth RDoc .rdoc rdoc Radius .radius radius Markaby .mab markaby Nokogiri .nokogiri nokogiri CoffeeScript .coffee coffee-script (+ javascript) Creole (Wiki markup) .wiki, .creole creole WikiCloth (Wiki markup) .wiki, .mediawiki, .mw wikicloth Yajl .yajl yajl-ruby CSV .rcsv none (Ruby >= 1.9), fastercsv (Ruby < 1.9) These template engines ship with their own Tilt integration: ENGINE FILE EXTENSIONS REQUIRED LIBRARIES -------------------------- ----------------- ---------------------------- Slim .slim slim (>= 0.7) Embedded JavaScript sprockets Embedded CoffeeScript sprockets JST sprockets Org-mode .org org-ruby (>= 0.6.2) See [TEMPLATES.md][t] for detailed information on template engine options and supported features. [t]: http://github.com/rtomayko/tilt/blob/master/TEMPLATES.md "Tilt Template Engine Documentation" Basic Usage ----------- Instant gratification: require 'erb' require 'tilt' template = Tilt.new('templates/foo.erb') => # output = template.render => "Hello world!" It's recommended that calling programs explicitly require template engine libraries (like 'erb' above) at load time. Tilt attempts to lazy require the template engine library the first time a template is created but this is prone to error in threaded environments. The `Tilt` module contains generic implementation classes for all supported template engines. Each template class adheres to the same interface for creation and rendering. In the instant gratification example, we let Tilt determine the template implementation class based on the filename, but `Tilt::Template` implementations can also be used directly: template = Tilt::HamlTemplate.new('templates/foo.haml') output = template.render The `render` method takes an optional evaluation scope and locals hash arguments. Here, the template is evaluated within the context of the `Person` object with locals `x` and `y`: template = Tilt::ERBTemplate.new('templates/foo.erb') joe = Person.find('joe') output = template.render(joe, :x => 35, :y => 42) If no scope is provided, the template is evaluated within the context of an object created with `Object.new`. A single `Template` instance's `render` method may be called multiple times with different scope and locals arguments. Continuing the previous example, we render the same compiled template but this time in jane's scope: jane = Person.find('jane') output = template.render(jane, :x => 22, :y => nil) Blocks can be passed to `render` for templates that support running arbitrary ruby code (usually with some form of `yield`). For instance, assuming the following in `foo.erb`: Hey <%= yield %>! The block passed to `render` is called on `yield`: template = Tilt::ERBTemplate.new('foo.erb') template.render { 'Joe' } # => "Hey Joe!" Template Mappings ----------------- The `Tilt` module includes methods for associating template implementation classes with filename patterns and for locating/instantiating template classes based on those associations. The `Tilt::register` method associates a filename pattern with a specific template implementation. To use ERB for files ending in a `.bar` extension: >> Tilt.register Tilt::ERBTemplate, 'bar' >> Tilt.new('views/foo.bar') => # Retrieving the template class for a file or file extension: >> Tilt['foo.bar'] => Tilt::ERBTemplate >> Tilt['haml'] => Tilt::HamlTemplate It's also possible to register template file mappings that are more specific than a file extension. To use Erubis for `bar.erb` but ERB for all other `.erb` files: >> Tilt.register Tilt::ErubisTemplate, 'bar.erb' >> Tilt.new('views/foo.erb') => Tilt::ERBTemplate >> Tilt.new('views/bar.erb') => Tilt::ErubisTemplate The template class is determined by searching for a series of decreasingly specific name patterns. When creating a new template with `Tilt.new('views/foo.html.erb')`, we check for the following template mappings: 1. `views/foo.html.erb` 2. `foo.html.erb` 3. `html.erb` 4. `erb` ### Fallback mode If there are more than one template class registered for a file extension, Tilt will automatically try to load the version that works on your machine: 1. If any of the template engines has been loaded already: Use that one. 2. If not, it will try to initialize each of the classes with an empty template. 3. Tilt will use the first that doesn't raise an exception. 4. If however *all* of them failed, Tilt will raise the exception of the first template engine, since that was the most preferred one. Template classes that were registered *last* would be tried first. Because the Markdown extensions are registered like this: Tilt.register Tilt::BlueClothTemplate, 'md' Tilt.register Tilt::RDiscountTemplate, 'md' Tilt will first try RDiscount and then BlueCloth. You could say that RDiscount has a *higher priority* than BlueCloth. The fallback mode works nicely when you just need to render an ERB or Markdown template, but if you depend on a specific implementation, you should use #prefer: # Prefer BlueCloth for all its registered extensions (markdown, mkd, md) Tilt.prefer Tilt::BlueClothTemplate # Prefer Erubis for .erb only: Tilt.prefer Tilt::ErubisTemplate, 'erb' When a file extension has a preferred template class, Tilt will *always* use that class, even if it raises an exception. Encodings --------- Tilt needs to know the encoding of the template in order to work properly: Tilt will use `Encoding.default_external` as the encoding when reading external files. If you're mostly working with one encoding (e.g. UTF-8) we *highly* recommend setting this option. When providing a custom reader block (`Tilt.new { custom_string }`) you'll have ensure the string is properly encoded yourself. Most of the template engines in Tilt also allows you to override the encoding using the `:default_encoding`-option: ```ruby tmpl = Tilt.new('hello.erb', :default_encoding => 'Big5') ``` Ultimately it's up to the template engine how to handle the encoding: It might respect `:default_encoding`, it might always assume it's UTF-8 (like CoffeScript), or it can do its own encoding detection. Template Compilation -------------------- Tilt compiles generated Ruby source code produced by template engines and reuses it on subsequent template invocations. Benchmarks show this yields a 5x-10x performance increase over evaluating the Ruby source on each invocation. Template compilation is currently supported for these template engines: StringTemplate, ERB, Erubis, Haml, Nokogiri, Builder and Yajl. LICENSE ------- Tilt is Copyright (c) 2010 [Ryan Tomayko](http://tomayko.com/about) and distributed under the MIT license. See the `COPYING` file for more info. tilt-1.4.1/Rakefile0000644000004100000410000000565012162124415014172 0ustar www-datawww-datarequire 'rbconfig' require 'rake/testtask' task :default => [:setup, :test] # set GEM_HOME to use local ./vendor dir for tests vendor_dir = './vendor' ruby_version = RbConfig::CONFIG['ruby_version'] ruby_engine = (defined?(RUBY_ENGINE) && RUBY_ENGINE) || 'ruby' gem_home = ENV['GEM_HOME'] = "#{vendor_dir}/#{ruby_engine}/#{ruby_version}" # Write the current version. task :version do puts "#{ruby_engine} #{RUBY_VERSION} (#{gem_home})" end desc "Install gems to #{ENV['GEM_HOME']}" task :setup do verbose false do sh " bundle check >/dev/null || { echo 'Updating #{gem_home}' && bundle install --path='#{vendor_dir}'; } " end end # SPECS ===================================================================== desc 'Generate test coverage report' task :rcov do sh "rcov -Ilib:test test/*_test.rb" end desc 'Run tests (default)' Rake::TestTask.new(:test) do |t| t.test_files = FileList['test/*_test.rb'] t.ruby_opts = ['-Itest'] t.ruby_opts << '-rubygems' if defined? Gem end task :test => :version # PACKAGING ================================================================= begin require 'rubygems' rescue LoadError end if defined?(Gem) SPEC = eval(File.read('tilt.gemspec')) def package(ext='') "pkg/tilt-#{SPEC.version}" + ext end desc 'Build packages' task :package => %w[.gem .tar.gz].map {|e| package(e)} desc 'Build and install as local gem' task :install => package('.gem') do sh "gem install #{package('.gem')}" end directory 'pkg/' file package('.gem') => %w[pkg/ tilt.gemspec] + SPEC.files do |f| sh "gem build tilt.gemspec" mv File.basename(f.name), f.name end file package('.tar.gz') => %w[pkg/] + SPEC.files do |f| sh "git archive --format=tar HEAD | gzip > #{f.name}" end desc 'Upload gem and tar.gz distributables to rubyforge' task :release => [package('.gem'), package('.tar.gz')] do |t| sh <<-SH rubyforge add_release sinatra tilt #{SPEC.version} #{package('.gem')} && rubyforge add_file sinatra tilt #{SPEC.version} #{package('.tar.gz')} SH end end # GEMSPEC =================================================================== file 'tilt.gemspec' => FileList['{lib,test}/**','Rakefile'] do |f| # read version from tilt.rb version = File.read('lib/tilt.rb')[/VERSION = '(.*)'/] && $1 # read spec file and split out manifest section spec = File. read(f.name). sub(/s\.version\s*=\s*'.*'/, "s.version = '#{version}'") parts = spec.split(" # = MANIFEST =\n") # determine file list from git ls-files files = `git ls-files`. split("\n").sort.reject{ |file| file =~ /^\./ }. map{ |file| " #{file}" }.join("\n") # piece file back together and write... parts[1] = " s.files = %w[\n#{files}\n ]\n" spec = parts.join(" # = MANIFEST =\n") spec.sub!(/s.date = '.*'/, "s.date = '#{Time.now.strftime("%Y-%m-%d")}'") File.open(f.name, 'w') { |io| io.write(spec) } puts "updated #{f.name}" end tilt-1.4.1/bin/0000755000004100000410000000000012162124415013267 5ustar www-datawww-datatilt-1.4.1/bin/tilt0000755000004100000410000000563412162124415014201 0ustar www-datawww-data#!/usr/bin/env ruby require 'ostruct' require 'optparse' require 'tilt' usage = < Process template and write output to stdout. With no or when is '-', read template from stdin and use the --type option to determine the template's type. Options -l, --list List template engines + file patterns and exit -t, --type= Use this template engine; required if no -y, --layout= Use as a layout template -D= Define variable as --vars= Evaluate to Hash and use for variables -h, --help Show this help message Convert markdown to HTML: $ tilt foo.markdown > foo.html Process ERB template: $ echo "Answer: <%= 2 + 2 %>" | tilt -t erb Answer: 4 Define variables: $ echo "Answer: <%= 2 + n %>" | tilt -t erb --vars="{:n=>40}" Answer: 42 $ echo "Answer: <%= 2 + n.to_i %>" | tilt -t erb -Dn=40 Answer: 42 USAGE script_name = File.basename($0) pattern = nil layout = nil locals = {} ARGV.options do |o| o.program_name = script_name # list all available template engines o.on("-l", "--list") do groups = {} Tilt.mappings.each do |pattern,engines| engines.each do |engine| key = engine.name.split('::').last.sub(/Template$/, '') (groups[key] ||= []) << pattern end end groups.sort { |(k1,v1),(k2,v2)| k1 <=> k2 }.each do |engine,files| printf "%-15s %s\n", engine, files.sort.join(', ') end exit end # the template type / pattern o.on("-t", "--type=PATTERN", String) do |val| abort "unknown template type: #{val}" if Tilt[val].nil? pattern = val end # pass template output into the specified layout template o.on("-y", "--layout=FILE", String) do |file| paths = [file, "~/.tilt/#{file}", "/etc/tilt/#{file}"] layout = paths. map { |p| File.expand_path(p) }. find { |p| File.exist?(p) } abort "no such layout: #{file}" if layout.nil? end # define a local variable o.on("-D", "--define=PAIR", String) do |pair| key, value = pair.split(/[=:]/, 2) locals[key.to_sym] = value end # define local variables using a Ruby hash o.on("--vars=RUBY") do |ruby| hash = eval(ruby) abort "vars must be a Hash, not #{hash.inspect}" if !hash.is_a?(Hash) hash.each { |key, value| locals[key.to_sym] = value } end o.on_tail("-h", "--help") { puts usage; exit } o.parse! end file = ARGV.first || '-' pattern = file if pattern.nil? abort "template type not given. see: #{$0} --help" if ['-', ''].include?(pattern) engine = Tilt[pattern] abort "template engine not found for: #{pattern}" if engine.nil? template = engine.new(file) { if file == '-' $stdin.read else File.read(file) end } output = template.render(self, locals) # process layout output = Tilt.new(layout).render(self, locals) { output } if layout $stdout.write(output) tilt-1.4.1/metadata.yml0000644000004100000410000003125612162124415015031 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: tilt version: !ruby/object:Gem::Version version: 1.4.1 prerelease: platform: ruby authors: - Ryan Tomayko autorequire: bindir: bin cert_chain: [] date: 2013-05-08 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: asciidoctor requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 0.1.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 0.1.0 - !ruby/object:Gem::Dependency name: RedCloth requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: bluecloth requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: builder requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: coffee-script requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: contest requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: creole requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: erubis requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: haml requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 2.2.11 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 2.2.11 - !ruby/object:Gem::Dependency name: kramdown requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: less requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: liquid requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: markaby requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: maruku requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: nokogiri requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: radius requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rdiscount requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rdoc requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: redcarpet requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: sass requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: wikicloth requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: yajl-ruby requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rdoc requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' description: Generic interface to multiple Ruby template engines email: r@tomayko.com executables: - tilt extensions: [] extra_rdoc_files: [] files: - CHANGELOG.md - COPYING - Gemfile - HACKING - README.md - Rakefile - TEMPLATES.md - bin/tilt - lib/tilt.rb - lib/tilt/asciidoc.rb - lib/tilt/builder.rb - lib/tilt/coffee.rb - lib/tilt/css.rb - lib/tilt/csv.rb - lib/tilt/erb.rb - lib/tilt/etanni.rb - lib/tilt/haml.rb - lib/tilt/liquid.rb - lib/tilt/markaby.rb - lib/tilt/markdown.rb - lib/tilt/nokogiri.rb - lib/tilt/plain.rb - lib/tilt/radius.rb - lib/tilt/rdoc.rb - lib/tilt/string.rb - lib/tilt/template.rb - lib/tilt/textile.rb - lib/tilt/wiki.rb - lib/tilt/yajl.rb - test/contest.rb - test/markaby/locals.mab - test/markaby/markaby.mab - test/markaby/markaby_other_static.mab - test/markaby/render_twice.mab - test/markaby/scope.mab - test/markaby/yielding.mab - test/tilt_asciidoctor_test.rb - test/tilt_blueclothtemplate_test.rb - test/tilt_buildertemplate_test.rb - test/tilt_cache_test.rb - test/tilt_coffeescripttemplate_test.rb - test/tilt_compilesite_test.rb - test/tilt_creoletemplate_test.rb - test/tilt_csv_test.rb - test/tilt_erbtemplate_test.rb - test/tilt_erubistemplate_test.rb - test/tilt_etannitemplate_test.rb - test/tilt_fallback_test.rb - test/tilt_hamltemplate_test.rb - test/tilt_kramdown_test.rb - test/tilt_lesstemplate_test.less - test/tilt_lesstemplate_test.rb - test/tilt_liquidtemplate_test.rb - test/tilt_markaby_test.rb - test/tilt_markdown_test.rb - test/tilt_marukutemplate_test.rb - test/tilt_nokogiritemplate_test.rb - test/tilt_radiustemplate_test.rb - test/tilt_rdiscounttemplate_test.rb - test/tilt_rdoctemplate_test.rb - test/tilt_redcarpettemplate_test.rb - test/tilt_redclothtemplate_test.rb - test/tilt_sasstemplate_test.rb - test/tilt_stringtemplate_test.rb - test/tilt_template_test.rb - test/tilt_test.rb - test/tilt_wikiclothtemplate_test.rb - test/tilt_yajltemplate_test.rb - tilt.gemspec homepage: http://github.com/rtomayko/tilt/ licenses: - MIT post_install_message: rdoc_options: - --line-numbers - --inline-source - --title - Tilt - --main - Tilt require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 1.8.25 signing_key: specification_version: 2 summary: Generic interface to multiple Ruby template engines test_files: - test/tilt_asciidoctor_test.rb - test/tilt_blueclothtemplate_test.rb - test/tilt_buildertemplate_test.rb - test/tilt_cache_test.rb - test/tilt_coffeescripttemplate_test.rb - test/tilt_compilesite_test.rb - test/tilt_creoletemplate_test.rb - test/tilt_csv_test.rb - test/tilt_erbtemplate_test.rb - test/tilt_erubistemplate_test.rb - test/tilt_etannitemplate_test.rb - test/tilt_fallback_test.rb - test/tilt_hamltemplate_test.rb - test/tilt_kramdown_test.rb - test/tilt_lesstemplate_test.rb - test/tilt_liquidtemplate_test.rb - test/tilt_markaby_test.rb - test/tilt_markdown_test.rb - test/tilt_marukutemplate_test.rb - test/tilt_nokogiritemplate_test.rb - test/tilt_radiustemplate_test.rb - test/tilt_rdiscounttemplate_test.rb - test/tilt_rdoctemplate_test.rb - test/tilt_redcarpettemplate_test.rb - test/tilt_redclothtemplate_test.rb - test/tilt_sasstemplate_test.rb - test/tilt_stringtemplate_test.rb - test/tilt_template_test.rb - test/tilt_test.rb - test/tilt_wikiclothtemplate_test.rb - test/tilt_yajltemplate_test.rb has_rdoc: tilt-1.4.1/CHANGELOG.md0000644000004100000410000000252712162124415014336 0ustar www-datawww-data## master ## 1.4.1 (2013-05-08) * Support Arrays in pre/postambles (#193, jbwiv) ## 1.4.0 (2013-05-01) * Better encoding support ## 1.3.7 (2013-04-09) * Erubis: Check for the correct constant (#183, mattwildig) * Don't fail when BasicObject is defined in 1.8 (#182, technobrat, judofyr) ## 1.3.6 (2013-03-17) * Accept Hash that implements #path as options (#180, lawso017) * Changed extension for CsvTemplate from '.csv' to '.rcsv' (#177, alexgb) ## 1.3.5 (2013-03-06) * Fixed extension for PlainTemplate (judofyr) * Improved local variables regexp (#174, razorinc) * Added CHANGELOG.md ## 1.3.4 (2013-02-28) * Support RDoc 4.0 (#168, judofyr) * Add mention of Org-Mode support (#165, aslakknutsen) * Add AsciiDoctorTemplate (#163, #164, aslakknutsen) * Add PlainTextTemplate (nathanaeljones) * Restrict locals to valid variable names (#158, thinkerbot) * ERB: Improve trim mode support (#156, ssimeonov) * Add CSVTemplate (#153, alexgb) * Remove special case for 1.9.1 (#147, guilleiguaran) * Add allows\_script? method to Template (#143, bhollis) * Default to using Redcarpet2 (#139, DAddYE) * Allow File/Tempfile as filenames (#134, jamesotron) * Add EtanniTemplate (#131, manveru) * Support RDoc 3.10 (#112, timfel) * Always compile templates; remove old source evaluator (rtomayko) * Less: Options are now being passed to the parser (#106, cowboyd) tilt-1.4.1/COPYING0000644000004100000410000000204612162124415013554 0ustar www-datawww-dataCopyright (c) 2010 Ryan Tomayko 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 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. tilt-1.4.1/Gemfile0000644000004100000410000000101212162124415014004 0ustar www-datawww-datasource "http://rubygems.org" gem 'rake' gem 'asciidoctor', '>= 0.1.0' gem 'builder' gem 'coffee-script' gem 'contest' gem 'creole' gem 'erubis' gem 'haml', '>= 2.2.11', '< 4' gem 'kramdown' gem 'less' gem 'liquid' gem 'markaby' gem 'maruku' gem 'nokogiri' gem 'radius' gem 'sass' gem 'wikicloth' gem 'rdoc', (ENV['RDOC_VERSION'] || '> 0') platform :ruby do gem 'yajl-ruby' gem 'redcarpet' gem 'rdiscount' if RUBY_VERSION != '1.9.2' gem 'RedCloth' end platform :mri do gem 'therubyracer' gem 'bluecloth' end tilt-1.4.1/TEMPLATES.md0000644000004100000410000003533112162124415014404 0ustar www-datawww-dataTilt Templates ============== (See for a rendered, HTML-version of this file). While all Tilt templates use the same basic interface for template loading and evaluation, each varies in its capabilities and available options. Detailed documentation on each supported template engine is provided below. There are also some file extensions that have several implementations (currently ERB and Markdown). These template classes have certain features which are guaranteed to work across all the implementations. If you wish to be compatible with all of these template classes, you should only depend on the cross-implementation features. * [ERB](#erb) - Generic ERB implementation (backed by erb.rb or Erubis) * [erb.rb](#erbrb) - `Tilt::ERBTemplate` * [Erubis](#erubis) - `Tilt::ErubisTemplate` * [Haml](#haml) - `Tilt::HamlTemplate` * [Liquid](#liquid) - `Tilt::LiquidTemplate` * Nokogiri - `Tilt::NokogiriTemplate` * Builder - `Tilt::BuilderTemplate` * Markaby - `Tilt::MarkabyTemplate` * [Radius](#radius) - `Tilt::RadiusTemplate` Tilt also includes support for CSS processors like [LessCSS][lesscss] and [Sass][sass], [CoffeeScript][coffee-script] and some simple text formats. * Less - `Tilt::LessTemplate` * Sass - `Tilt::SassTemplate` * Scss - `Tilt::ScssTemplate` * CoffeeScript - `Tilt::CoffeeScriptTemplate` * [Textile](#redcloth) - `Tilt::RedClothTemplate` * Creole - `Tilt::CreoleTemplate` * [RDoc](#rdoc) - `Tilt::RDocTemplate` Tilt has extensive support for Markdown, backed by one of four different implementations (depending on which are available on your system): * [Markdown](#markdown) - Generic Markdown implementation * [RDiscount](#rdiscount) - `Tilt::RDiscountTemplate` * Redcarpet - `Tilt::RedcarpetTemplate` * BlueCloth - `Tilt::BlueClothTemplate` * Kramdown - `Tilt::KramdownTemplate` * Maruku - `Tilt::MarukuTemplate` ERB (`erb`, `rhtml`) -------------------- ERB is a simple but powerful template languge for Ruby. In Tilt it's backed by [Erubis](#erubis) (if installed on your system) or by [erb.rb](#erbrb) (which is included in Ruby's standard library). This documentation applies to both implementations. ### Example Hello <%= world %>! ### Usage ERB templates support custom evaluation scopes and locals: >> require 'erb' >> template = Tilt.new('hello.html.erb') >> template.render(self, :world => 'World!') => "Hello World!" Or, use `Tilt['erb']` directly to process strings: template = Tilt['erb'].new { "Hello <%= world %>!" } template.render(self, :world => 'World!') ### Options #### `:trim => trim` Omits newlines and spaces around certain lines (usually those that starts with `<%` and ends with `%>`). There isn't a specification for how trimming in ERB should work, so if you need more control over the whitespace, you should use [erb.rb](#erbrb) or [Erubis](#erubis) directly. #### `:outvar => '_erbout'` The name of the variable used to accumulate template output. This can be any valid Ruby expression but must be assignable. By default a local variable named `_erbout` is used. erb.rb (`erb`, `rhtml`) ----------------------- [ERB](#erb) implementation available in Ruby's standard library. All the documentation of [ERB](#erb) applies in addition to the following: ### Usage The `Tilt::ERBTemplate` class is registered for all files ending in `.erb` or `.rhtml` by default, but with a *lower* priority than ErubisTemplate. If you specifically want to use ERB, it's recommended to use `#prefer`: Tilt.prefer Tilt::ERBTemplate __NOTE:__ It's suggested that your program `require 'erb'` at load time when using this template engine within a threaded environment. ### Options #### `:trim => true` The ERB trim mode flags. This is a string consisting of any combination of the following characters: * `'>'` omits newlines for lines ending in `>` * `'<>'` omits newlines for lines starting with `<%` and ending in `%>` * `'%'` enables processing of lines beginning with `%` * `true` is an alias of `<>` #### `:safe => nil` The `$SAFE` level; when set, ERB code will be run in a separate thread with `$SAFE` set to the provided level. #### `:outvar => '_erbout'` The name of the variable used to accumulate template output. This can be any valid Ruby expression but must be assignable. By default a local variable named `_erbout` is used. ### See also * [ERB documentation](http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html) Erubis (`erb`, `rhtml`, `erubis`) --------------------------------- [Erubis][erubis] is a fast, secure, and very extensible implementation of [ERB](#erb). All the documentation of [ERB](#erb) applies in addition to the following: ### Usage The `Tilt::ErubisTemplate` class is registered for all files ending in `.erb` or `.rhtml` by default, but with a *higher* priority than `ERBTemplate`. If you specifically want to use Erubis, it's recommended to use `#prefer`: Tilt.prefer Tilt::ErubisTemplate __NOTE:__ It's suggested that your program `require 'erubis'` at load time when using this template engine within a threaded environment. ### Options #### `:engine_class => Erubis::Eruby` Allows you to specify a custom engine class to use instead of the default which is `Erubis::Eruby`. #### `:escape_html => false` When `true`, `Erubis::EscapedEruby` will be used as the engine class instead of the default. All content within `<%= %>` blocks will be automatically html escaped. #### `:outvar => '_erbout'` The name of the variable used to accumulate template output. This can be any valid Ruby expression but must be assignable. By default a local variable named `_erbout` is used. #### `:pattern => '<% %>'` Set pattern for embedded Ruby code. #### `:trim => true` Delete spaces around `<% %>`. (But, spaces around `<%= %>` are preserved.) ### See also * [Erubis Home][erubis] * [Erubis User's Guide](http://www.kuwata-lab.com/erubis/users-guide.html) Haml (`haml`) ------------- [Haml][haml] is a markup language that’s used to cleanly and simply describe the HTML of any web document without the use of inline code. Haml functions as a replacement for inline page templating systems such as PHP, ASP, and ERB, the templating language used in most Ruby on Rails applications. However, Haml avoids the need for explicitly coding HTML into the template, because it itself is a description of the HTML, with some code to generate dynamic content. ([more](http://haml.info/about.html)) ### Example %html %head %title= @title %body %h1 Hello = world + '!' ### Usage The `Tilt::HamlTemplate` class is registered for all files ending in `.haml` by default. Haml templates support custom evaluation scopes and locals: >> require 'haml' >> template = Tilt.new('hello.haml') => # >> @title = "Hello Haml!" >> template.render(self, :world => 'Haml!') => " Hello Haml!

    Hello Haml!

    " Or, use the `Tilt::HamlTemplate` class directly to process strings: >> require 'haml' >> template = Tilt::HamlTemplate.new { "%h1= 'Hello Haml!'" } => # >> template.render => "

    Hello Haml!

    " __NOTE:__ It's suggested that your program `require 'haml'` at load time when using this template engine within a threaded environment. ### Options Please see the [Haml Reference](http://haml.info/docs/yardoc/file.HAML_REFERENCE.html#options) for all available options. ### See also * [#haml.docs](http://haml.info/docs.html) * [Haml Tutorial](http://haml.info/tutorial.html) * [Haml Reference](http://haml.info/docs/yardoc/file.HAML_REFERENCE.html) Liquid (`liquid`) ----------------- [Liquid][liquid] is for rendering safe templates which cannot affect the security of the server they are rendered on. ### Example {{ title }}

    Hello {{ world }}!

    ### Usage `Tilt::LiquidTemplate` is registered for all files ending in `.liquid` by default. Liquid templates support locals and objects that respond to `#to_h` as scopes: >> require 'liquid' >> require 'tilt' >> template = Tilt.new('hello.liquid') => # >> scope = { :title => "Hello Liquid Templates" } >> template.render(nil, :world => "Liquid") => " Hello Liquid Templates

    Hello Liquid!

    " Or, use `Tilt::LiquidTemplate` directly to process strings: >> require 'liquid' >> template = Tilt::LiquidTemplate.new { "

    Hello Liquid!

    " } => # >> template.render => "

    Hello Liquid!

    " __NOTE:__ It's suggested that your program `require 'liquid'` at load time when using this template engine within a threaded environment. ### See also * [Liquid for Programmers](https://wiki.github.com/Shopify/liquid/liquid-for-programmers) * [Liquid Docs](http://liquid.rubyforge.org/) * GitHub: [Shopify/liquid](https://github.com/Shopify/liquid/) Radius (`radius`) ----------------- [Radius][radius] is the template language used by [Radiant CMS][radiant]. It is a tag language designed to be valid XML/HTML. ### Example

    • !
    ### Usage To render a template such as the one above. scope = OpenStruct.new scope.title = "Radius Example" scope.hello = "Hello, World!" require 'radius' template = Tilt::RadiusTemplate.new('example.radius', :tag_prefix=>'r') template.render(scope, :type=>'hlist'){ "Jackpot!" } The result will be:

    Radius Example

    • Hello, World!
    • Hello, World!
    • Hello, World!
    Jackpot! ### See also * [Radius][radius] * [Radiant CMS][radiant] Textile (`textile`) ------------------- Textile is a lightweight markup language originally developed by Dean Allen and billed as a "humane Web text generator". Textile converts its marked-up text input to valid, well-formed XHTML and also inserts character entity references for apostrophes, opening and closing single and double quotation marks, ellipses and em dashes. Textile formatted texts are converted to HTML with the [RedCloth][redcloth] engine, which is a Ruby extension written in C. ### Example h1. Hello Textile Templates Hello World. This is a paragraph. ### Usage __NOTE:__ It's suggested that your program `require 'redcloth'` at load time when using this template engine in a threaded environment. ### See Also * [RedCloth][redcloth] RDoc (`rdoc`) ------------- [RDoc][rdoc] is the simple text markup system that comes with Ruby's standard library. ### Example = Hello RDoc Templates Hello World. This is a paragraph. ### Usage __NOTE:__ It's suggested that your program `require 'rdoc'`, `require 'rdoc/markup'`, and `require 'rdoc/markup/to_html'` at load time when using this template engine in a threaded environment. ### See also * [RDoc][rdoc] Markdown (`markdown`, `md`, `mkd`) ---------------------------------- [Markdown][markdown] is a lightweight markup language, created by John Gruber and Aaron Swartz. For any markup that is not covered by Markdown’s syntax, HTML is used. Marking up plain text with Markdown markup is easy and Markdown formatted texts are readable. Markdown formatted texts are converted to HTML with one of these libraries: * [RDiscount](#rdiscount) - `Tilt::RDiscountTemplate` * Redcarpet - `Tilt::RedcarpetTemplate` * BlueCloth - `Tilt::BlueClothTemplate` * Kramdown - `Tilt::KramdownTemplate` * Maruku - `Tilt::MarukuTemplate` Tilt will use fallback mode (as documented in the README) for determining which library to use. RDiscount has highest priority - Maruku has lowest. ### Example Hello Markdown Templates ======================== Hello World. This is a paragraph. ### Usage To wrap a Markdown formatted document with a layout: layout = Tilt['erb'].new do "<%= yield %>" end data = Tilt['md'].new { "# hello tilt" } layout.render { data.render } # => "

    hello tilt

    \n" ### Options Every implementation of Markdown *should* support these options, but there are some known problems with the Kramdown and Maruku engines. #### `:smartypants => true|false` Set `true` to enable [Smarty Pants][smartypants] style punctuation replacement. #### `:escape_html => true|false` Set `true` disallow raw HTML in Markdown contents. HTML is converted to literal text by escaping `<` characters. ### See also * [Markdown Syntax Documentation](http://daringfireball.net/projects/markdown/syntax/) RDiscount (`markdown`, `md`, `mkd`) ----------------------------------- [Discount][discount] is an implementation of the Markdown markup language in C. [RDiscount][rdiscount] is a Ruby wrapper around Discount. All the documentation of [Markdown](#markdown) applies in addition to the following: ### Usage The `Tilt::RDiscountTemplate` class is registered for all files ending in `.markdown`, `.md` or `.mkd` by default with the highest priority. If you specifically want to use RDiscount, it's recommended to use `#prefer`: Tilt.prefer Tilt::RDiscountTemplate __NOTE:__ It's suggested that your program `require 'erubis'` at load time when using this template engine within a threaded environment. ### See also * [Discount][discount] * [RDiscount][rdiscount] * GitHub: [rtomayko/rdiscount][rdiscount] [lesscss]: http://lesscss.org/ "Less CSS" [sass]: http://sass-lang.com/ "Sass" [coffee-script]: http://jashkenas.github.com/coffee-script/ "Coffee Script" [erubis]: http://www.kuwata-lab.com/erubis/ "Erubis" [haml]: http://haml.info/ "Haml" [liquid]: http://www.liquidmarkup.org/ "Liquid" [radius]: http://radius.rubyforge.org/ "Radius" [radiant]: http://radiantcms.org/ "Radiant CMS" [redcloth]: http://redcloth.org/ "RedCloth" [rdoc]: http://rdoc.rubyforge.org/ "RDoc" [discount]: http://www.pell.portland.or.us/~orc/Code/discount/ "Discount" [rdiscount]: http://github.com/rtomayko/rdiscount/ "RDiscount" [smartypants]: http://daringfireball.net/projects/smartypants/ "Smarty Pants" tilt-1.4.1/lib/0000755000004100000410000000000012162124415013265 5ustar www-datawww-datatilt-1.4.1/lib/tilt.rb0000644000004100000410000001267212162124415014576 0ustar www-datawww-datamodule Tilt VERSION = '1.4.1' @preferred_mappings = Hash.new @template_mappings = Hash.new { |h, k| h[k] = [] } # Hash of template path pattern => template implementation class mappings. def self.mappings @template_mappings end def self.normalize(ext) ext.to_s.downcase.sub(/^\./, '') end # Register a template implementation by file extension. def self.register(template_class, *extensions) if template_class.respond_to?(:to_str) # Support register(ext, template_class) too extensions, template_class = [template_class], extensions[0] end extensions.each do |ext| ext = normalize(ext) mappings[ext].unshift(template_class).uniq! end end # Makes a template class preferred for the given file extensions. If you # don't provide any extensions, it will be preferred for all its already # registered extensions: # # # Prefer RDiscount for its registered file extensions: # Tilt.prefer(Tilt::RDiscountTemplate) # # # Prefer RDiscount only for the .md extensions: # Tilt.prefer(Tilt::RDiscountTemplate, '.md') def self.prefer(template_class, *extensions) if extensions.empty? mappings.each do |ext, klasses| @preferred_mappings[ext] = template_class if klasses.include? template_class end else extensions.each do |ext| ext = normalize(ext) register(template_class, ext) @preferred_mappings[ext] = template_class end end end # Returns true when a template exists on an exact match of the provided file extension def self.registered?(ext) mappings.key?(ext.downcase) && !mappings[ext.downcase].empty? end # Create a new template for the given file using the file's extension # to determine the the template mapping. def self.new(file, line=nil, options={}, &block) if template_class = self[file] template_class.new(file, line, options, &block) else fail "No template engine registered for #{File.basename(file)}" end end # Lookup a template class for the given filename or file # extension. Return nil when no implementation is found. def self.[](file) pattern = file.to_s.downcase until pattern.empty? || registered?(pattern) pattern = File.basename(pattern) pattern.sub!(/^[^.]*\.?/, '') end # Try to find a preferred engine. preferred_klass = @preferred_mappings[pattern] return preferred_klass if preferred_klass # Fall back to the general list of mappings. klasses = @template_mappings[pattern] # Try to find an engine which is already loaded. template = klasses.detect do |klass| if klass.respond_to?(:engine_initialized?) klass.engine_initialized? end end return template if template # Try each of the classes until one succeeds. If all of them fails, # we'll raise the error of the first class. first_failure = nil klasses.each do |klass| begin klass.new { '' } rescue Exception => ex first_failure ||= ex next else return klass end end raise first_failure if first_failure end # Deprecated module. module CompileSite end # Extremely simple template cache implementation. Calling applications # create a Tilt::Cache instance and use #fetch with any set of hashable # arguments (such as those to Tilt.new): # cache = Tilt::Cache.new # cache.fetch(path, line, options) { Tilt.new(path, line, options) } # # Subsequent invocations return the already loaded template object. class Cache def initialize @cache = {} end def fetch(*key) @cache[key] ||= yield end def clear @cache = {} end end # Template Implementations ================================================ require 'tilt/string' register StringTemplate, 'str' require 'tilt/erb' register ERBTemplate, 'erb', 'rhtml' register ErubisTemplate, 'erb', 'rhtml', 'erubis' require 'tilt/etanni' register EtanniTemplate, 'etn', 'etanni' require 'tilt/haml' register HamlTemplate, 'haml' require 'tilt/css' register SassTemplate, 'sass' register ScssTemplate, 'scss' register LessTemplate, 'less' require 'tilt/csv' register CSVTemplate, 'rcsv' require 'tilt/coffee' register CoffeeScriptTemplate, 'coffee' require 'tilt/nokogiri' register NokogiriTemplate, 'nokogiri' require 'tilt/builder' register BuilderTemplate, 'builder' require 'tilt/markaby' register MarkabyTemplate, 'mab' require 'tilt/liquid' register LiquidTemplate, 'liquid' require 'tilt/radius' register RadiusTemplate, 'radius' require 'tilt/markdown' register MarukuTemplate, 'markdown', 'mkd', 'md' register KramdownTemplate, 'markdown', 'mkd', 'md' register BlueClothTemplate, 'markdown', 'mkd', 'md' register RDiscountTemplate, 'markdown', 'mkd', 'md' register RedcarpetTemplate::Redcarpet1, 'markdown', 'mkd', 'md' register RedcarpetTemplate::Redcarpet2, 'markdown', 'mkd', 'md' register RedcarpetTemplate, 'markdown', 'mkd', 'md' require 'tilt/textile' register RedClothTemplate, 'textile' require 'tilt/rdoc' register RDocTemplate, 'rdoc' require 'tilt/wiki' register CreoleTemplate, 'wiki', 'creole' register WikiClothTemplate, 'wiki', 'mediawiki', 'mw' require 'tilt/yajl' register YajlTemplate, 'yajl' require 'tilt/asciidoc' register AsciidoctorTemplate, 'ad', 'adoc', 'asciidoc' require 'tilt/plain' register PlainTemplate, 'html' end tilt-1.4.1/lib/tilt/0000755000004100000410000000000012162124415014241 5ustar www-datawww-datatilt-1.4.1/lib/tilt/yajl.rb0000644000004100000410000000466012162124415015533 0ustar www-datawww-datarequire 'tilt/template' module Tilt # Yajl Template implementation # # Yajl is a fast JSON parsing and encoding library for Ruby # See https://github.com/brianmario/yajl-ruby # # The template source is evaluated as a Ruby string, # and the result is converted #to_json. # # == Example # # # This is a template example. # # The template can contain any Ruby statement. # tpl <<-EOS # @counter = 0 # # # The json variable represents the buffer # # and holds the data to be serialized into json. # # It defaults to an empty hash, but you can override it at any time. # json = { # :"user#{@counter += 1}" => { :name => "Joshua Peek", :id => @counter }, # :"user#{@counter += 1}" => { :name => "Ryan Tomayko", :id => @counter }, # :"user#{@counter += 1}" => { :name => "Simone Carletti", :id => @counter }, # } # # # Since the json variable is a Hash, # # you can use conditional statements or any other Ruby statement # # to populate it. # json[:"user#{@counter += 1}"] = { :name => "Unknown" } if 1 == 2 # # # The last line doesn't affect the returned value. # nil # EOS # # template = Tilt::YajlTemplate.new { tpl } # template.render(self) # class YajlTemplate < Template self.default_mime_type = 'application/json' def self.engine_initialized? defined? ::Yajl end def initialize_engine require_template_library 'yajl' end def prepare end def evaluate(scope, locals, &block) decorate super(scope, locals, &block) end def precompiled_preamble(locals) return super if locals.include? :json "json = {}\n#{super}" end def precompiled_postamble(locals) "Yajl::Encoder.new.encode(json)" end def precompiled_template(locals) data.to_str end # Decorates the +json+ input according to given +options+. # # json - The json String to decorate. # options - The option Hash to customize the behavior. # # Returns the decorated String. def decorate(json) callback, variable = options[:callback], options[:variable] if callback && variable "var #{variable} = #{json}; #{callback}(#{variable});" elsif variable "var #{variable} = #{json};" elsif callback "#{callback}(#{json});" else json end end end end tilt-1.4.1/lib/tilt/rdoc.rb0000644000004100000410000000202712162124415015516 0ustar www-datawww-datarequire 'tilt/template' module Tilt # RDoc template. See: # http://rdoc.rubyforge.org/ # # It's suggested that your program `require 'rdoc/markup'` and # `require 'rdoc/markup/to_html'` at load time when using this template # engine in a threaded environment. class RDocTemplate < Template self.default_mime_type = 'text/html' def self.engine_initialized? defined? ::RDoc::Markup::ToHtml end def initialize_engine require_template_library 'rdoc' require_template_library 'rdoc/markup' require_template_library 'rdoc/markup/to_html' end def markup begin # RDoc 4.0 require 'rdoc/options' RDoc::Markup::ToHtml.new(RDoc::Options.new, nil) rescue ArgumentError # RDoc < 4.0 RDoc::Markup::ToHtml.new end end def prepare @engine = markup.convert(data) @output = nil end def evaluate(scope, locals, &block) @output ||= @engine.to_s end def allows_script? false end end end tilt-1.4.1/lib/tilt/asciidoc.rb0000644000004100000410000000145512162124415016351 0ustar www-datawww-datarequire 'tilt/template' # AsciiDoc see: http://asciidoc.org/ module Tilt # Asciidoctor implementation for AsciiDoc see: # http://asciidoctor.github.com/ # # Asciidoctor is an open source, pure-Ruby processor for # converting AsciiDoc documents or strings into HTML 5, # DocBook 4.5 and other formats. class AsciidoctorTemplate < Template self.default_mime_type = 'text/html' def self.engine_initialized? defined? ::Asciidoctor::Document end def initialize_engine require_template_library 'asciidoctor' end def prepare options[:header_footer] = false if options[:header_footer].nil? end def evaluate(scope, locals, &block) @output ||= Asciidoctor.render(data, options, &block) end def allows_script? false end end end tilt-1.4.1/lib/tilt/erb.rb0000644000004100000410000000577112162124415015350 0ustar www-datawww-datarequire 'tilt/template' module Tilt # ERB template implementation. See: # http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html class ERBTemplate < Template @@default_output_variable = '_erbout' def self.default_output_variable @@default_output_variable end def self.default_output_variable=(name) @@default_output_variable = name end def self.engine_initialized? defined? ::ERB end def initialize_engine require_template_library 'erb' end def prepare @outvar = options[:outvar] || self.class.default_output_variable options[:trim] = '<>' if !(options[:trim] == false) && (options[:trim].nil? || options[:trim] == true) @engine = ::ERB.new(data, options[:safe], options[:trim], @outvar) end def precompiled_template(locals) source = @engine.src source end def precompiled_preamble(locals) <<-RUBY begin __original_outvar = #{@outvar} if defined?(#{@outvar}) #{super} RUBY end def precompiled_postamble(locals) <<-RUBY #{super} ensure #{@outvar} = __original_outvar end RUBY end # ERB generates a line to specify the character coding of the generated # source in 1.9. Account for this in the line offset. if RUBY_VERSION >= '1.9.0' def precompiled(locals) source, offset = super [source, offset + 1] end end end # Erubis template implementation. See: # http://www.kuwata-lab.com/erubis/ # # ErubisTemplate supports the following additional options, which are not # passed down to the Erubis engine: # # :engine_class allows you to specify a custom engine class to use # instead of the default (which is ::Erubis::Eruby). # # :escape_html when true, ::Erubis::EscapedEruby will be used as # the engine class instead of the default. All content # within <%= %> blocks will be automatically html escaped. class ErubisTemplate < ERBTemplate def self.engine_initialized? defined? ::Erubis::Eruby end def initialize_engine require_template_library 'erubis' end def prepare @outvar = options.delete(:outvar) || self.class.default_output_variable @options.merge!(:preamble => false, :postamble => false, :bufvar => @outvar) engine_class = options.delete(:engine_class) engine_class = ::Erubis::EscapedEruby if options.delete(:escape_html) @engine = (engine_class || ::Erubis::Eruby).new(data, options) end def precompiled_preamble(locals) [super, "#{@outvar} = _buf = ''"].join("\n") end def precompiled_postamble(locals) [@outvar, super].join("\n") end # Erubis doesn't have ERB's line-off-by-one under 1.9 problem. # Override and adjust back. if RUBY_VERSION >= '1.9.0' def precompiled(locals) source, offset = super [source, offset - 1] end end end end tilt-1.4.1/lib/tilt/builder.rb0000644000004100000410000000153212162124415016215 0ustar www-datawww-datarequire 'tilt/template' module Tilt # Builder template implementation. See: # http://builder.rubyforge.org/ class BuilderTemplate < Template self.default_mime_type = 'text/xml' def self.engine_initialized? defined? ::Builder end def initialize_engine require_template_library 'builder' end def prepare; end def evaluate(scope, locals, &block) return super(scope, locals, &block) if data.respond_to?(:to_str) xml = ::Builder::XmlMarkup.new(:indent => 2) data.call(xml) xml.target! end def precompiled_preamble(locals) return super if locals.include? :xml "xml = ::Builder::XmlMarkup.new(:indent => 2)\n#{super}" end def precompiled_postamble(locals) "xml.target!" end def precompiled_template(locals) data.to_str end end end tilt-1.4.1/lib/tilt/markaby.rb0000644000004100000410000000211012162124415016206 0ustar www-datawww-datarequire 'tilt/template' module Tilt # Markaby # http://github.com/markaby/markaby class MarkabyTemplate < Template def self.builder_class @builder_class ||= Class.new(Markaby::Builder) do def __capture_markaby_tilt__(&block) __run_markaby_tilt__ do text capture(&block) end end end end def self.engine_initialized? defined? ::Markaby end def initialize_engine require_template_library 'markaby' end def prepare end def evaluate(scope, locals, &block) builder = self.class.builder_class.new({}, scope) builder.locals = locals if data.kind_of? Proc (class << builder; self end).send(:define_method, :__run_markaby_tilt__, &data) else builder.instance_eval <<-CODE, __FILE__, __LINE__ def __run_markaby_tilt__ #{data} end CODE end if block builder.__capture_markaby_tilt__(&block) else builder.__run_markaby_tilt__ end builder.to_s end end end tilt-1.4.1/lib/tilt/haml.rb0000644000004100000410000000311412162124415015506 0ustar www-datawww-datarequire 'tilt/template' module Tilt # Haml template implementation. See: # http://haml.hamptoncatlin.com/ class HamlTemplate < Template self.default_mime_type = 'text/html' def self.engine_initialized? defined? ::Haml::Engine end def initialize_engine require_template_library 'haml' end def prepare options = @options.merge(:filename => eval_file, :line => line) @engine = ::Haml::Engine.new(data, options) end def evaluate(scope, locals, &block) if @engine.respond_to?(:precompiled_method_return_value, true) super else @engine.render(scope, locals, &block) end end # Precompiled Haml source. Taken from the precompiled_with_ambles # method in Haml::Precompiler: # http://github.com/nex3/haml/blob/master/lib/haml/precompiler.rb#L111-126 def precompiled_template(locals) @engine.precompiled end def precompiled_preamble(locals) local_assigns = super @engine.instance_eval do <<-RUBY begin extend Haml::Helpers _hamlout = @haml_buffer = Haml::Buffer.new(@haml_buffer, #{options_for_buffer.inspect}) _erbout = _hamlout.buffer __in_erb_template = true _haml_locals = locals #{local_assigns} RUBY end end def precompiled_postamble(locals) @engine.instance_eval do <<-RUBY #{precompiled_method_return_value} ensure @haml_buffer = @haml_buffer.upper end RUBY end end end end tilt-1.4.1/lib/tilt/css.rb0000644000004100000410000000330112162124415015353 0ustar www-datawww-datarequire 'tilt/template' module Tilt # Sass template implementation. See: # http://haml.hamptoncatlin.com/ # # Sass templates do not support object scopes, locals, or yield. class SassTemplate < Template self.default_mime_type = 'text/css' def self.engine_initialized? defined? ::Sass::Engine end def initialize_engine require_template_library 'sass' end def prepare @engine = ::Sass::Engine.new(data, sass_options) end def evaluate(scope, locals, &block) @output ||= @engine.render end def allows_script? false end private def sass_options options.merge(:filename => eval_file, :line => line, :syntax => :sass) end end # Sass's new .scss type template implementation. class ScssTemplate < SassTemplate self.default_mime_type = 'text/css' private def sass_options options.merge(:filename => eval_file, :line => line, :syntax => :scss) end end # Lessscss template implementation. See: # http://lesscss.org/ # # Less templates do not support object scopes, locals, or yield. class LessTemplate < Template self.default_mime_type = 'text/css' def self.engine_initialized? defined? ::Less end def initialize_engine require_template_library 'less' end def prepare if ::Less.const_defined? :Engine @engine = ::Less::Engine.new(data) else parser = ::Less::Parser.new(options.merge :filename => eval_file, :line => line) @engine = parser.parse(data) end end def evaluate(scope, locals, &block) @output ||= @engine.to_css(options) end def allows_script? false end end end tilt-1.4.1/lib/tilt/template.rb0000644000004100000410000002423012162124415016402 0ustar www-datawww-datamodule Tilt TOPOBJECT = Object.superclass || Object # Base class for template implementations. Subclasses must implement # the #prepare method and one of the #evaluate or #precompiled_template # methods. class Template # Template source; loaded from a file or given directly. attr_reader :data # The name of the file where the template data was loaded from. attr_reader :file # The line number in #file where template data was loaded from. attr_reader :line # A Hash of template engine specific options. This is passed directly # to the underlying engine and is not used by the generic template # interface. attr_reader :options # Used to determine if this class's initialize_engine method has # been called yet. @engine_initialized = false class << self attr_accessor :engine_initialized alias engine_initialized? engine_initialized attr_accessor :default_mime_type end # Create a new template with the file, line, and options specified. By # default, template data is read from the file. When a block is given, # it should read template data and return as a String. When file is nil, # a block is required. # # All arguments are optional. def initialize(file=nil, line=1, options={}, &block) @file, @line, @options = nil, 1, {} [options, line, file].compact.each do |arg| case when arg.respond_to?(:to_str) ; @file = arg.to_str when arg.respond_to?(:to_int) ; @line = arg.to_int when arg.respond_to?(:to_hash) ; @options = arg.to_hash.dup when arg.respond_to?(:path) ; @file = arg.path else raise TypeError end end raise ArgumentError, "file or block required" if (@file || block).nil? # call the initialize_engine method if this is the very first time # an instance of this class has been created. if !self.class.engine_initialized? initialize_engine self.class.engine_initialized = true end # used to hold compiled template methods @compiled_method = {} # used on 1.9 to set the encoding if it is not set elsewhere (like a magic comment) # currently only used if template compiles to ruby @default_encoding = @options.delete :default_encoding # load template data and prepare (uses binread to avoid encoding issues) @reader = block || lambda { |t| read_template_file } @data = @reader.call(self) if @data.respond_to?(:force_encoding) @data.force_encoding(default_encoding) if default_encoding if !@data.valid_encoding? raise Encoding::InvalidByteSequenceError, "#{eval_file} is not valid #{@data.encoding}" end end prepare end # The encoding of the source data. Defaults to the # default_encoding-option if present. You may override this method # in your template class if you have a better hint of the data's # encoding. def default_encoding @default_encoding end def read_template_file data = File.open(file, 'rb') { |io| io.read } if data.respond_to?(:force_encoding) # Set it to the default external (without verifying) data.force_encoding(Encoding.default_external) if Encoding.default_external end data end # Render the template in the given scope with the locals specified. If a # block is given, it is typically available within the template via # +yield+. def render(scope=Object.new, locals={}, &block) evaluate scope, locals || {}, &block end # The basename of the template file. def basename(suffix='') File.basename(file, suffix) if file end # The template file's basename with all extensions chomped off. def name basename.split('.', 2).first if basename end # The filename used in backtraces to describe the template. def eval_file file || '(__TEMPLATE__)' end # Whether or not this template engine allows executing Ruby script # within the template. If this is false, +scope+ and +locals+ will # generally not be used, nor will the provided block be avaiable # via +yield+. # This should be overridden by template subclasses. def allows_script? true end protected # Called once and only once for each template subclass the first time # the template class is initialized. This should be used to require the # underlying template library and perform any initial setup. def initialize_engine end # Like Kernel#require but issues a warning urging a manual require when # running under a threaded environment. def require_template_library(name) if Thread.list.size > 1 warn "WARN: tilt autoloading '#{name}' in a non thread-safe way; " + "explicit require '#{name}' suggested." end require name end # Do whatever preparation is necessary to setup the underlying template # engine. Called immediately after template data is loaded. Instance # variables set in this method are available when #evaluate is called. # # Subclasses must provide an implementation of this method. def prepare if respond_to?(:compile!) # backward compat with tilt < 0.6; just in case warn 'Tilt::Template#compile! is deprecated; implement #prepare instead.' compile! else raise NotImplementedError end end # Execute the compiled template and return the result string. Template # evaluation is guaranteed to be performed in the scope object with the # locals specified and with support for yielding to the block. # # This method is only used by source generating templates. Subclasses that # override render() may not support all features. def evaluate(scope, locals, &block) method = compiled_method(locals.keys) method.bind(scope).call(locals, &block) end # Generates all template source by combining the preamble, template, and # postamble and returns a two-tuple of the form: [source, offset], where # source is the string containing (Ruby) source code for the template and # offset is the integer line offset where line reporting should begin. # # Template subclasses may override this method when they need complete # control over source generation or want to adjust the default line # offset. In most cases, overriding the #precompiled_template method is # easier and more appropriate. def precompiled(locals) preamble = precompiled_preamble(locals) template = precompiled_template(locals) postamble = precompiled_postamble(locals) source = '' # Ensure that our generated source code has the same encoding as the # the source code generated by the template engine. if source.respond_to?(:force_encoding) template_encoding = extract_encoding(template) source.force_encoding(template_encoding) template.force_encoding(template_encoding) end # https://github.com/rtomayko/tilt/issues/193 warn "precompiled_preamble should return String (not Array)" if preamble.is_a?(Array) warn "precompiled_postamble should return String (not Array)" if postamble.is_a?(Array) source << [preamble, template, postamble].join("\n") [source, preamble.count("\n")+1] end # A string containing the (Ruby) source code for the template. The # default Template#evaluate implementation requires either this # method or the #precompiled method be overridden. When defined, # the base Template guarantees correct file/line handling, locals # support, custom scopes, proper encoding, and support for template # compilation. def precompiled_template(locals) raise NotImplementedError end # Generates preamble code for initializing template state, and performing # locals assignment. The default implementation performs locals # assignment only. Lines included in the preamble are subtracted from the # source line offset, so adding code to the preamble does not effect line # reporting in Kernel::caller and backtraces. def precompiled_preamble(locals) locals.map do |k,v| if k.to_s =~ /\A[a-z_][a-zA-Z_0-9]*\z/ "#{k} = locals[#{k.inspect}]" else raise "invalid locals key: #{k.inspect} (keys must be variable names)" end end.join("\n") end # Generates postamble code for the precompiled template source. The # string returned from this method is appended to the precompiled # template source. def precompiled_postamble(locals) '' end # The compiled method for the locals keys provided. def compiled_method(locals_keys) @compiled_method[locals_keys] ||= compile_template_method(locals_keys) end private def compile_template_method(locals) source, offset = precompiled(locals) method_name = "__tilt_#{Thread.current.object_id.abs}" method_source = "" if method_source.respond_to?(:force_encoding) method_source.force_encoding(source.encoding) end method_source << <<-RUBY TOPOBJECT.class_eval do def #{method_name}(locals) Thread.current[:tilt_vars] = [self, locals] class << self this, locals = Thread.current[:tilt_vars] this.instance_eval do RUBY offset += method_source.count("\n") method_source << source method_source << "\nend;end;end;end" Object.class_eval method_source, eval_file, line - offset unbind_compiled_method(method_name) end def unbind_compiled_method(method_name) method = TOPOBJECT.instance_method(method_name) TOPOBJECT.class_eval { remove_method(method_name) } method end def extract_encoding(script) extract_magic_comment(script) || script.encoding end def extract_magic_comment(script) binary script do script[/\A[ \t]*\#.*coding\s*[=:]\s*([[:alnum:]\-_]+).*$/n, 1] end end def binary(string) original_encoding = string.encoding string.force_encoding(Encoding::BINARY) yield ensure string.force_encoding(original_encoding) end end end tilt-1.4.1/lib/tilt/liquid.rb0000644000004100000410000000237612162124415016065 0ustar www-datawww-datarequire 'tilt/template' module Tilt # Liquid template implementation. See: # http://liquid.rubyforge.org/ # # Liquid is designed to be a *safe* template system and threfore # does not provide direct access to execuatable scopes. In order to # support a +scope+, the +scope+ must be able to represent itself # as a hash by responding to #to_h. If the +scope+ does not respond # to #to_h it will be ignored. # # LiquidTemplate does not support yield blocks. # # It's suggested that your program require 'liquid' at load # time when using this template engine. class LiquidTemplate < Template def self.engine_initialized? defined? ::Liquid::Template end def initialize_engine require_template_library 'liquid' end def prepare @engine = ::Liquid::Template.parse(data) end def evaluate(scope, locals, &block) locals = locals.inject({}){ |h,(k,v)| h[k.to_s] = v ; h } if scope.respond_to?(:to_h) scope = scope.to_h.inject({}){ |h,(k,v)| h[k.to_s] = v ; h } locals = scope.merge(locals) end locals['yield'] = block.nil? ? '' : yield locals['content'] = locals['yield'] @engine.render(locals) end def allows_script? false end end end tilt-1.4.1/lib/tilt/coffee.rb0000644000004100000410000000205012162124415016012 0ustar www-datawww-datarequire 'tilt/template' module Tilt # CoffeeScript template implementation. See: # http://coffeescript.org/ # # CoffeeScript templates do not support object scopes, locals, or yield. class CoffeeScriptTemplate < Template self.default_mime_type = 'application/javascript' @@default_bare = false def self.default_bare @@default_bare end def self.default_bare=(value) @@default_bare = value end # DEPRECATED def self.default_no_wrap @@default_bare end # DEPRECATED def self.default_no_wrap=(value) @@default_bare = value end def self.engine_initialized? defined? ::CoffeeScript end def initialize_engine require_template_library 'coffee_script' end def prepare if !options.key?(:bare) and !options.key?(:no_wrap) options[:bare] = self.class.default_bare end end def evaluate(scope, locals, &block) @output ||= CoffeeScript.compile(data, options) end def allows_script? false end end end tilt-1.4.1/lib/tilt/radius.rb0000644000004100000410000000211412162124415016053 0ustar www-datawww-datarequire 'tilt/template' module Tilt # Radius Template # http://github.com/jlong/radius/ class RadiusTemplate < Template def self.engine_initialized? defined? ::Radius end def self.context_class @context_class ||= Class.new(Radius::Context) do attr_accessor :tilt_scope def tag_missing(name, attributes) tilt_scope.__send__(name) end def dup i = super i.tilt_scope = tilt_scope i end end end def initialize_engine require_template_library 'radius' end def prepare end def evaluate(scope, locals, &block) context = self.class.context_class.new context.tilt_scope = scope context.define_tag("yield") do block.call end locals.each do |tag, value| context.define_tag(tag) do value end end options = {:tag_prefix => 'r'}.merge(@options) parser = Radius::Parser.new(context, options) parser.parse(data) end def allows_script? false end end end tilt-1.4.1/lib/tilt/plain.rb0000644000004100000410000000047212162124415015674 0ustar www-datawww-datarequire 'tilt/template' module Tilt # Raw text (no template functionality). class PlainTemplate < Template self.default_mime_type = 'text/html' def self.engine_initialized? true end def prepare end def evaluate(scope, locals, &block) @output ||= data end end end tilt-1.4.1/lib/tilt/markdown.rb0000644000004100000410000001200512162124415016406 0ustar www-datawww-datarequire 'tilt/template' module Tilt # Discount Markdown implementation. See: # http://github.com/rtomayko/rdiscount # # RDiscount is a simple text filter. It does not support +scope+ or # +locals+. The +:smart+ and +:filter_html+ options may be set true # to enable those flags on the underlying RDiscount object. class RDiscountTemplate < Template self.default_mime_type = 'text/html' ALIAS = { :escape_html => :filter_html, :smartypants => :smart } FLAGS = [:smart, :filter_html, :smartypants, :escape_html] def flags FLAGS.select { |flag| options[flag] }.map { |flag| ALIAS[flag] || flag } end def self.engine_initialized? defined? ::RDiscount end def initialize_engine require_template_library 'rdiscount' end def prepare @engine = RDiscount.new(data, *flags) @output = nil end def evaluate(scope, locals, &block) @output ||= @engine.to_html end def allows_script? false end end # Upskirt Markdown implementation. See: # https://github.com/tanoku/redcarpet # # Supports both Redcarpet 1.x and 2.x class RedcarpetTemplate < Template def self.engine_initialized? defined? ::Redcarpet end def initialize_engine require_template_library 'redcarpet' end def prepare klass = [Redcarpet2, Redcarpet1].detect { |e| e.engine_initialized? } @engine = klass.new(file, line, options) { data } end def evaluate(scope, locals, &block) @engine.evaluate(scope, locals, &block) end def allows_script? false end # Compatibility mode for Redcarpet 1.x class Redcarpet1 < RDiscountTemplate self.default_mime_type = 'text/html' def self.engine_initialized? defined? ::RedcarpetCompat end def prepare @engine = RedcarpetCompat.new(data, *flags) @output = nil end end # Future proof mode for Redcarpet 2.x (not yet released) class Redcarpet2 < Template self.default_mime_type = 'text/html' def self.engine_initialized? defined? ::Redcarpet::Render and defined? ::Redcarpet::Markdown end def generate_renderer renderer = options.delete(:renderer) || ::Redcarpet::Render::HTML return renderer unless options.delete(:smartypants) return renderer if renderer.is_a?(Class) && renderer <= ::Redcarpet::Render::SmartyPants if renderer == ::Redcarpet::Render::XHTML ::Redcarpet::Render::SmartyHTML.new(:xhtml => true) elsif renderer == ::Redcarpet::Render::HTML ::Redcarpet::Render::SmartyHTML elsif renderer.is_a? Class Class.new(renderer) { include ::Redcarpet::Render::SmartyPants } else renderer.extend ::Redcarpet::Render::SmartyPants end end def prepare # try to support the same aliases RDiscountTemplate::ALIAS.each do |opt, aka| next if options.key? opt or not options.key? aka options[opt] = options.delete(aka) end # only raise an exception if someone is trying to enable :escape_html options.delete(:escape_html) unless options[:escape_html] @engine = ::Redcarpet::Markdown.new(generate_renderer, options) @output = nil end def evaluate(scope, locals, &block) @output ||= @engine.render(data) end def allows_script? false end end end # BlueCloth Markdown implementation. See: # http://deveiate.org/projects/BlueCloth/ class BlueClothTemplate < Template self.default_mime_type = 'text/html' def self.engine_initialized? defined? ::BlueCloth end def initialize_engine require_template_library 'bluecloth' end def prepare @engine = BlueCloth.new(data, options) @output = nil end def evaluate(scope, locals, &block) @output ||= @engine.to_html end def allows_script? false end end # Maruku markdown implementation. See: # http://maruku.rubyforge.org/ class MarukuTemplate < Template def self.engine_initialized? defined? ::Maruku end def initialize_engine require_template_library 'maruku' end def prepare @engine = Maruku.new(data, options) @output = nil end def evaluate(scope, locals, &block) @output ||= @engine.to_html end def allows_script? false end end # Kramdown Markdown implementation. See: # http://kramdown.rubyforge.org/ class KramdownTemplate < Template DUMB_QUOTES = [39, 39, 34, 34] def self.engine_initialized? defined? ::Kramdown end def initialize_engine require_template_library 'kramdown' end def prepare options[:smart_quotes] = DUMB_QUOTES unless options[:smartypants] @engine = Kramdown::Document.new(data, options) @output = nil end def evaluate(scope, locals, &block) @output ||= @engine.to_html end def allows_script? false end end end tilt-1.4.1/lib/tilt/string.rb0000644000004100000410000000072712162124415016102 0ustar www-datawww-datarequire 'tilt/template' module Tilt # The template source is evaluated as a Ruby string. The #{} interpolation # syntax can be used to generated dynamic output. class StringTemplate < Template def prepare hash = "TILT#{data.hash.abs}" @code = "<<#{hash}.chomp\n#{data}\n#{hash}" end def precompiled_template(locals) @code end def precompiled(locals) source, offset = super [source, offset + 1] end end end tilt-1.4.1/lib/tilt/textile.rb0000644000004100000410000000110212162124415016236 0ustar www-datawww-datarequire 'tilt/template' module Tilt # RedCloth implementation. See: # http://redcloth.org/ class RedClothTemplate < Template def self.engine_initialized? defined? ::RedCloth end def initialize_engine require_template_library 'redcloth' end def prepare @engine = RedCloth.new(data) options.each {|k, v| @engine.send("#{k}=", v) if @engine.respond_to? "#{k}="} @output = nil end def evaluate(scope, locals, &block) @output ||= @engine.to_html end def allows_script? false end end end tilt-1.4.1/lib/tilt/wiki.rb0000644000004100000410000000223612162124415015534 0ustar www-datawww-datarequire 'tilt/template' module Tilt # Creole implementation. See: # http://www.wikicreole.org/ class CreoleTemplate < Template def self.engine_initialized? defined? ::Creole end def initialize_engine require_template_library 'creole' end def prepare opts = {} [:allowed_schemes, :extensions, :no_escape].each do |k| opts[k] = options[k] if options[k] end @engine = Creole::Parser.new(data, opts) @output = nil end def evaluate(scope, locals, &block) @output ||= @engine.to_html end def allows_script? false end end # WikiCloth implementation. See: # http://redcloth.org/ class WikiClothTemplate < Template def self.engine_initialized? defined? ::WikiCloth::Parser end def initialize_engine require_template_library 'wikicloth' end def prepare @parser = options.delete(:parser) || WikiCloth::Parser @engine = @parser.new options.merge(:data => data) @output = nil end def evaluate(scope, locals, &block) @output ||= @engine.to_html end def allows_script? false end end end tilt-1.4.1/lib/tilt/nokogiri.rb0000644000004100000410000000170112162124415016406 0ustar www-datawww-datarequire 'tilt/template' module Tilt # Nokogiri template implementation. See: # http://nokogiri.org/ class NokogiriTemplate < Template DOCUMENT_HEADER = /^<\?xml version=\"1\.0\"\?>\n?/ self.default_mime_type = 'text/xml' def self.engine_initialized? defined? ::Nokogiri end def initialize_engine require_template_library 'nokogiri' end def prepare; end def evaluate(scope, locals) if data.respond_to?(:to_str) wrapper = proc { yield.sub(DOCUMENT_HEADER, "") } if block_given? super(scope, locals, &wrapper) else ::Nokogiri::XML::Builder.new.tap(&data).to_xml end end def precompiled_preamble(locals) return super if locals.include? :xml "xml = ::Nokogiri::XML::Builder.new { |xml| }\n#{super}" end def precompiled_postamble(locals) "xml.to_xml" end def precompiled_template(locals) data.to_str end end end tilt-1.4.1/lib/tilt/etanni.rb0000644000004100000410000000111612162124415016043 0ustar www-datawww-datarequire 'tilt/template' module Tilt class EtanniTemplate < Template def prepare separator = data.hash.abs chomp = "<<#{separator}.chomp!" start = "\n_out_ << #{chomp}\n" stop = "\n#{separator}\n" replacement = "#{stop}\\1#{start}" temp = data.strip temp.gsub!(/<\?r\s+(.*?)\s+\?>/m, replacement) @code = "_out_ = [<<#{separator}.chomp!]\n#{temp}#{stop}_out_.join" end def precompiled_template(locals) @code end def precompiled(locals) source, offset = super [source, offset + 1] end end end tilt-1.4.1/lib/tilt/csv.rb0000644000004100000410000000256312162124415015367 0ustar www-datawww-datarequire 'tilt/template' module Tilt # CSV Template implementation. See: # http://ruby-doc.org/stdlib/libdoc/csv/rdoc/CSV.html # # == Example # # # Example of csv template # tpl = <<-EOS # # header # csv << ['NAME', 'ID'] # # # data rows # @people.each do |person| # csv << [person[:name], person[:id]] # end # EOS # # @people = [ # {:name => "Joshua Peek", :id => 1}, # {:name => "Ryan Tomayko", :id => 2}, # {:name => "Simone Carletti", :id => 3} # ] # # template = Tilt::CSVTemplate.new { tpl } # template.render(self) # class CSVTemplate < Template self.default_mime_type = 'text/csv' def self.engine_initialized? engine end def self.engine if RUBY_VERSION >= '1.9.0' && defined? ::CSV ::CSV elsif defined? ::FasterCSV ::FasterCSV end end def initialize_engine if RUBY_VERSION >= '1.9.0' require_template_library 'csv' else require_template_library 'fastercsv' end end def prepare @code =<<-RUBY #{self.class.engine}.generate do |csv| #{data} end RUBY end def precompiled_template(locals) @code end def precompiled(locals) source, offset = super [source, offset + 1] end end end