class String
Rake extension methods for String.
#####################################################################
def ext(newext='')
is not given, or is the empty string, remove any existing extension.
the string, append the new extension to the end. If the new extension
Replace the file extension with +newext+. If there is no extension on
def ext(newext='') return self.dup if ['.', '..'].include? self if newext != '' newext = (newext =~ /^\./) ? newext : ("." + newext) end self.chomp(File.extname(self)) << newext end
def pathmap(spec=nil, &block)
"/path/to/file.txt"
Returns:
}
ext.downcase
"/path/to/file.TXT".pathmap("%X%{.*,*}x") { |ext|
For example:
some arbitrary calculation for the replacement.
If the replacement text is '*', then a block may be provided to perform
"bin/org/onestepback/proj/A.class"
returns:
"src/org/onestepback/proj/A.java".pathmap("%{^src,bin}X.class")
For example:
reasonable).
excluded from both the pattern and replacement text (let's keep parsing
used in the replacement text. Curly braces, commas and semi-colons are
Regular expressions may be used for the pattern, and back refs may be
semi-colons (e.g. "%{old,new;src,bin}d").
"%{old,new}d"). Multiple replacement specs should be separated by
after the % character but before the operator letter. (e.g.
by a comma and are enclosed by curly braces. The replacement spec comes
particular part of the path. The pattern and replacement are separated
pattern/replacement argument to perform simple string substitutions on a
Also the %d, %p, %f, %n, %x, and %X operators can take a
'a/b/c/d/file.txt'.pathmap("%-2d") => 'c/d'
'a/b/c/d/file.txt'.pathmap("%2d") => 'a/b'
Examples:
|+n+| directories from the right hand side of the path.
starting from the left hand side. If +n+ is negative, return (up to)
number is positive, only return (up to) +n+ directories in the path,
The %d specifier can also have a numeric prefix (e.g. '%2d'). If the
* %% -- A percent sign.
the standard file separator.
* %s -- The alternate file separator if defined, otherwise use
* %X -- Everything *but* the file extension.
is no extension.
* %x -- The file extension of the path. An empty string if there
* %d -- The directory list of the path.
* %n -- The file name of the path without its file extension.
but without any directories.
* %f -- The base file name of the path, with its file extension,
* %p -- The complete path.
recognized:
controls the details of the mapping. The following special patterns are
Map the path according to the given specification. The specification
def pathmap(spec=nil, &block) return self if spec.nil? result = '' spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag| case frag when '%f' result << File.basename(self) when '%n' result << File.basename(self).ext when '%d' result << File.dirname(self) when '%x' result << File.extname(self) when '%X' result << self.ext when '%p' result << self when '%s' result << (File::ALT_SEPARATOR || File::SEPARATOR) when '%-' # do nothing when '%%' result << "%" when /%(-?\d+)d/ result << pathmap_partial($1.to_i) when /^%\{([^}]*)\}(\d*[dpfnxX])/ patterns, operator = $1, $2 result << pathmap('%' + operator).pathmap_replace(patterns, &block) when /^%/ fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'" else result << frag end end result end
def pathmap_explode
def pathmap_explode head, tail = File.split(self) return [self] if head == self return [tail] if head == '.' || tail == '/' return [head, tail] if head == '/' return head.pathmap_explode + [tail] end
def pathmap_partial(n)
front end (left hand side) if +n+ is positive. Include |+n+|
Extract a partial path from the path. Include +n+ directories from the
def pathmap_partial(n) dirs = File.dirname(self).pathmap_explode partial_dirs = if n > 0 dirs[0...n] elsif n < 0 dirs.reverse[0...-n].reverse else "." end File.join(partial_dirs) end
def pathmap_replace(patterns, &block)
Preform the pathmap replacement operations on the given path. The
def pathmap_replace(patterns, &block) result = self patterns.split(';').each do |pair| pattern, replacement = pair.split(',') pattern = Regexp.new(pattern) if replacement == '*' && block_given? result = result.sub(pattern, &block) elsif replacement result = result.sub(pattern, replacement) else result = result.sub(pattern, '') end end result end