Created
February 27, 2010 15:19
-
-
Save kristianmandrup/316748 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Texer::Operate DSL examples | |
--------------------------- | |
Will be changed to use Ripper2Ruby API in progress for much more flexibility and power! | |
include 'finder' | |
txt = %q{ | |
gem 'a' do |b| | |
a | |
b | |
c | |
end | |
gem.call :blip | |
} | |
# DSL EXAMPLES | |
Texer::Operate.on txt do # txt.extend(Finder) | |
txt.within( :do => 'gem' ).where(:args => {:hello,'blip', :ged}) do |block| | |
# ... | |
end | |
end | |
# :do => 'gem' --> 'gem\s+#{args}\s+do |#{block_args}| | |
where(:args => {:hello,'blip', :ged}) | |
# translated into regular this expr | |
':hello\s*,\s*\'blip\'...' | |
# IF ELSIF ELSE END | |
# within : regular expr | |
txt.within( :if).where(:expr => /a\s*<\s*b/) # if a < v | |
# substitute ' ' with \s* | |
# :spaces means at least 1 space, so '_' is substituted with \s+ | |
txt.within( :if).where(:expr => 'a <_b', :spaces => '_') # if a < v NOT a <v, since must be at least one space after '<' | |
txt.within( :if).where(:expr => %Q{a == '1_2'}, :space => '_') # if a < v : substitute -- with \s* AND -+ with \s+ | |
txt.within( :elsif).where(:expr => 'a--<--b') # elsif a < v | |
txt.within( :else) # else end | |
# CASE WHEN END | |
txt.within( :case).where(:expr => 'x') # case x when end | |
txt.within( :when).where(:expr => 'y') # when y when|else|end | |
# CLASS | |
# module | |
txt.within( :module => :finder) # module Finder | |
# class | |
txt.within( :class => 'Finder') # module Finder | |
# module class inheritance | |
txt.within( :module => :finder).within(:class => :ruby_matcher).which(:inherits_from => {:base_matcher}) # module Finder class RubyMatcher < BaseMatcher | |
# METHODS | |
txt.within( :initializer) # def initialize | |
# singleton method | |
txt.within( :method => :hello).where(:obj => 'obj', :args=> {:a, :options => '{}'}) # def obj.hello(a, options = {}) | |
# instance method | |
txt.within( :method => :hello).where(:args=> {:a, :options => '{}'}) # def obj.hello(a, options = {}) | |
# setter | |
txt.within( :setter => :price).where(:args => {:a}) # def price=(a) | |
# exclaim ! | |
txt.within( :exclaim => :merge).where(:args => {:a}) # def merge!(a) | |
# ask ? | |
txt.within( :ask => :blue?).where(:args => {:a}) # def blue?(a) | |
# SCOPE | |
txt.within( :class_self) # def class << self ... end | |
# DO BLOCK | |
txt.within( :do => :group).where(/:test/) # group :test do OR group :test, 'dds' do | |
txt.within( :do => :group).where(:args => {:test} ) # group :test do OR group (:test) do NOT group :test, 'dds' do | |
txt.within( :do => :group).where(:block_args => {:x, :y} ) # group do |x, y | | |
txt.within( :do => :group).where(:args => ANY, :block_args => {:x, :y} ) # group :blip, 'blap, 7 |x, y | | |
txt.within( :do => /Module::#{CONST}\.abc/).where(:args => {:grip}, :block_args => {:x, :y} ) # Module::Clazz.abc :grip do |x, y | OR Module::Blip.abc :grip do |x, y | | |
# =========== | |
# BEFORE | |
Texer::Operate.on txt do # txt.extend(Finder) | |
txt.before( :do => 'gem').where(:args => {:hello,'blip', :ged}) do |block| | |
# returns block of text before the start of this matching line | |
txt.before( :class => :finder) | |
# returns block of text before the start of this matching line | |
# AFTER | |
Texer::Operate.on txt do # txt.extend(Finder) | |
txt.after( :do => 'gem').where(:args => {:hello,'blip', :ged}) do |block| | |
# returns block of text after the end of this matching block | |
txt.before( :class => :finder) | |
# returns block of text after the end of this matching block | |
# ========== | |
# MUTATATIONS | |
txt = %q{ | |
gem 'a' do |b| | |
a | |
if x - 1=0 | |
puts 'hello' | |
end | |
end | |
gem.call :blip | |
} | |
# Clipboard actions can operate in two modes, stack or overwrite | |
# By default it is in overwrite mode | |
# If a block is cut and pushed onto the stack, it can later be pop-pasted, pasting while removing the block from the clipboard stack | |
# if popped, the next item on the stack is available for pasting | |
# Also support for multiple clipboards | |
# Use case: Find block, cut line from block, then cut remaining block and insert it into outer text block | |
Texer::Operate.on txt do # txt.extend(Finder) | |
# within block gem 'a' do |b| | |
txt.after( :do => :gem ).where(:args => 'a', :block_args => 'b') do |block| | |
clipboard = Texer.clipboard | |
clipboard2 = Texer.clipboard | |
# cut line puts 'hello' | |
block.remove!(:puts).where(:string) | |
# cut remaining block and put onto clipboard | |
clipboard.cut(block, :push) | |
# paste block from clipboard after gem.call :blip | |
clipboard.paste(:pop).into(txt).after(:send => 'call').where(:args => :blip) | |
clipboard.paste(:pop).into(txt).after(:send => 'call').where(:args => :blip) # no text pasted, clipboard is empty | |
end | |
end | |
# Use case: Cut line from block, then cut remaining block and insert it into outer text block | |
Texer::Operate.on txt do # txt.extend(Finder) | |
# within block gem 'a' do |b| | |
txt.after( :do => :gem ).where(:args => 'a', :block_args => 'b') do |block| | |
# find block 'if x-1 < 0' and cut it | |
piece = block.cut(:if).where(:expr => 'x - 1 = 0') | |
block.insert(piece).in(txt).before(:send => 'call').where(:args => :blip) | |
end | |
end | |
# OR | |
Texer::Operate.on txt do # txt.extend(Finder) | |
# within block gem 'a' do |b| | |
txt.after( :do => :gem ).where(:args => 'a', :block_args => 'b') do |block| | |
# find block 'if x-1 < 0' and cut it (and move to clipboard) | |
cut_block = clipboard.cut.from(block).content(:if).where(:expr => 'x - 1 = 0') | |
# replace puts '..' with puts "goodbye" | |
cut_block.replace(:puts).where(:string).with(:puts => %Q{ "goodbye" }) | |
# alternative syntax | |
cut_block.replace(:puts).where(:string).with(:puts).where(:args => "goodbye") | |
# paste block from clipboard before gem.call :blip | |
txt.insert(cut_block).before(:send => 'call').where(:args => :blip) | |
txt.append(clipboard.paste(:pop)) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment