seto 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ memo.txt
19
+ Guardfile
20
+ *.org
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ notifications:
5
+ email:
6
+ - m.kukenko@gmail.com
7
+ script:
8
+ - bundle exec rspec
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8; mode: ruby; -*-
2
+ source 'https://rubygems.org'
3
+
4
+ def darwin?
5
+ RUBY_PLATFORM =~ /darwin/i
6
+ end
7
+
8
+ group :test do
9
+ gem 'growl', :require => darwin?
10
+ gem 'guard'
11
+ gem 'guard-rspec'
12
+ gem 'rb-fsevent', '~> 0.9.1', :require => darwin?
13
+ gem 'rspec'
14
+ end
15
+
16
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 kukenko
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # Seto
2
+
3
+ [![Build Status](https://travis-ci.org/kukenko/seto.png)](https://travis-ci.org/kukenko/seto)
4
+
5
+ Seto is pseudo sed.
6
+
7
+ ## Installation
8
+
9
+ TODO: Write installation here
10
+
11
+ ## Examples
12
+ ### substitute the replacement
13
+ require 'seto'
14
+
15
+ DATA.sed {
16
+ s /<b>/, '<strong>'
17
+ s %r!</b>!, '</strong>'
18
+ }.each { |l| puts l }
19
+
20
+ __END__
21
+ <html>
22
+ <body>
23
+ Hello <b>Seto</b> World.
24
+ </body>
25
+ </html>
26
+
27
+ ### delete the lines
28
+ require 'seto'
29
+
30
+ DATA.sed {
31
+ d if address(/<!--/, /-->/)
32
+ }.each { |l| puts l }
33
+
34
+ __END__
35
+ <html>
36
+ <body>
37
+ <!--
38
+ This is a comment.
39
+ -->
40
+ Hello Seto World.
41
+ <!--
42
+ This is a comment too.
43
+ -->
44
+ </body>
45
+ </html>
46
+
47
+ and other commands.
48
+
49
+ ## To-dos
50
+
51
+ * implement b, G, H, l, N, P, t commands
52
+ * support $ (the last line of input)
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ task :default => [:spec]
6
+
7
+ RSpec::Core::RakeTask.new(:spec) do |spec|
8
+ spec.pattern = 'spec/**/*_spec.rb'
9
+ end
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'seto'
3
+
4
+ DATA.sed {
5
+ d if address(/<!--/, /-->/)
6
+ }.each { |l| puts l }
7
+
8
+ __END__
9
+ <html>
10
+ <body>
11
+ <!--
12
+ This is a comment.
13
+ -->
14
+ Hello Seto World.
15
+ <!--
16
+ This is a comment too.
17
+ -->
18
+ </body>
19
+ </html>
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'seto'
3
+
4
+ DATA.sed {
5
+ address(/<html>/) {
6
+ n
7
+ i <<-EOS
8
+ <head>
9
+ <title>hello world</title>
10
+ </head>
11
+ EOS
12
+ }
13
+ }.each { |l| puts l }
14
+
15
+ __END__
16
+ <html>
17
+ <body>
18
+ Hello Seto World.
19
+ </body>
20
+ </html>
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'seto'
3
+
4
+ DATA.sed {
5
+ s /<b>/, '<strong>'
6
+ s %r!</b>!, '</strong>'
7
+ }.each { |l| puts l }
8
+
9
+ __END__
10
+ <html>
11
+ <body>
12
+ Hello <b>Seto</b> World.
13
+ </body>
14
+ </html>
data/lib/seto.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "seto/version"
2
+
3
+ module Seto
4
+ require 'seto/ext/io'
5
+ require 'seto/ext/string'
6
+ end
@@ -0,0 +1,151 @@
1
+ module Seto
2
+ class Editor
3
+ attr_reader :current_line, :line_number, :result
4
+ def initialize(enumerator)
5
+ @enumerator = enumerator
6
+ @patterns = {}
7
+ @result = []
8
+ @hold_space = []
9
+ end
10
+
11
+ def load
12
+ @current_line, @line_number = @enumerator.next
13
+ end
14
+
15
+ def append(text)
16
+ @current_line += text
17
+ end
18
+
19
+ def change(text)
20
+ @current_line = text
21
+ end
22
+
23
+ def delete
24
+ @current_line = ''
25
+ end
26
+
27
+ def insert(text)
28
+ @current_line = "#{text}#{@current_line}"
29
+ end
30
+
31
+ def substitute(pattern, replace, flag=nil)
32
+ method = :sub!
33
+ method = :gsub! if flag && flag == :g
34
+ @current_line.send method, pattern, replace
35
+ end
36
+
37
+ def transform(pattern, replace)
38
+ @current_line.tr! pattern, replace
39
+ end
40
+
41
+ def copy
42
+ @result << @current_line.dup
43
+ end
44
+
45
+ def get
46
+ @current_line = @hold_space.pop
47
+ end
48
+
49
+ def hold
50
+ @hold_space << @current_line.dup
51
+ end
52
+
53
+ def exchange
54
+ @current_line, hs = @hold_space.pop, @current_line
55
+ @hold_space << hs
56
+ end
57
+
58
+ def lineno
59
+ Kernel.print @line_number
60
+ end
61
+
62
+ def next
63
+ copy
64
+ load
65
+ end
66
+
67
+ def print
68
+ Kernel.print @current_line
69
+ end
70
+
71
+ def quit
72
+ copy
73
+ raise StopIteration
74
+ end
75
+
76
+ def read(filename)
77
+ begin
78
+ text = open(filename).read
79
+ rescue
80
+ # ignore
81
+ end
82
+ append text if text
83
+ end
84
+
85
+ def write(filename)
86
+ open(filename, 'a') do |f|
87
+ f.write @current_line
88
+ end
89
+ end
90
+
91
+ def match?(condition)
92
+ case condition
93
+ when Fixnum then condition == @line_number
94
+ when Regexp then condition =~ @current_line
95
+ else
96
+ condition
97
+ end
98
+ end
99
+
100
+ def cover?(first, last)
101
+ case [first.class, last.class]
102
+ when [Fixnum, Fixnum] then cover1 first, last
103
+ else cover2 first, last
104
+ end
105
+ end
106
+
107
+ private
108
+
109
+ def cover1(first, last)
110
+ (first..last).cover? @line_number
111
+ end
112
+
113
+ def cover2(first, last)
114
+ (match_first? first) && (match_second? first, last)
115
+ end
116
+
117
+ def match_first?(condition)
118
+ case condition
119
+ when Fixnum then condition <= @line_number
120
+ when Regexp
121
+ unless @patterns.has_key? condition
122
+ if match? condition
123
+ @patterns[condition] = @line_number
124
+ true
125
+ else
126
+ false
127
+ end
128
+ else
129
+ true
130
+ end
131
+ end
132
+ end
133
+
134
+ def match_second?(*conditions)
135
+ condition = conditions[1]
136
+ case condition
137
+ when Fixnum then condition >= @line_number
138
+ when Regexp
139
+ unless @patterns.has_key? condition
140
+ if match? condition
141
+ @patterns[condition] = @line_number
142
+ end
143
+ true
144
+ else
145
+ conditions.each { |key| @patterns.delete key }
146
+ false
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,7 @@
1
+ require 'seto/sed'
2
+
3
+ class IO
4
+ def sed(&block)
5
+ Seto::Sed.new(self.each.with_index(1)).edit &block
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def sed(&block)
3
+ Seto::Sed.new(self.each_line.with_index(1)).edit &block
4
+ end
5
+ end
data/lib/seto/sed.rb ADDED
@@ -0,0 +1,93 @@
1
+ require 'forwardable'
2
+ require 'seto/editor'
3
+
4
+ module Seto
5
+ class Sed
6
+ extend Forwardable
7
+
8
+ def initialize(enumerator)
9
+ @editor = Seto::Editor.new(enumerator)
10
+ end
11
+
12
+ def edit(&block)
13
+ loop do
14
+ @editor.load
15
+ instance_eval &block
16
+ @editor.copy
17
+ end
18
+ @editor.result.reject { |l| l.empty? }
19
+ end
20
+
21
+ def address(pattern, last=nil)
22
+ result = cover?(pattern, last)
23
+ yield if result && block_given?
24
+ result
25
+ end
26
+
27
+ def_delegator :@editor, :append, :a
28
+ def_delegator :@editor, :change, :c
29
+ def_delegator :@editor, :delete, :d
30
+ def_delegator :@editor, :get, :g
31
+ def_delegator :@editor, :hold, :h
32
+ def_delegator :@editor, :insert, :i
33
+ def_delegator :@editor, :lineno
34
+ def_delegator :@editor, :next, :n
35
+ def_delegator :@editor, :print, :p
36
+ def_delegator :@editor, :quit, :q
37
+ def_delegator :@editor, :read, :r
38
+ def_delegator :@editor, :substitute, :s
39
+ def_delegator :@editor, :write, :w
40
+ def_delegator :@editor, :exchange, :x
41
+ def_delegator :@editor, :transform, :y
42
+
43
+ # :label
44
+ def label
45
+ raise NotImplementedError
46
+ end
47
+
48
+ # b
49
+ def branch(label)
50
+ raise NotImplementedError
51
+ end
52
+
53
+ # G
54
+ def get!
55
+ raise NotImplementedError
56
+ end
57
+
58
+ # H
59
+ def hold!
60
+ raise NotImplementedError
61
+ end
62
+
63
+ # l
64
+ def look
65
+ raise NotImplementedError
66
+ end
67
+
68
+ # N
69
+ def next!
70
+ raise NotImplementedError
71
+ end
72
+
73
+ # P
74
+ def print!
75
+ raise NotImplementedError
76
+ end
77
+
78
+ # t
79
+ def test(label)
80
+ raise NotImplementedError
81
+ end
82
+
83
+ private
84
+
85
+ def cover?(pattern, last=nil)
86
+ unless last
87
+ @editor.match? pattern
88
+ else
89
+ @editor.cover? pattern, last
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,3 @@
1
+ module Seto
2
+ VERSION = "0.0.1"
3
+ end
data/seto.gemspec ADDED
@@ -0,0 +1,17 @@
1
+ # -*- coding: utf-8; mode: ruby; -*-
2
+ require File.expand_path('../lib/seto/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["kukenko"]
6
+ gem.email = ["m.kukenko@gmail.com"]
7
+ gem.summary = %q{Seto is pseudo sed}
8
+ gem.description = gem.summary
9
+ gem.homepage = "https://github.com/kukenko/seto"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.name = "seto"
13
+ # gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Seto::VERSION
17
+ end
@@ -0,0 +1,3 @@
1
+ # Seto
2
+
3
+ Seto is pseudo sed.
@@ -0,0 +1,2 @@
1
+ Seto is pseudo sed.
2
+ Seto is a place name.
@@ -0,0 +1 @@
1
+ Seto is pseudo sed.
@@ -0,0 +1,5 @@
1
+ hello
2
+ START hello
3
+ hello
4
+ END hello
5
+ hello
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe IO do
4
+ let(:file) { File.open('./spec/files/seto_is.txt') }
5
+
6
+ describe '#sed' do
7
+ it 'executes Seto::Sed commands' do
8
+ file.sed do
9
+ s /is/, 'no'
10
+ s /a place name/, 'Hanayome'
11
+ s /pseudo sed/, 'Hanayome'
12
+ end
13
+ .should eql(["Seto no Hanayome.\n", "Seto no Hanayome.\n"])
14
+ end
15
+
16
+ it 'executes Seto::Sed commands with address block' do
17
+ file.sed do
18
+ s /is/, 'no'
19
+ address(2) { s /a place name/, 'Hanayome' }
20
+ s /pseudo sed/, 'Hanayome'
21
+ end
22
+ .should eql(["Seto no Hanayome.\n", "Seto no Hanayome.\n"])
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe IO do
4
+ let(:file) { File.open('./spec/files/seto_is.txt') }
5
+
6
+ describe '#sed' do
7
+ it 'executes Seto::Sed commands' do
8
+ file.sed do
9
+ s /is/, 'no'
10
+ s /a place name/, 'Hanayome'
11
+ s /pseudo sed/, 'Hanayome'
12
+ end
13
+ .should eql(["Seto no Hanayome.\n", "Seto no Hanayome.\n"])
14
+ end
15
+
16
+ it 'executes Seto::Sed commands with address block' do
17
+ file.sed do
18
+ s /is/, 'no'
19
+ address(2) { s /a place name/, 'Hanayome' }
20
+ s /pseudo sed/, 'Hanayome'
21
+ end
22
+ .should eql(["Seto no Hanayome.\n", "Seto no Hanayome.\n"])
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe String do
4
+ let(:string) { File.open('./spec/files/seto_is.txt').read }
5
+
6
+ describe '#sed' do
7
+ it 'executes Seto::Sed commands' do
8
+ string.sed do
9
+ s /is/, 'no'
10
+ s /a place name/, 'Hanayome'
11
+ s /pseudo sed/, 'Hanayome'
12
+ end
13
+ .should eql(["Seto no Hanayome.\n", "Seto no Hanayome.\n"])
14
+ end
15
+
16
+ it 'executes Seto::Sed commands with address block' do
17
+ string.sed do
18
+ s /is/, 'no'
19
+ address(2) { s /a place name/, 'Hanayome' }
20
+ s /pseudo sed/, 'Hanayome'
21
+ end
22
+ .should eql(["Seto no Hanayome.\n", "Seto no Hanayome.\n"])
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,268 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+
4
+ module Seto
5
+ describe Sed do
6
+ SIMPLE = './spec/files/simple.txt'
7
+ SETOIS = './spec/files/seto_is.txt'
8
+ STARTEND = './spec/files/start_end.txt'
9
+ SETO = './spec/files/seto.txt'
10
+
11
+ let(:simple) { Sed.new(File.open(SIMPLE).each.with_index(1)) }
12
+ let(:setois) { Sed.new(File.open(SETOIS).each.with_index(1)) }
13
+ let(:startend) { Sed.new(File.open(STARTEND).each.with_index(1)) }
14
+ let(:seto) { Sed.new(File.open(SETO).each.with_index(1)) }
15
+
16
+ it 'has the following methods' do
17
+ m = Sed.new(File.open(__FILE__).each).methods
18
+ m.should include(:edit)
19
+ m.should include(:address)
20
+ m.should include(:a)
21
+ m.should include(:c)
22
+ m.should include(:d)
23
+ m.should include(:g)
24
+ m.should include(:h)
25
+ m.should include(:i)
26
+ m.should include(:lineno)
27
+ m.should include(:n)
28
+ m.should include(:p)
29
+ m.should include(:q)
30
+ m.should include(:r)
31
+ m.should include(:s)
32
+ m.should include(:w)
33
+ m.should include(:x)
34
+ m.should include(:y)
35
+ end
36
+
37
+ describe '#address' do
38
+ it 'selects the row by the line number' do
39
+ setois.edit do
40
+ s /is/, 'no' if address(2)
41
+ s /a place name/, 'Hanayome' if address(2)
42
+ end
43
+ .should eql(["Seto is pseudo sed.\n", "Seto no Hanayome.\n"])
44
+ end
45
+
46
+ it 'selects the row by the regular expression' do
47
+ setois.edit do
48
+ s /\./, '!' if address(/pseudo/)
49
+ end
50
+ .should eql(["Seto is pseudo sed!\n", "Seto is a place name.\n"])
51
+ end
52
+
53
+ it 'selects the row by the line number range' do
54
+ setois.edit do
55
+ s /\./, '!' if address(1, 2)
56
+ end
57
+ .should eql(["Seto is pseudo sed!\n", "Seto is a place name!\n"])
58
+ end
59
+
60
+ it 'selects the row by the regexp range' do
61
+ startend.edit do
62
+ s /hello/, 'world' if address(/START/, /END/)
63
+ end
64
+ .should eql(["hello\n", "START world\n", "world\n", "END world\n", "hello\n"])
65
+ end
66
+
67
+ it 'selects the row by line number and regexp range' do
68
+ startend.edit do
69
+ s /hello/, 'world' if address(3, /END/)
70
+ end
71
+ .should eql(["hello\n", "START hello\n", "world\n", "END world\n", "hello\n"])
72
+ end
73
+
74
+ it 'selects the row by the regexp and line number range' do
75
+ startend.edit do
76
+ s /hello/, 'world' if address(/START/, 3)
77
+ end
78
+ .should eql(["hello\n", "START world\n", "world\n", "END hello\n", "hello\n"])
79
+ end
80
+
81
+ context 'with block' do
82
+ it 'selects the row by the line number' do
83
+ setois.edit do
84
+ address(2) {
85
+ s /is/, 'no'
86
+ s /a place name/, 'Hanayome'
87
+ }
88
+ end
89
+ .should eql(["Seto is pseudo sed.\n", "Seto no Hanayome.\n"])
90
+ end
91
+
92
+ it 'selects the row by the regular expression' do
93
+ setois.edit do
94
+ address(/place/) {
95
+ s /is/, 'no'
96
+ s /a place name/, 'Hanayome'
97
+ }
98
+ end
99
+ .should eql(["Seto is pseudo sed.\n", "Seto no Hanayome.\n"])
100
+ end
101
+
102
+ it 'selects the row by the regexp range' do
103
+ startend.edit do
104
+ address(/START/, /END/) do
105
+ s /hello/, 'world'
106
+ end
107
+ end
108
+ .should eql(["hello\n", "START world\n", "world\n", "END world\n", "hello\n"])
109
+ end
110
+
111
+ it 'selects the row by line number and regexp range' do
112
+ startend.edit do
113
+ address(3, /END/) {
114
+ s /hello/, 'world'
115
+ }
116
+ end
117
+ .should eql(["hello\n", "START hello\n", "world\n", "END world\n", "hello\n"])
118
+ end
119
+ end
120
+ end
121
+
122
+ describe '#a' do
123
+ it 'appends text to current line' do
124
+ simple.edit { a 'by ruby.'}
125
+ .should eql(["Seto is pseudo sed.\nby ruby."])
126
+ end
127
+ end
128
+
129
+ describe '#c' do
130
+ it 'changes the current line with text' do
131
+ simple.edit { c 'This line has been censored.'}
132
+ .should eql(["This line has been censored."])
133
+ end
134
+ end
135
+
136
+ describe '#d' do
137
+ it 'deletes current line' do
138
+ simple.edit { d }.should be_empty
139
+ end
140
+ end
141
+
142
+ describe '#g' do
143
+ it 'copies the hold space into the pattern space' do
144
+ simple.edit do
145
+ h
146
+ g
147
+ end
148
+ .should eql(["Seto is pseudo sed.\n"])
149
+ end
150
+ end
151
+
152
+ # xxx
153
+ describe '#h' do
154
+ it 'copies the pattern space into the hold space' do
155
+ simple.edit { h }
156
+ simple.instance_eval {
157
+ @editor.instance_eval { @hold_space }
158
+ }
159
+ .should eql(["Seto is pseudo sed.\n"])
160
+ end
161
+ end
162
+
163
+ describe '#i' do
164
+ it 'inserts text before current line' do
165
+ simple.edit { i 'by ruby.' }
166
+ .should eql(["by ruby.Seto is pseudo sed.\n"])
167
+ end
168
+ end
169
+
170
+ describe '#lineno' do
171
+ it 'prints current line number to stdout' do
172
+ capture {
173
+ startend.edit {
174
+ lineno if address /START/
175
+ }
176
+ }
177
+ .should eql("2")
178
+ end
179
+ end
180
+
181
+ describe '#n' do
182
+ it 'reads the next line' do
183
+ seto.edit {
184
+ address(/^#/) {
185
+ n
186
+ d if address /^$/
187
+ }
188
+ }
189
+ .should eql(["# Seto\n", "Seto is pseudo sed.\n"])
190
+ end
191
+ end
192
+
193
+ describe '#p' do
194
+ it 'prints pattern space to stdout' do
195
+ capture {
196
+ simple.edit {
197
+ p
198
+ s /s/, 'S', :g
199
+ p
200
+ }
201
+ }
202
+ .should eql("Seto is pseudo sed.\nSeto iS pSeudo Sed.\n")
203
+ end
204
+ end
205
+
206
+ describe '#q' do
207
+ it 'quit the running scripts' do
208
+ simple.edit do
209
+ q
210
+ s /s/, 'S'
211
+ end
212
+ .should eql(["Seto is pseudo sed.\n"])
213
+ end
214
+ end
215
+
216
+ describe '#r' do
217
+ it 'read from file' do
218
+ setois.edit { r SIMPLE if address(2) }
219
+ .should eql(["Seto is pseudo sed.\n",
220
+ "Seto is a place name.\nSeto is pseudo sed.\n"])
221
+ end
222
+ end
223
+
224
+ describe '#s' do
225
+ it 'changes occurrence of the regular expression into a new value' do
226
+ setois.edit do
227
+ s /is/, 'no'
228
+ s /a place name/, 'Hanayome'
229
+ s /pseudo sed/, 'Hanayome'
230
+ end
231
+ .should eql(["Seto no Hanayome.\n", "Seto no Hanayome.\n"])
232
+ end
233
+ context 'with g flag' do
234
+ it 'changes all occurrence of the regular expression into a new value' do
235
+ simple.edit { s /s/, 'S', :g }
236
+ .should eql(["Seto iS pSeudo Sed.\n"])
237
+ end
238
+ end
239
+ end
240
+
241
+ describe '#w' do
242
+ it 'writes to file' do
243
+ tempfile = Tempfile.new('seto_temp')
244
+ setois.edit { w tempfile }
245
+ open(tempfile).read.should eql("Seto is pseudo sed.\nSeto is a place name.\n")
246
+ tempfile.close!
247
+ end
248
+ end
249
+
250
+ # xxx
251
+ describe '#x' do
252
+ it 'exchanges the pattern space and hold space' do
253
+ simple.edit do
254
+ h
255
+ x
256
+ end
257
+ .should eql(["Seto is pseudo sed.\n"])
258
+ end
259
+ end
260
+
261
+ describe '#y' do
262
+ it 'transforms characters into the other charaters' do
263
+ simple.edit { y 'a-z', 'A-Z' }
264
+ .should eql(["SETO IS PSEUDO SED.\n"])
265
+ end
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Seto do
4
+ it 'extends the String class' do
5
+ ''.methods.should include(:sed)
6
+ end
7
+
8
+ it 'extends the IO class' do
9
+ IO.new(0).methods.should include(:sed)
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ require 'seto'
2
+ require 'seto/sed'
3
+ require 'stringio'
4
+
5
+ def capture
6
+ begin
7
+ $stdout = StringIO.new
8
+ yield
9
+ out = $stdout.string
10
+ ensure
11
+ $stdout = STDOUT
12
+ end
13
+ out
14
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: seto
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - kukenko
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-05 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Seto is pseudo sed
15
+ email:
16
+ - m.kukenko@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - .travis.yml
23
+ - Gemfile
24
+ - LICENSE
25
+ - README.md
26
+ - Rakefile
27
+ - examples/delete.rb
28
+ - examples/insert.rb
29
+ - examples/substitute.rb
30
+ - lib/seto.rb
31
+ - lib/seto/editor.rb
32
+ - lib/seto/ext/io.rb
33
+ - lib/seto/ext/string.rb
34
+ - lib/seto/sed.rb
35
+ - lib/seto/version.rb
36
+ - seto.gemspec
37
+ - spec/files/seto.txt
38
+ - spec/files/seto_is.txt
39
+ - spec/files/simple.txt
40
+ - spec/files/start_end.txt
41
+ - spec/lib/seto/ext/io.rb
42
+ - spec/lib/seto/ext/io_spec.rb
43
+ - spec/lib/seto/ext/string_spec.rb
44
+ - spec/lib/seto/sed_spec.rb
45
+ - spec/lib/seto_spec.rb
46
+ - spec/spec_helper.rb
47
+ homepage: https://github.com/kukenko/seto
48
+ licenses: []
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 1.8.24
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Seto is pseudo sed
71
+ test_files:
72
+ - spec/files/seto.txt
73
+ - spec/files/seto_is.txt
74
+ - spec/files/simple.txt
75
+ - spec/files/start_end.txt
76
+ - spec/lib/seto/ext/io.rb
77
+ - spec/lib/seto/ext/io_spec.rb
78
+ - spec/lib/seto/ext/string_spec.rb
79
+ - spec/lib/seto/sed_spec.rb
80
+ - spec/lib/seto_spec.rb
81
+ - spec/spec_helper.rb
82
+ has_rdoc: