# 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