# Our custom loggerrequire"middleman-core/logger"# For instrumentingrequire"active_support/notifications"# Using Thor's indifferent hash accessrequire"thor"# Core Pathname library used for traversalrequire"pathname"require"tilt"require"rack/mime"moduleMiddlemanmoduleUtil# Whether the source file is binary.## @param [String] filename The file to check.# @return [Boolean]defself.binary?(filename)ext=File.extname(filename)returntrueifext=='.svgz'returnfalseifTilt.registered?(ext.sub('.',''))ext=".#{ext}"unlessext.to_s[0]==?.mime=::Rack::Mime.mime_type(ext,nil)unlessmimebinary_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_bytedo|c|returntrueifbinary_bytes.include?(c)endreturnfalseendreturnfalseifmime.start_with?('text/')returnfalseifmime.include?('xml')returnfalseifmime.include?('json')returnfalseifmime.include?('javascript')trueend# The logger## @return [Middleman::Logger] The loggerdefself.logger(*args)if!@_logger||args.length>0@_logger=::Middleman::Logger.new(*args)end@_loggerend# Facade for ActiveSupport/Notificationdefself.instrument(name,payload={},&block)name<<".middleman"unlessname=~/\.middleman$/::ActiveSupport::Notifications.instrument(name,payload,&block)end# Recursively convert a normal Hash into a HashWithIndifferentAccess## @private# @param [Hash] data Normal hash# @return [Thor::CoreExt::HashWithIndifferentAccess]defself.recursively_enhance(data)ifdata.is_a?Hashdata=::Thor::CoreExt::HashWithIndifferentAccess.new(data)data.eachdo|key,val|data[key]=recursively_enhance(val)enddataelsifdata.is_a?Arraydata.each_with_indexdo|val,i|data[i]=recursively_enhance(val)enddataelsedataendend# Normalize a path to not include a leading slash# @param [String] path# @return [String]defself.normalize_path(path)# The tr call works around a bug in Ruby's Unicode handlingpath.sub(%r{^/},"").tr('','')end# This is a separate method from normalize_path in case we# change how we normalize pathsdefself.strip_leading_slash(path)path.sub(%r{^/},"")end# Extract the text of a Rack response as a string.# Useful for extensions implemented as Rack middleware.# @param response The response from #call# @return [String] The whole response as a string.defself.extract_response_text(response)# The rack spec states all response bodies must respond to eachresult=''response.eachdo|part,s|result<<partendresultend# Takes a matcher, which can be a literal string# or a string containing glob expressions, or a# regexp, or a proc, or anything else that responds# to #match or #call, and returns whether or not the# given path matches that matcher.## @param matcher A matcher string/regexp/proc/etc# @param path A path as a string# @return [Boolean] Whether the path matches the matcherdefself.path_match(matcher,path)ifmatcher.is_a?Stringpath.matchmatcherelsifmatcher.respond_to?:matchmatcher.matchpathelsifmatcher.respond_to?:callmatcher.callpathelseFile.fnmatch(matcher.to_s,path)endend# Get a recusive list of files inside a set of paths.# Works with symlinks.## @param paths Some paths string or Pathname# @return [Array] An array of filenamesdefself.all_files_under(*paths)# when we drop 1.8, replace this with flat_mappaths.mapdo|p|path=Pathname(p)ifpath.directory?all_files_under(*path.children)elsifpath.file?pathendend.flatten.compactendendend