rake
rake copied to clipboard
Add regexp capturing in rules
This PR allows regexp capturing and backreferencing to task_pattern
in rules.
rule task_pattern => source do |task|
# action
end
-
Regexp.last_match
($~
) will be set inProc
s at bothsource
andaction
.- Other
last_match
related special variables, such as$1
,$&
,$`
, and$'
, will also be set.
- Other
- If
source
is aString
, it may contain backreferences totask_pattern
by same format asString#sub
.
Here are some examples:
rule /^(.*)-(\d+)x(\d+)\.png$/ => [ # regexp with capture groups
proc { "#{$1}.svg" } # capture variable in a source proc
# or '\1.svg' # backreference in a source string
] do |task|
basename, width, height = $1, $2, $3 # capture variables in an action proc
sh "convert #{basename}.svg -resize #{width}x#{height} #{basename}-#{width}x#{height}.png"
end
This can make icon-32x32.png
from icon.svg
.
rule /-(?<width>\d+)x(?<height>\d+).(?<ext>png|jpg)$/ => [ # regexp with named capture groups
proc { "#{$`}.#{$~[:ext]}" } # matchdata in a source proc
# or '\`.\k<ext>' # named backreference in a source string
# or '.\k<ext>' # file extension replacement (already implemented in the current master branch)
] do |task|
sh "convert #{task.source} -resize #{$~[:width]}x#{$~[:height]} #{task.name}" # accessing named capture groups
end
rule %r{^build/(?<basename>.*?)\.html\.(?<lang>.*?)$} => [
'doc/\k<lang>/\k<basename>.md' # named backreference in a source string
] do
sh "pandoc -o #{task.name} #{task.source}"
end
This can make build/index.html.en
from doc/en/index.md
.
Although it passes all the tests, it will break backward compatibility in some cases:
-
Proc
s that refer toRegexp.last_match
related variables assigned outside the rule block -
String
sources that include backslashes (directory separator in Windows?)
Former case example:
options.match(/^CFLAGS=(.*)$/) # extract a parameter from a multiline text
rule '.o' => '.c' do |task|
sh "gcc #{$1} -c -o #{task.name} #{task.source} # $1 will be replaced to nil
end
Any feedback would be appreciated. Thanks.