seto 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +20 -0
- data/.travis.yml +8 -0
- data/Gemfile +16 -0
- data/LICENSE +22 -0
- data/README.md +52 -0
- data/Rakefile +9 -0
- data/examples/delete.rb +19 -0
- data/examples/insert.rb +20 -0
- data/examples/substitute.rb +14 -0
- data/lib/seto.rb +6 -0
- data/lib/seto/editor.rb +151 -0
- data/lib/seto/ext/io.rb +7 -0
- data/lib/seto/ext/string.rb +5 -0
- data/lib/seto/sed.rb +93 -0
- data/lib/seto/version.rb +3 -0
- data/seto.gemspec +17 -0
- data/spec/files/seto.txt +3 -0
- data/spec/files/seto_is.txt +2 -0
- data/spec/files/simple.txt +1 -0
- data/spec/files/start_end.txt +5 -0
- data/spec/lib/seto/ext/io.rb +25 -0
- data/spec/lib/seto/ext/io_spec.rb +25 -0
- data/spec/lib/seto/ext/string_spec.rb +25 -0
- data/spec/lib/seto/sed_spec.rb +268 -0
- data/spec/lib/seto_spec.rb +11 -0
- data/spec/spec_helper.rb +14 -0
- metadata +82 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
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
|
+
[](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
data/examples/delete.rb
ADDED
@@ -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>
|
data/examples/insert.rb
ADDED
@@ -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>
|
data/lib/seto.rb
ADDED
data/lib/seto/editor.rb
ADDED
@@ -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
|
data/lib/seto/ext/io.rb
ADDED
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
|
data/lib/seto/version.rb
ADDED
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
|
data/spec/files/seto.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Seto is pseudo sed.
|
@@ -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
|
data/spec/spec_helper.rb
ADDED
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:
|