Module: Middleman::Util
- Includes:
- Contracts
- Defined in:
- lib/middleman-core/util.rb
Defined Under Namespace
Modules: Data, UriTemplates Classes: BlogTemplateProcessor, EnhancedHash
Constant Summary
Constants included from Contracts
Class Method Summary collapse
- .all_files_under(path, &ignore) ⇒ Object
- .asset_path(app, kind, source, options = {}) ⇒ Object
- .asset_url(app, path, prefix = '', options = {}) ⇒ Object
- .binary?(filename) ⇒ Boolean
- .collect_extensions(path) ⇒ Object
-
.current_directory ⇒ Array<String>
Get the PWD and try to keep path encoding consistent.
-
.each ⇒ String
Extract the text of a Rack response as a string.
- .extract_response_text(response) ⇒ Object
- .file_contents_include_binary_bytes?(filename) ⇒ Boolean
- .find_related_files(app, files) ⇒ Object
- .full_path(path, app) ⇒ Object
-
.glob_directory(path) ⇒ Array<String>
Glob a directory and try to keep path encoding consistent.
-
.instrument(name, payload = {}, &block) ⇒ Object
Facade for ActiveSupport/Notification.
- .nonbinary_mime?(mime) ⇒ Boolean
- .normalize_path(path) ⇒ Object
- .path_match(matcher, path) ⇒ Object
-
.PATH_MATCHER ⇒ Boolean
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.
- .path_to_source_file(path, directory, type, destination_dir) ⇒ Object
-
.Pathname ⇒ Middleman::SourceFile
Convert a path to a file resprentation.
- .recursively_enhance(obj) ⇒ Object
- .relative_path_from_resource(curr_resource, resource_url, relative) ⇒ Object
- .remove_templating_extensions(path) ⇒ Object
- .rewrite_paths(body, _path, exts, &_block) ⇒ Object
- .step_through_extensions(path) {|File.extname(path)| ... } ⇒ Object
-
.String ⇒ String
Expand a path to include the index file if it's a directory.
- .strip_leading_slash(path) ⇒ Object
- .url_for(app, path_or_resource, options = {}) ⇒ Object
Methods included from Contracts
Class Method Details
.all_files_under(path, &ignore) ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/middleman-core/util.rb', line 145 def all_files_under(path, &ignore) path = Pathname(path) if path.directory? path.children.flat_map do |child| all_files_under(child, &ignore) end.compact elsif path.file? if block_given? && ignore.call(path) [] else [path] end else [] end end |
.asset_path(app, kind, source, options = {}) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/middleman-core/util.rb', line 171 def asset_path(app, kind, source, ={}) return source if source.to_s.include?('//') || source.to_s.start_with?('data:') asset_folder = case kind when :css app.config[:css_dir] when :js app.config[:js_dir] when :images app.config[:images_dir] when :fonts app.config[:fonts_dir] else kind.to_s end source = source.to_s.tr(' ', '') ignore_extension = (kind == :images || kind == :fonts) # don't append extension source << ".#{kind}" unless ignore_extension || source.end_with?(".#{kind}") asset_folder = '' if source.start_with?('/') # absolute path asset_url(app, source, asset_folder, ) end |
.asset_url(app, path, prefix = '', options = {}) ⇒ Object
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/middleman-core/util.rb', line 202 def asset_url(app, path, prefix='', ={}) # Don't touch assets which already have a full path if path.include?('//') || path.start_with?('data:') path else # rewrite paths to use their destination path result = if resource = app.sitemap.find_resource_by_destination_path(url_for(app, path)) resource.url else path = File.join(prefix, path) if resource = app.sitemap.find_resource_by_path(path) resource.url else File.join(app.config[:http_prefix], path) end end if [:relative] != true result else unless [:current_resource] raise ArgumentError, '#asset_url must be run in a context with current_resource if relative: true' end current_dir = Pathname('/' + [:current_resource].destination_path) Pathname(result).relative_path_from(current_dir.dirname).to_s end end end |
.binary?(filename) ⇒ Boolean
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/middleman-core/util.rb', line 34 def binary?(filename) path = Pathname(filename) ext = path.extname # 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?(path.to_s) end end |
.collect_extensions(path) ⇒ Object
473 474 475 476 477 478 479 |
# File 'lib/middleman-core/util.rb', line 473 def collect_extensions(path) result = [] step_through_extensions(path) { |e| result << e } result end |
.current_directory ⇒ Array<String>
Get the PWD and try to keep path encoding consistent.
413 414 415 416 417 418 419 |
# File 'lib/middleman-core/util.rb', line 413 def current_directory result = ::Dir.pwd return result unless RUBY_PLATFORM =~ /darwin/ result.encode('UTF-8', 'UTF-8-MAC') end |
.each ⇒ String
Extract the text of a Rack response as a string. Useful for extensions implemented as Rack middleware.
127 |
# File 'lib/middleman-core/util.rb', line 127 Contract RespondTo[:each] => String |
.extract_response_text(response) ⇒ Object
128 129 130 131 132 133 134 135 |
# File 'lib/middleman-core/util.rb', line 128 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 |
.file_contents_include_binary_bytes?(filename) ⇒ Boolean
387 388 389 390 391 392 393 394 395 |
# File 'lib/middleman-core/util.rb', line 387 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 |
.find_related_files(app, files) ⇒ Object
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 |
# File 'lib/middleman-core/util.rb', line 502 def (app, files) all_extensions = files.flat_map { |f| collect_extensions(f.to_s) } sass_type_aliasing = ['.scss', '.sass'] erb_type_aliasing = ['.erb', '.haml', '.slim'] if (all_extensions & sass_type_aliasing).length > 0 all_extensions |= sass_type_aliasing end if (all_extensions & erb_type_aliasing).length > 0 all_extensions |= erb_type_aliasing end all_extensions.uniq! app.sitemap.resources.select(&:file_descriptor).select { |r| local_extensions = collect_extensions(r.file_descriptor[:full_path].to_s) if (local_extensions & sass_type_aliasing).length > 0 local_extensions |= sass_type_aliasing end if (local_extensions & erb_type_aliasing).length > 0 local_extensions |= erb_type_aliasing end local_extensions.uniq! ((all_extensions & local_extensions).length > 0) && files.none? { |f| f == r.file_descriptor[:full_path] } }.map(&:file_descriptor) end |
.full_path(path, app) ⇒ Object
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/middleman-core/util.rb', line 317 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 |
.glob_directory(path) ⇒ Array<String>
Glob a directory and try to keep path encoding consistent.
401 402 403 404 405 406 407 |
# File 'lib/middleman-core/util.rb', line 401 def glob_directory(path) results = ::Dir[path] return results unless RUBY_PLATFORM =~ /darwin/ results.map { |r| r.encode('UTF-8', 'UTF-8-MAC') } end |
.instrument(name, payload = {}, &block) ⇒ Object
Facade for ActiveSupport/Notification
118 119 120 121 |
# File 'lib/middleman-core/util.rb', line 118 def instrument(name, payload={}, &block) suffixed_name = (name =~ /\.middleman$/) ? name.dup : "#{name}.middleman" ::ActiveSupport::Notifications.instrument(suffixed_name, payload, &block) end |
.nonbinary_mime?(mime) ⇒ Boolean
367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'lib/middleman-core/util.rb', line 367 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 |
.normalize_path(path) ⇒ Object
105 106 107 108 |
# File 'lib/middleman-core/util.rb', line 105 def normalize_path(path) # The tr call works around a bug in Ruby's Unicode handling URI.decode(path).sub(%r{^/}, '').tr('', '') end |
.path_match(matcher, path) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/middleman-core/util.rb', line 62 def path_match(matcher, path) case when matcher.is_a?(String) if matcher.include? '*' File.fnmatch(matcher, path) else path == matcher end when matcher.respond_to?(:match) !matcher.match(path).nil? when matcher.respond_to?(:call) matcher.call(path) else File.fnmatch(matcher.to_s, path) end end |
.PATH_MATCHER ⇒ Boolean
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.
61 |
# File 'lib/middleman-core/util.rb', line 61 Contract PATH_MATCHER, String => Bool |
.path_to_source_file(path, directory, type, destination_dir) ⇒ Object
486 487 488 489 490 491 492 493 |
# File 'lib/middleman-core/util.rb', line 486 def path_to_source_file(path, directory, type, destination_dir) types = Set.new([type]) relative_path = path.relative_path_from(directory) relative_path = File.join(destination_dir, relative_path) if destination_dir ::Middleman::SourceFile.new(Pathname(relative_path), path, directory, types) end |
.Pathname ⇒ Middleman::SourceFile
Convert a path to a file resprentation.
|
# File 'lib/middleman-core/util.rb', line 485
|
.recursively_enhance(obj) ⇒ Object
91 92 93 94 95 96 97 98 99 |
# File 'lib/middleman-core/util.rb', line 91 def recursively_enhance(obj) if obj.is_a? ::Array obj.map { |e| recursively_enhance(e) } elsif obj.is_a? ::Hash ::Hashie::Mash.new(obj) else obj end end |
.relative_path_from_resource(curr_resource, resource_url, relative) ⇒ Object
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
# File 'lib/middleman-core/util.rb', line 428 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 # 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 |
.remove_templating_extensions(path) ⇒ Object
465 466 467 |
# File 'lib/middleman-core/util.rb', line 465 def remove_templating_extensions(path) step_through_extensions(path) end |
.rewrite_paths(body, _path, exts, &_block) ⇒ Object
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
# File 'lib/middleman-core/util.rb', line 334 def rewrite_paths(body, _path, exts, &_block) matcher = /([=\'\"\(,]\s*)([^\s\'\"\)>]+(#{Regexp.union(exts)}))/ url_fn_prefix = 'url(' body.dup.gsub(matcher) do |match| opening_character = $1 asset_path = $2 if asset_path.start_with?(url_fn_prefix) opening_character << url_fn_prefix asset_path = asset_path[url_fn_prefix.length..-1] end begin uri = ::Addressable::URI.parse(asset_path) if uri.relative? && uri.host.nil? && (result = yield(asset_path)) "#{opening_character}#{result}" else match end rescue ::Addressable::URI::InvalidURIError match end end end |
.step_through_extensions(path) {|File.extname(path)| ... } ⇒ Object
448 449 450 451 452 453 454 455 456 457 458 459 |
# File 'lib/middleman-core/util.rb', line 448 def step_through_extensions(path) while ::Tilt[path] yield File.extname(path) if block_given? # Strip templating extensions as long as Tilt knows them path = path.sub(/#{::Regexp.escape(File.extname(path))}$/, '') end yield File.extname(path) if block_given? path end |
.String ⇒ String
Expand a path to include the index file if it's a directory
316 |
# File 'lib/middleman-core/util.rb', line 316 Contract String, IsA['Middleman::Application'] => String |
.strip_leading_slash(path) ⇒ Object
113 114 115 |
# File 'lib/middleman-core/util.rb', line 113 def strip_leading_slash(path) path.sub(%r{^/}, '') end |
.url_for(app, path_or_resource, options = {}) ⇒ Object
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/middleman-core/util.rb', line 235 def url_for(app, path_or_resource, ={}) # 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 # 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 = [: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 = [:current_resource] if path_or_resource.is_a?(::Middleman::Sitemap::Resource) resource = path_or_resource resource_url = url elsif this_resource && uri.path && !uri.host # 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) if resource resource_url = resource.url else # Try to find a resource relative to destination paths url_path = Pathname(uri.path) current_source_dir = Pathname('/' + this_resource.destination_path).dirname url_path = current_source_dir.join(url_path) if url_path.relative? resource = app.sitemap.find_resource_by_destination_path(url_path.to_s) resource_url = resource.url if resource end elsif [:find_resource] && uri.path && !uri.host resource = app.sitemap.find_resource_by_path(uri.path) resource_url = resource.url if resource end if resource uri.path = if this_resource URI.encode(relative_path_from_resource(this_resource, resource_url, effective_relative)) else 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 = [: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 = [:anchor] || [:fragment] uri.fragment = fragment.to_s if fragment # Finally make the URL back into a string uri.to_s end |