D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
td-agent
/
embedded
/
lib
/
ruby
/
gems
/
2.1.0
/
gems
/
hirb-0.7.3
/
lib
/
hirb
/
Filename :
formatter.rb
back
Copy
module Hirb # A Formatter object formats an output object (using Formatter.format_output) into a string based on the views defined # for its class and/or ancestry. class Formatter class<<self # This config is used by Formatter.format_output to lazily load dynamic views defined with Hirb::DynamicView. # This hash has the same format as Formatter.config. attr_accessor :dynamic_config # Array of classes whose objects respond to :to_a and allow the first # element of the converted array to determine the output class. attr_accessor :to_a_classes end self.dynamic_config = {} self.to_a_classes = %w{Array Set ActiveRecord::Relation} def initialize(additional_config={}) #:nodoc: @klass_config = {} @config = additional_config || {} end # A hash of Ruby class strings mapped to view hashes. A view hash must have at least a :method, :output_method # or :class option for a view to be applied to an output. A view hash has the following keys: # [*:method*] Specifies a global (Kernel) method to do the formatting. # [*:class*] Specifies a class to do the formatting, using its render() class method. If a symbol it's converted to a corresponding # Hirb::Helpers::* class if it exists. # [*:output_method*] Specifies a method or proc to call on output before passing it to a helper. If the output is an array, it's applied # to every element in the array. # [*:options*] Options to pass the helper method or class. # [*:ancestor*] Boolean which when true causes subclasses of the output class to inherit its config. This doesn't effect the current # output class. Defaults to false. This is used by ActiveRecord classes. # # Examples: # {'WWW::Delicious::Element'=>{:class=>'Hirb::Helpers::ObjectTable', :ancestor=>true, :options=>{:max_width=>180}}} # {'Date'=>{:class=>:auto_table, :ancestor=>true}} # {'Hash'=>{:method=>:puts}} def config @config end # Adds the view for the given class and view hash config. See Formatter.config for valid keys for view hash. def add_view(klass, view_config) @klass_config.delete(klass) @config[klass.to_s] = view_config true end # This method looks for an output object's view in Formatter.config and then Formatter.dynamic_config. # If a view is found, a stringified view is returned based on the object. If no view is found, nil is returned. The options this # class takes are a view hash as described in Formatter.config. These options will be merged with any existing helper # config hash an output class has in Formatter.config. Any block given is passed along to a helper class. def format_output(output, options={}, &block) output_class = determine_output_class(output) options = parse_console_options(options) if options.delete(:console) options = Util.recursive_hash_merge(klass_config(output_class), options) _format_output(output, options, &block) end #:stopdoc: def to_a_classes @to_a_classes ||= self.class.to_a_classes.map {|e| Util.any_const_get(e) }.compact end def _format_output(output, options, &block) output = options[:output_method] ? (output.is_a?(Array) ? output.map {|e| call_output_method(options[:output_method], e) } : call_output_method(options[:output_method], output) ) : output args = [output] args << options[:options] if options[:options] && !options[:options].empty? if options[:method] send(options[:method],*args) elsif options[:class] && (helper_class = Helpers.helper_class(options[:class])) helper_class.render(*args, &block) elsif options[:output_method] output end end def parse_console_options(options) #:nodoc: real_options = [:method, :class, :output_method].inject({}) do |h, e| h[e] = options.delete(e) if options[e]; h end real_options.merge! :options=>options end def determine_output_class(output) output.respond_to?(:to_a) && to_a_classes.any? {|e| output.is_a?(e) } ? Array(output)[0].class : output.class end def call_output_method(output_method, output) output_method.is_a?(Proc) ? output_method.call(output) : output.send(output_method) end # Internal view options built from user-defined ones. Options are built by recursively merging options from oldest # ancestors to the most recent ones. def klass_config(output_class) @klass_config[output_class] ||= build_klass_config(output_class) end def build_klass_config(output_class) output_ancestors = output_class.ancestors.map {|e| e.to_s}.reverse output_ancestors.pop hash = output_ancestors.inject({}) {|h, ancestor_klass| add_klass_config_if_true(h, ancestor_klass) {|c, klass| c[klass] && c[klass][:ancestor] } } add_klass_config_if_true(hash, output_class.to_s) {|c, klass| c[klass] } end def add_klass_config_if_true(hash, klass) if yield(@config, klass) Util.recursive_hash_merge hash, @config[klass] elsif yield(self.class.dynamic_config, klass) @config[klass] = self.class.dynamic_config[klass].dup # copy to local Util.recursive_hash_merge hash, self.class.dynamic_config[klass] else hash end end def reset_klass_config @klass_config = {} end #:startdoc: end end