tilt-2.0.10/0000755000175000017500000000000013542210003012076 5ustar josephjosephtilt-2.0.10/HACKING0000644000175000017500000000045613542210003013072 0ustar josephjosephClone: 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-2.0.10/tilt.gemspec0000644000175000017500000000323113542210003014416 0ustar josephjosephGem::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 = '2.0.10' s.date = '2019-09-23' 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[ COPYING bin/tilt lib/tilt.rb lib/tilt/asciidoc.rb lib/tilt/babel.rb lib/tilt/bluecloth.rb lib/tilt/builder.rb lib/tilt/coffee.rb lib/tilt/commonmarker.rb lib/tilt/creole.rb lib/tilt/csv.rb lib/tilt/dummy.rb lib/tilt/erb.rb lib/tilt/erubi.rb lib/tilt/erubis.rb lib/tilt/etanni.rb lib/tilt/haml.rb lib/tilt/kramdown.rb lib/tilt/less.rb lib/tilt/liquid.rb lib/tilt/livescript.rb lib/tilt/mapping.rb lib/tilt/markaby.rb lib/tilt/maruku.rb lib/tilt/nokogiri.rb lib/tilt/pandoc.rb lib/tilt/plain.rb lib/tilt/prawn.rb lib/tilt/radius.rb lib/tilt/rdiscount.rb lib/tilt/rdoc.rb lib/tilt/redcarpet.rb lib/tilt/redcloth.rb lib/tilt/rst-pandoc.rb lib/tilt/sass.rb lib/tilt/sigil.rb lib/tilt/string.rb lib/tilt/template.rb lib/tilt/typescript.rb lib/tilt/wikicloth.rb lib/tilt/yajl.rb ] # = MANIFEST = s.executables = ['tilt'] 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-2.0.10/.gitignore0000644000175000017500000000011213542210003014060 0ustar josephjoseph/dist *.swp /Gemfile.lock /vendor /.bundle /.yardoc /doc .sass-cache /man tilt-2.0.10/lib/0000755000175000017500000000000013542210003012644 5ustar josephjosephtilt-2.0.10/lib/tilt.rb0000644000175000017500000001416013542210003014147 0ustar josephjosephrequire 'tilt/mapping' require 'tilt/template' # Namespace for Tilt. This module is not intended to be included anywhere. module Tilt # Current version. VERSION = '2.0.10' @default_mapping = Mapping.new # @return [Tilt::Mapping] the main mapping object def self.default_mapping @default_mapping end # @private def self.lazy_map default_mapping.lazy_map end # @see Tilt::Mapping#register def self.register(template_class, *extensions) default_mapping.register(template_class, *extensions) end # @see Tilt::Mapping#register_lazy def self.register_lazy(class_name, file, *extensions) default_mapping.register_lazy(class_name, file, *extensions) end # @deprecated Use {register} instead. def self.prefer(template_class, *extensions) register(template_class, *extensions) end # @see Tilt::Mapping#registered? def self.registered?(ext) default_mapping.registered?(ext) end # @see Tilt::Mapping#new def self.new(file, line=nil, options={}, &block) default_mapping.new(file, line, options, &block) end # @see Tilt::Mapping#[] def self.[](file) default_mapping[file] end # @see Tilt::Mapping#template_for def self.template_for(file) default_mapping.template_for(file) end # @see Tilt::Mapping#templates_for def self.templates_for(file) default_mapping.templates_for(file) end # @return the template object that is currently rendering. # # @example # tmpl = Tilt['index.erb'].new { '<%= Tilt.current_template %>' } # tmpl.render == tmpl.to_s # # @note This is currently an experimental feature and might return nil # in the future. def self.current_template Thread.current[:tilt_current_template] 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. # # @note # Tilt::Cache is a thin wrapper around Hash. It has the following # limitations: # * Not thread-safe. # * Size is unbounded. # * Keys are not copied defensively, and should not be modified after # being passed to #fetch. More specifically, the values returned by # key#hash and key#eql? should not change. # If this is too limiting for you, use a different cache implementation. class Cache def initialize @cache = {} end # Caches a value for key, or returns the previously cached value. # If a value has been previously cached for key then it is # returned. Otherwise, block is yielded to and its return value # which may be nil, is cached under key and returned. # @yield # @yieldreturn the value to cache for key def fetch(*key) @cache.fetch(key) do @cache[key] = yield end end # Clears the cache. def clear @cache = {} end end # Template Implementations ================================================ # ERB register_lazy :ERBTemplate, 'tilt/erb', 'erb', 'rhtml' register_lazy :ErubisTemplate, 'tilt/erubis', 'erb', 'rhtml', 'erubis' register_lazy :ErubiTemplate, 'tilt/erubi', 'erb', 'rhtml', 'erubi' # Markdown register_lazy :BlueClothTemplate, 'tilt/bluecloth', 'markdown', 'mkd', 'md' register_lazy :MarukuTemplate, 'tilt/maruku', 'markdown', 'mkd', 'md' register_lazy :KramdownTemplate, 'tilt/kramdown', 'markdown', 'mkd', 'md' register_lazy :RDiscountTemplate, 'tilt/rdiscount', 'markdown', 'mkd', 'md' register_lazy :RedcarpetTemplate, 'tilt/redcarpet', 'markdown', 'mkd', 'md' register_lazy :CommonMarkerTemplate, 'tilt/commonmarker', 'markdown', 'mkd', 'md' register_lazy :PandocTemplate, 'tilt/pandoc', 'markdown', 'mkd', 'md' # Rest (sorted by name) register_lazy :AsciidoctorTemplate, 'tilt/asciidoc', 'ad', 'adoc', 'asciidoc' register_lazy :BabelTemplate, 'tilt/babel', 'es6', 'babel', 'jsx' register_lazy :BuilderTemplate, 'tilt/builder', 'builder' register_lazy :CSVTemplate, 'tilt/csv', 'rcsv' register_lazy :CoffeeScriptTemplate, 'tilt/coffee', 'coffee' register_lazy :CoffeeScriptLiterateTemplate, 'tilt/coffee', 'litcoffee' register_lazy :CreoleTemplate, 'tilt/creole', 'wiki', 'creole' register_lazy :EtanniTemplate, 'tilt/etanni', 'etn', 'etanni' register_lazy :HamlTemplate, 'tilt/haml', 'haml' register_lazy :LessTemplate, 'tilt/less', 'less' register_lazy :LiquidTemplate, 'tilt/liquid', 'liquid' register_lazy :LiveScriptTemplate, 'tilt/livescript','ls' register_lazy :MarkabyTemplate, 'tilt/markaby', 'mab' register_lazy :NokogiriTemplate, 'tilt/nokogiri', 'nokogiri' register_lazy :PlainTemplate, 'tilt/plain', 'html' register_lazy :PrawnTemplate, 'tilt/prawn', 'prawn' register_lazy :RDocTemplate, 'tilt/rdoc', 'rdoc' register_lazy :RadiusTemplate, 'tilt/radius', 'radius' register_lazy :RedClothTemplate, 'tilt/redcloth', 'textile' register_lazy :RstPandocTemplate, 'tilt/rst-pandoc', 'rst' register_lazy :SassTemplate, 'tilt/sass', 'sass' register_lazy :ScssTemplate, 'tilt/sass', 'scss' register_lazy :SigilTemplate, 'tilt/sigil', 'sigil' register_lazy :StringTemplate, 'tilt/string', 'str' register_lazy :TypeScriptTemplate, 'tilt/typescript', 'ts', 'tsx' register_lazy :WikiClothTemplate, 'tilt/wikicloth', 'wiki', 'mediawiki', 'mw' register_lazy :YajlTemplate, 'tilt/yajl', 'yajl' # External template engines register_lazy 'Slim::Template', 'slim', 'slim' register_lazy 'Tilt::HandlebarsTemplate', 'tilt/handlebars', 'handlebars', 'hbs' register_lazy 'Tilt::OrgTemplate', 'org-ruby', 'org' register_lazy 'Opal::Processor', 'opal', 'opal', 'rb' register_lazy 'Tilt::JbuilderTemplate', 'tilt/jbuilder', 'jbuilder' end tilt-2.0.10/lib/tilt/0000755000175000017500000000000013542210003013620 5ustar josephjosephtilt-2.0.10/lib/tilt/dummy.rb0000644000175000017500000000010613542210003015275 0ustar josephjoseph# Used for detecting autoloading bug in JRuby class Tilt::Dummy; end tilt-2.0.10/lib/tilt/rst-pandoc.rb0000644000175000017500000000057313542210003016224 0ustar josephjosephrequire 'tilt/template' require 'tilt/pandoc' module Tilt # Pandoc reStructuredText implementation. See: # http://pandoc.org/ # Use PandocTemplate and specify input format class RstPandocTemplate < PandocTemplate def tilt_to_pandoc_mapping { :smartypants => :smart } end def pandoc_options options.merge!(f: 'rst') super end end end tilt-2.0.10/lib/tilt/sigil.rb0000644000175000017500000000124713542210003015260 0ustar josephjosephrequire 'open3' require 'shellwords' module Tilt # Standalone string interpolator and template processor implementation in Go. # see: https://github.com/gliderlabs/sigil class SigilTemplate < Template def prepare end def evaluate(scope, locals, &block) variables = locals.map {|k, v| "#{k}=#{v}" } cmd = ['sigil'] unless variables.empty? cmd << '-p' cmd.concat(variables) end out, err, status = Open3.capture3(*cmd, :stdin_data => data) if status.success? out.chomp else raise err.chomp.gsub('', file) end end def allows_script? false end end end tilt-2.0.10/lib/tilt/babel.rb0000644000175000017500000000051113542210003015207 0ustar josephjosephrequire 'tilt/template' require 'babel/transpiler' module Tilt class BabelTemplate < Template self.default_mime_type = 'application/javascript' def prepare options[:filename] ||= file end def evaluate(scope, locals, &block) @output ||= Babel::Transpiler.transform(data)["code"] end end end tilt-2.0.10/lib/tilt/redcarpet.rb0000644000175000017500000000425613542210003016125 0ustar josephjosephrequire 'tilt/template' require 'redcarpet' module Tilt # Compatibility mode for Redcarpet 1.x class Redcarpet1Template < 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 prepare @engine = RedcarpetCompat.new(data, *flags) @output = nil end def evaluate(scope, locals, &block) @output ||= @engine.to_html end def allows_script? false end end # Future proof mode for Redcarpet 2.x (not yet released) class Redcarpet2Template < Template self.default_mime_type = 'text/html' def generate_renderer renderer = options.delete(:renderer) || ::Redcarpet::Render::HTML.new(options) 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 Redcarpet1Template::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 if defined? ::Redcarpet::Render and defined? ::Redcarpet::Markdown RedcarpetTemplate = Redcarpet2Template else RedcarpetTemplate = Redcarpet1Template end end tilt-2.0.10/lib/tilt/radius.rb0000644000175000017500000000172013542210003015434 0ustar josephjosephrequire 'tilt/template' require 'radius' module Tilt # Radius Template # http://github.com/jlong/radius/ class RadiusTemplate < Template 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 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-2.0.10/lib/tilt/liquid.rb0000644000175000017500000000233413542210003015436 0ustar josephjosephrequire 'tilt/template' require 'liquid' module Tilt # Liquid template implementation. See: # http://liquidmarkup.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 prepare @engine = ::Liquid::Template.parse(data, liquid_options) 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 private def liquid_options { line_numbers: true }.merge options end end end tilt-2.0.10/lib/tilt/nokogiri.rb0000644000175000017500000000150313542210003015765 0ustar josephjosephrequire 'tilt/template' require 'nokogiri' 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 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-2.0.10/lib/tilt/markaby.rb0000644000175000017500000000171313542210003015575 0ustar josephjosephrequire 'tilt/template' require 'markaby' 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 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-2.0.10/lib/tilt/redcloth.rb0000644000175000017500000000070413542210003015752 0ustar josephjosephrequire 'tilt/template' require 'redcloth' module Tilt # RedCloth implementation. See: # http://redcloth.org/ class RedClothTemplate < Template 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-2.0.10/lib/tilt/kramdown.rb0000644000175000017500000000100213542210003015760 0ustar josephjosephrequire 'tilt/template' require 'kramdown' module Tilt # Kramdown Markdown implementation. See: # http://kramdown.rubyforge.org/ class KramdownTemplate < Template DUMB_QUOTES = [39, 39, 34, 34] 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-2.0.10/lib/tilt/mapping.rb0000644000175000017500000002214113542210003015600 0ustar josephjosephrequire 'monitor' module Tilt # Tilt::Mapping associates file extensions with template implementations. # # mapping = Tilt::Mapping.new # mapping.register(Tilt::RDocTemplate, 'rdoc') # mapping['index.rdoc'] # => Tilt::RDocTemplate # mapping.new('index.rdoc').render # # You can use {#register} to register a template class by file # extension, {#registered?} to see if a file extension is mapped, # {#[]} to lookup template classes, and {#new} to instantiate template # objects. # # Mapping also supports *lazy* template implementations. Note that regularly # registered template implementations *always* have preference over lazily # registered template implementations. You should use {#register} if you # depend on a specific template implementation and {#register_lazy} if there # are multiple alternatives. # # mapping = Tilt::Mapping.new # mapping.register_lazy('RDiscount::Template', 'rdiscount/template', 'md') # mapping['index.md'] # # => RDiscount::Template # # {#register_lazy} takes a class name, a filename, and a list of file # extensions. When you try to lookup a template name that matches the # file extension, Tilt will automatically try to require the filename and # constantize the class name. # # Unlike {#register}, there can be multiple template implementations # registered lazily to the same file extension. Tilt will attempt to load the # template implementations in order (registered *last* would be tried first), # returning the first which doesn't raise LoadError. # # If all of the registered template implementations fails, Tilt will raise # the exception of the first, since that was the most preferred one. # # mapping = Tilt::Mapping.new # mapping.register_lazy('Bluecloth::Template', 'bluecloth/template', 'md') # mapping.register_lazy('RDiscount::Template', 'rdiscount/template', 'md') # mapping['index.md'] # # => RDiscount::Template # # In the previous example we say that RDiscount has a *higher priority* than # BlueCloth. Tilt will first try to `require "rdiscount/template"`, falling # back to `require "bluecloth/template"`. If none of these are successful, # the first error will be raised. class Mapping # @private attr_reader :lazy_map, :template_map def initialize @template_map = Hash.new @lazy_map = Hash.new { |h, k| h[k] = [] } end # @private def initialize_copy(other) @template_map = other.template_map.dup @lazy_map = other.lazy_map.dup end # Registers a lazy template implementation by file extension. You # can have multiple lazy template implementations defined on the # same file extension, in which case the template implementation # defined *last* will be attempted loaded *first*. # # @param class_name [String] Class name of a template class. # @param file [String] Filename where the template class is defined. # @param extensions [Array] List of extensions. # @return [void] # # @example # mapping.register_lazy 'MyEngine::Template', 'my_engine/template', 'mt' # # defined?(MyEngine::Template) # => false # mapping['index.mt'] # => MyEngine::Template # defined?(MyEngine::Template) # => true def register_lazy(class_name, file, *extensions) # Internal API if class_name.is_a?(Symbol) Tilt.autoload class_name, file class_name = "Tilt::#{class_name}" end extensions.each do |ext| @lazy_map[ext].unshift([class_name, file]) end end # Registers a template implementation by file extension. There can only be # one template implementation per file extension, and this method will # override any existing mapping. # # @param template_class # @param extensions [Array] List of extensions. # @return [void] # # @example # mapping.register MyEngine::Template, 'mt' # mapping['index.mt'] # => MyEngine::Template def 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| @template_map[ext.to_s] = template_class end end # Checks if a file extension is registered (either eagerly or # lazily) in this mapping. # # @param ext [String] File extension. # # @example # mapping.registered?('erb') # => true # mapping.registered?('nope') # => false def registered?(ext) @template_map.has_key?(ext.downcase) or lazy?(ext) end # Instantiates a new template class based on the file. # # @raise [RuntimeError] if there is no template class registered for the # file name. # # @example # mapping.new('index.mt') # => instance of MyEngine::Template # # @see Tilt::Template.new def 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 # Looks up a template class based on file name and/or extension. # # @example # mapping['views/hello.erb'] # => Tilt::ERBTemplate # mapping['hello.erb'] # => Tilt::ERBTemplate # mapping['erb'] # => Tilt::ERBTemplate # # @return [template class] def [](file) _, ext = split(file) ext && lookup(ext) end alias template_for [] # Looks up a list of template classes based on file name. If the file name # has multiple extensions, it will return all template classes matching the # extensions from the end. # # @example # mapping.templates_for('views/index.haml.erb') # # => [Tilt::ERBTemplate, Tilt::HamlTemplate] # # @return [Array