# encoding: UTF-8 require 'erb' require 'uri' module Pizzazz class Colorer def initialize(object, options = nil) options ||= {} @object = object @indent = 0 @array_limit = options[:array_limit] || options[:limit] || 0 @array_omission = options[:array_omission] || '…' @value_limit = options[:value_limit] || 0 @value_omission = options[:value_omission] || '…' @tab = options[:tab] || ' ' @prefix = options[:prefix] @omit_root_container = options[:omit_root_container] || false @detect_links = options[:detect_links] == nil ? true : options[:detect_links] @sort_keys = options[:sort_keys] == nil ? true : options[:sort_keys] end def ify return '' unless @object # Parse output = node(@object, true) return output unless @prefix # Add prefix prefix = %Q{#{@prefix}} lines = output.split("\n") prefix + lines.join("\n#{prefix}") end private URL_PATTERN = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,})([\/\w \.-]*)*\/?$/i def tab %Q{#{@tab * @indent}} end def truncate(string) return string if @value_limit < 1 text = string.dup stop = @value_limit - @value_omission.length (text.length > @value_limit ? text[0...stop] + @value_omission : text).to_s end def node(object, root = false) omit_container = root && @omit_root_container case object when String if @detect_links && is_link?(object) %Q{"#{truncate(::ERB::Util.h(object.gsub("\n", '\n')))}"} else %Q{"#{truncate(::ERB::Util.h(object.gsub("\n", '\n')))}"} end when Time %Q{#{object.to_json}} when TrueClass %Q{true} when FalseClass %Q{false} when NilClass %Q{null} when Numeric %Q{#{object}} when Hash return omit_container ? '' : '{}' if object.length == 0 string = if omit_container '' else @indent += 1 %Q[{\n] end rows = [] keys = object.keys.collect(&:to_s) keys.sort! if @sort_keys keys.each do |key| value = (object[key] != nil ? object[key] : object[key.to_sym]) row = %Q{"#{key}": #{node(value)}} # Hopefully most keys will be sane since there are probably JSON row = %Q{#{row}} rows << tab + row end string << rows.join(%Q{,\n}) unless omit_container @indent -= 1 string << %Q[\n#{tab}}] end string when Array return omit_container ? '' : '[]' if object.length == 0 string = if omit_container '' else @indent += 1 %Q{[\n} end rows = [] array = @array_limit > 0 ? object[0...@array_limit] : object array.each do |value| rows << tab + node(value) end if @array_limit > 0 and object.length > @array_limit rows << tab + (object[0].is_a?(Hash) ? %Q[{ #{@array_omission} }] : %Q{#{@array_omission}}) end string << rows.join(%Q{,\n}) unless omit_container @indent -= 1 string << %Q{\n#{tab}]} end string end end def is_link?(string) scheme = URI.parse(string).scheme scheme == 'http' || scheme == 'https' rescue false end end end