module Middleman::Util

def all_files_under(path, &ignore)

Returns:
  • (Array) - An array of Pathnames for each file (no directories)

Parameters:
  • ignore () -- A proc/block that returns true if a given path should be ignored - if a path
  • path () -- Some path string or Pathname
def all_files_under(path, &ignore)
  path = Pathname(path)
  return [] if ignore && ignore.call(path)
  if path.directory?
    path.children.flat_map do |child|
      all_files_under(child, &ignore)
    end.compact
  elsif path.file?
    [path]
  else
    []
  end
end

def binary?(filename)

Returns:
  • (Boolean) -

Parameters:
  • filename (String) -- The file to check.
def binary?(filename)
  ext = File.extname(filename)
  # We hardcode detecting of gzipped SVG files
  return true if ext == '.svgz'
  return false if Tilt.registered?(ext.sub('.', ''))
  dot_ext = (ext.to_s[0] == '.') ? ext.dup : ".#{ext}"
  if mime = ::Rack::Mime.mime_type(dot_ext, nil)
    !nonbinary_mime?(mime)
  else
    file_contents_include_binary_bytes?(filename)
  end
end

def extract_response_text(response)

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

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

def file_contents_include_binary_bytes?(filename)

Returns:
  • (Boolean) -

Parameters:
  • filename (String) -- The file to check.
def file_contents_include_binary_bytes?(filename)
  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
  false
end

def full_path(path, app)

Returns:
  • (String) - Path with index file if necessary.

Parameters:
  • app (Middleman::Application) -- The requesting app.
  • path (String) -- Request path/
def full_path(path, app)
  resource = app.sitemap.find_resource_by_destination_path(path)
  unless resource
    # Try it with /index.html at the end
    indexed_path = File.join(path.sub(%r{/$}, ''), app.config[:index_file])
    resource = app.sitemap.find_resource_by_destination_path(indexed_path)
  end
  if resource
    '/' + resource.destination_path
  else
    '/' + normalize_path(path)
  end
end

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

Facade for ActiveSupport/Notification
def instrument(name, payload={}, &block)
  suffixed_name = (name =~ /\.middleman$/) ? name.dup : "#{name}.middleman"
  ::ActiveSupport::Notifications.instrument(suffixed_name, payload, &block)
end

def nonbinary_mime?(mime)

Returns:
  • (Boolean) -

Parameters:
  • mime (String) -- The mimetype to check.
def nonbinary_mime?(mime)
  case
  when mime.start_with?('text/')
    true
  when mime.include?('xml')
    true
  when mime.include?('json')
    true
  when mime.include?('javascript')
    true
  else
    false
  end
end

def normalize_path(path)

Returns:
  • (String) -

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

def 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 path_match(matcher, path)
  case
  when matcher.is_a?(String)
    path.match(matcher)
  when matcher.respond_to?(:match)
    matcher.match(path)
  when matcher.respond_to?(:call)
    matcher.call(path)
  else
    File.fnmatch(matcher.to_s, path)
  end
end

def recursively_enhance(data)

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

Parameters:
  • data (Hash) -- Normal hash

Other tags:
    Private: -
def 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 relative_path_from_resource(curr_resource, resource_url, relative)

Returns:
  • (String) -

Parameters:
  • relative (Boolean) -- If the path should be relative.
  • resource_url (String) -- The target url.
  • curr_resource (Middleman::Sitemap::Resource) -- The resource.
def relative_path_from_resource(curr_resource, resource_url, relative)
  # Switch to the relative path between resource and the given resource
  # if we've been asked to.
  if relative && curr_resource
    # Output urls relative to the destination path, not the source path
    current_dir = Pathname('/' + curr_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
    relative_path
  else
    resource_url
  end
end

def strip_leading_slash(path)

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

def 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 url_for(app, path_or_resource, options={})
  # Handle Resources and other things which define their own url method
  url = if path_or_resource.respond_to?(:url)
    path_or_resource.url
  else
    path_or_resource.dup
  end.gsub(' ', '%20')
  # Try to parse URL
  begin
    uri = URI(url)
  rescue URI::InvalidURIError
    # Nothing we can do with it, it's not really a URI
    return url
  end
  relative = options[: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 = options[:current_resource]
  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
    uri.path = relative_path_from_resource(this_resource, resource_url, effective_relative)
  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[: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[:anchor] || options[:fragment]
  uri.fragment = fragment.to_s if fragment
  # Finally make the URL back into a string
  uri.to_s
end