module Middleman::Util

def self.all_files_under(*paths)

Returns:
  • (Array) - An array of filenames

Parameters:
  • paths () -- Some paths string or Pathname
def self.all_files_under(*paths)
  # when we drop 1.8, replace this with flat_map
  paths.map do |p|
    path = Pathname(p)
    if path.directory?
      all_files_under(*path.children)
    elsif path.file?
      path
    end
  end.flatten.compact
end

def self.binary?(filename)

Returns:
  • (Boolean) -

Parameters:
  • filename (String) -- The file to check.
def self.binary?(filename)
  ext = File.extname(filename)
  return true if ext == '.svgz'
  return false if Tilt.registered?(ext.sub('.',''))
  ext = ".#{ext}" unless ext.to_s[0] == ?.
  mime = ::Rack::Mime.mime_type(ext, nil)
  unless mime
    binary_bytes = [0, 1, 2, 3, 4, 5, 6, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 30, 31]
    s = File.read(filename, 4096) || ''
    s.each_byte do |c|
      return true if binary_bytes.include?(c)
    end
    return false
  end
  return false if mime.start_with?('text/')
  return false if mime.include?('xml')
  return false if mime.include?('json')
  return false if mime.include?('javascript')
  true
end

def self.extract_response_text(response)

Returns:
  • (String) - The whole response as a string.

Parameters:
  • response () -- The response from #call
def self.extract_response_text(response)
  # The rack spec states all response bodies must respond to each
  result = ''
  response.each do |part, s|
    result << part
  end
  result
end

def self.instrument(name, payload={}, &block)

Facade for ActiveSupport/Notification
def self.instrument(name, payload={}, &block)
  name << ".middleman" unless name =~ /\.middleman$/
  ::ActiveSupport::Notifications.instrument(name, payload, &block)
end

def self.logger(*args)

Returns:
  • (Middleman::Logger) - The logger
def self.logger(*args)
  if !@_logger || args.length > 0
    @_logger = ::Middleman::Logger.new(*args)
  end
  @_logger
end

def self.normalize_path(path)

Returns:
  • (String) -

Parameters:
  • path (String) --
def self.normalize_path(path)
  # The tr call works around a bug in Ruby's Unicode handling
  path.sub(%r{^/}, "").tr('','')
end

def self.path_match(matcher, path)

Returns:
  • (Boolean) - Whether the path matches the matcher

Parameters:
  • path () -- A path as a string
  • matcher () -- A matcher string/regexp/proc/etc
def self.path_match(matcher, path)
  if matcher.is_a? String
    path.match matcher
  elsif matcher.respond_to? :match
    matcher.match path
  elsif matcher.respond_to? :call
    matcher.call path
  else
    File.fnmatch(matcher.to_s, path)
  end
end

def self.recursively_enhance(data)

Returns:
  • (Thor::CoreExt::HashWithIndifferentAccess) -

Parameters:
  • data (Hash) -- Normal hash

Other tags:
    Private: -
def self.recursively_enhance(data)
  if data.is_a? Hash
    data = ::Thor::CoreExt::HashWithIndifferentAccess.new(data)
    data.each do |key, val|
      data[key] = recursively_enhance(val)
    end
    data
  elsif data.is_a? Array
    data.each_with_index do |val, i|
      data[i] = recursively_enhance(val)
    end
    data
  else
    data
  end
end

def self.strip_leading_slash(path)

change how we normalize paths
This is a separate method from normalize_path in case we
def self.strip_leading_slash(path)
  path.sub(%r{^/}, "")
end

def self.url_for(app, path_or_resource, options={})

path, respecting :relative_links, directory indexes, etc.
or a Resource, this will produce the nice URL configured for that
Given a source path (referenced either absolutely or relatively)
def self.url_for(app, path_or_resource, options={})
  # Handle Resources and other things which define their own url method
  url = path_or_resource.respond_to?(:url) ? path_or_resource.url : path_or_resource
  url = url.gsub(' ', '%20')
  begin
    uri = URI(url)
  rescue URI::InvalidURIError
    # Nothing we can do with it, it's not really a URI
    return url
  end
  relative = options.delete(:relative)
  raise "Can't use the relative option with an external URL" if relative && uri.host
  # Allow people to turn on relative paths for all links with
  # set :relative_links, true
  # but still override on a case by case basis with the :relative parameter.
  effective_relative = relative || false
  effective_relative = true if relative.nil? && app.config[:relative_links]
  # Try to find a sitemap resource corresponding to the desired path
  this_resource = app.current_resource # store in a local var to save work
  if path_or_resource.is_a?(::Middleman::Sitemap::Resource)
    resource = path_or_resource
    resource_url = url
  elsif this_resource && uri.path
    # Handle relative urls
    url_path = Pathname(uri.path)
    current_source_dir = Pathname('/' + this_resource.path).dirname
    url_path = current_source_dir.join(url_path) if url_path.relative?
    resource = app.sitemap.find_resource_by_path(url_path.to_s)
    resource_url = resource.url if resource
  elsif options[:find_resource] && uri.path
    resource = app.sitemap.find_resource_by_path(uri.path)
    resource_url = resource.url if resource
  end
  if resource
    # Switch to the relative path between this_resource and the given resource
    # if we've been asked to.
    if effective_relative
      # Output urls relative to the destination path, not the source path
      current_dir = Pathname('/' + this_resource.destination_path).dirname
      relative_path = Pathname(resource_url).relative_path_from(current_dir).to_s
      # Put back the trailing slash to avoid unnecessary Apache redirects
      if resource_url.end_with?('/') && !relative_path.end_with?('/')
        relative_path << '/'
      end
      uri.path = relative_path
    else
      uri.path = resource_url
    end
  else
    # If they explicitly asked for relative links but we can't find a resource...
    raise "No resource exists at #{url}" if relative
  end
  # Support a :query option that can be a string or hash
  if query = options.delete(:query)
    uri.query = query.respond_to?(:to_param) ? query.to_param : query.to_s
  end
  # Support a :fragment or :anchor option just like Padrino
  fragment = options.delete(:anchor) || options.delete(:fragment)
  uri.fragment = fragment.to_s if fragment
  # Finally make the URL back into a string
  uri.to_s
end