crystalize 0.0.1 → 0.0.7
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/Gemfile.lock +10 -2
- data/Rakefile +9 -0
- data/bin/crystalize +36 -1
- data/crystalize.gemspec +3 -0
- data/hashes.rb +6 -0
- data/lib/crystalize.rb +13 -4
- data/lib/crystalize.rb.erb +2 -0
- data/lib/crystalize/check/lines/literals.rb +9 -0
- data/lib/crystalize/check/lines/meta.rb +15 -0
- data/lib/crystalize/code.rb +10 -0
- data/lib/crystalize/code_converter.rb +75 -0
- data/lib/crystalize/code_line.rb +10 -0
- data/lib/crystalize/options_validator.rb +6 -0
- data/lib/crystalize/project_converter.rb +21 -0
- data/lib/crystalize/ruby/ruby_core_extensions.rb +30 -0
- data/lib/crystalize/support.rb +14 -0
- data/lib/crystalize/transform/code/semicolons.rb +11 -0
- data/lib/crystalize/transform/lines/literals.rb +28 -0
- data/lib/crystalize/transform/lines/private_methods.rb +78 -0
- data/lib/crystalize/version.rb +1 -1
- data/todo.md +14 -0
- metadata +47 -6
- data/lib/crystalize/converter.rb +0 -5
- data/lib/crystalize/literals.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76816478d6cbaee2a2885c5520c014236edefef4be3ed0871dab90cfb446faa9
|
4
|
+
data.tar.gz: 3e287f0e4ffe910dbb414960e5a338d696cb7e38d63b26c409491a749f8e766d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfae3ce689ddf73ca751c88e1db7676253918a8d3422fcfdf8e86f4f275fcf5a6c9bbb83e12c82b0c19ca4ff501e0ea4ca4ab10c517d8b6b8ee4c8652bc6742c
|
7
|
+
data.tar.gz: caac041d3589bd9885f535a7e521d4ab4c2255ba2fadee78d6597a4c96555f27bca23ec6a686fffa832be6a2f2911b25353c50de1599fbb32aa5c8414366b50c
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
0.0.7
|
2
|
+
-------
|
3
|
+
- Do not transform lambdas to Arrays
|
4
|
+
- Update run options
|
5
|
+
|
6
|
+
0.0.6
|
7
|
+
------
|
8
|
+
- Fix core extensions
|
9
|
+
- Tests for core extensions
|
10
|
+
- Update bin interface
|
11
|
+
|
12
|
+
0.0.5
|
13
|
+
-----
|
14
|
+
- Core extensions
|
15
|
+
- Fixes for visibility for `self.methods`
|
16
|
+
|
17
|
+
0.0.4
|
18
|
+
-----
|
19
|
+
- Fix require directive
|
20
|
+
|
21
|
+
0.0.3
|
22
|
+
------
|
23
|
+
- Fixes for bin
|
24
|
+
- Improve logic for visibility methods transform
|
25
|
+
|
26
|
+
0.0.2
|
27
|
+
-----
|
28
|
+
New features:
|
29
|
+
- Transform private,public,protected methods in files
|
30
|
+
|
31
|
+
0.0.1
|
32
|
+
------
|
33
|
+
Initial version. Nothing works
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,20 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
crystalize (0.0.
|
4
|
+
crystalize (0.0.7)
|
5
|
+
require_all
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
8
9
|
specs:
|
10
|
+
coderay (1.1.2)
|
9
11
|
diff-lcs (1.3)
|
12
|
+
method_source (0.9.2)
|
13
|
+
pry (0.12.2)
|
14
|
+
coderay (~> 1.1.0)
|
15
|
+
method_source (~> 0.9.0)
|
10
16
|
rake (10.5.0)
|
17
|
+
require_all (2.0.0)
|
11
18
|
rspec (3.8.0)
|
12
19
|
rspec-core (~> 3.8.0)
|
13
20
|
rspec-expectations (~> 3.8.0)
|
@@ -28,8 +35,9 @@ PLATFORMS
|
|
28
35
|
DEPENDENCIES
|
29
36
|
bundler (~> 1.16)
|
30
37
|
crystalize!
|
38
|
+
pry
|
31
39
|
rake (~> 10.0)
|
32
40
|
rspec (~> 3.0)
|
33
41
|
|
34
42
|
BUNDLED WITH
|
35
|
-
1.
|
43
|
+
1.17.3
|
data/Rakefile
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
|
+
require 'erb'
|
3
4
|
|
4
5
|
RSpec::Core::RakeTask.new(:spec)
|
5
6
|
|
6
7
|
task :default => :spec
|
8
|
+
|
9
|
+
|
10
|
+
task :update_require do
|
11
|
+
File.open("lib/crystalize.rb", "w") do |f|
|
12
|
+
f.write ERB.new(File.read("lib/crystalize.rb.erb")).result(binding)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
data/bin/crystalize
CHANGED
@@ -1,2 +1,37 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'crystalize'
|
4
|
+
require 'optionparser'
|
5
|
+
|
6
|
+
# Used to parse command line arguments via +OptionParser+
|
7
|
+
class ARGVParser
|
8
|
+
# Returns parsed command line +options+
|
9
|
+
# @example
|
10
|
+
# options = ARGVParser.parse(ARGV)
|
11
|
+
def self.yesno(o, args, key)
|
12
|
+
o == 'yes' ? args[key] = true : args[key] = false
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.parse(options)
|
16
|
+
args = Hash.new
|
17
|
+
|
18
|
+
opt_parser = OptionParser.new do |opts|
|
19
|
+
opts.banner = "Usage: crystalize file_regex [options]"
|
20
|
+
opts.separator ''
|
21
|
+
opts.on('-f', '--files=', 'Regex for Dir') { |o| args[:files] = o }
|
22
|
+
opts.on("--transform-literals") {|o| args[:transform_literals] = true }
|
23
|
+
opts.on("--transform-private") {|o| args[:transform_private] = true }
|
24
|
+
opts.on("--transform-all") {|o| args[:transform_all] = true }
|
25
|
+
opts.separator ''
|
26
|
+
opts.on_tail("-h", "--help", "Show this message") { abort opts.to_s }
|
27
|
+
opts.on_tail("--version", "Show version") { abort Crystalize::VERSION }
|
28
|
+
end
|
29
|
+
|
30
|
+
opt_parser.parse!(options)
|
31
|
+
args
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
files = ARGV.first.start_with?('-') ? [] : ARGV.pop
|
36
|
+
options = ARGVParser.parse(ARGV)
|
37
|
+
Crystalize::ProjectConverter.new(files, options).convert
|
data/crystalize.gemspec
CHANGED
@@ -23,7 +23,10 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
24
24
|
spec.require_paths = ["lib"]
|
25
25
|
|
26
|
+
spec.add_runtime_dependency "require_all"
|
27
|
+
|
26
28
|
spec.add_development_dependency "bundler", "~> 1.16"
|
27
29
|
spec.add_development_dependency "rake", "~> 10.0"
|
28
30
|
spec.add_development_dependency "rspec", "~> 3.0"
|
31
|
+
spec.add_development_dependency "pry"
|
29
32
|
end
|
data/hashes.rb
ADDED
data/lib/crystalize.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
|
-
require "crystalize/
|
1
|
+
require "crystalize/transform/lines/private_methods"
|
2
|
+
require "crystalize/transform/code/semicolons"
|
3
|
+
require "crystalize/ruby/ruby_core_extensions"
|
4
|
+
require "crystalize/transform/lines/literals"
|
5
|
+
require "crystalize/check/lines/literals"
|
6
|
+
require "crystalize/options_validator"
|
7
|
+
require "crystalize/project_converter"
|
8
|
+
require "crystalize/check/lines/meta"
|
9
|
+
require "crystalize/code_converter"
|
10
|
+
require "crystalize/code_line"
|
11
|
+
require "crystalize/version"
|
12
|
+
require "crystalize/support"
|
13
|
+
require "crystalize/code"
|
2
14
|
|
3
|
-
module Crystalize
|
4
|
-
# Your code goes here...
|
5
|
-
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Crystalize
|
2
|
+
class CodeConverter
|
3
|
+
# Checks
|
4
|
+
include Check::Line::Literals
|
5
|
+
# include Check::Line::PrivateMethods
|
6
|
+
|
7
|
+
# Transforms
|
8
|
+
include Transform::Line::Literals
|
9
|
+
include Transform::Line::PrivateMethods
|
10
|
+
include Transform::Code::Semicolons
|
11
|
+
|
12
|
+
attr_reader :new_content
|
13
|
+
|
14
|
+
NEWLINE_DELIMITER = "\n"
|
15
|
+
DEFAULT_OPTIONS = {
|
16
|
+
transform_all: true
|
17
|
+
}
|
18
|
+
|
19
|
+
def initialize(options, content)
|
20
|
+
@options = options
|
21
|
+
@content = transform_semicolons(content)
|
22
|
+
@new_content = []
|
23
|
+
end
|
24
|
+
|
25
|
+
def new_content_string
|
26
|
+
@new_content.join(NEWLINE_DELIMITER)
|
27
|
+
end
|
28
|
+
|
29
|
+
def convert
|
30
|
+
# check_by_line
|
31
|
+
check_full
|
32
|
+
|
33
|
+
transform_full
|
34
|
+
@new_content = transform_by_line(@new_content)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def by_line content, &block
|
40
|
+
new_content = []
|
41
|
+
content.each do |line|
|
42
|
+
yield new_content, line
|
43
|
+
end
|
44
|
+
new_content
|
45
|
+
end
|
46
|
+
|
47
|
+
def check_by_line(content)
|
48
|
+
by_line(content) do |line|
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def transform_by_line(content)
|
54
|
+
by_line(content) do |new_content, line|
|
55
|
+
l = line
|
56
|
+
l = transform_array_literal(l) if @options[:transform_literals] || @options[:transform_all]
|
57
|
+
l = transform_hash_literal(l) if @options[:transform_literals] || @options[:transform_all]
|
58
|
+
new_content << l
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def check_full
|
63
|
+
end
|
64
|
+
|
65
|
+
def transform_full
|
66
|
+
@new_content = splitted_content
|
67
|
+
@new_content = transform_private_methods(@new_content) if @options[:transform_private] || @options[:transform_all]
|
68
|
+
end
|
69
|
+
|
70
|
+
def splitted_content
|
71
|
+
@content.split(NEWLINE_DELIMITER)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Crystalize
|
2
|
+
class ProjectConverter
|
3
|
+
def initialize(files, options)
|
4
|
+
@files = files
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def convert
|
9
|
+
files = @files ? Dir[@files] : []
|
10
|
+
puts "Processing #{files.size} files"
|
11
|
+
files.select{|f| f.end_with?(".rb") }.each do |file|
|
12
|
+
converter = CodeConverter.new(@options, File.read(file))
|
13
|
+
converter.convert
|
14
|
+
result = converter.new_content_string
|
15
|
+
File.open(file, 'w') {|f| f.write result}
|
16
|
+
end
|
17
|
+
puts "Done"
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Anything < Object; end
|
2
|
+
|
3
|
+
def Hash(*args)
|
4
|
+
if args.all?{|arg| arg == Anything}
|
5
|
+
Hash
|
6
|
+
else
|
7
|
+
if args
|
8
|
+
if args.first == nil
|
9
|
+
Hash.new
|
10
|
+
elsif args.first == []
|
11
|
+
Hash.new
|
12
|
+
elsif args.first.instance_of?(Array) && args.first != []
|
13
|
+
raise TypeError
|
14
|
+
else
|
15
|
+
args.first
|
16
|
+
end
|
17
|
+
else
|
18
|
+
Hash.new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def Array(arg)
|
25
|
+
if arg == Anything
|
26
|
+
Array
|
27
|
+
else
|
28
|
+
arg.respond_to?(:to_a) ? arg.to_a : [arg]
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Crystalize
|
2
|
+
module Support
|
3
|
+
def each_cr_file_line(&block)
|
4
|
+
Dir['./**/**/*.cr'].each do |filename|
|
5
|
+
puts filename
|
6
|
+
content = []
|
7
|
+
File.readlines(filename).each do |line|
|
8
|
+
content << yield(line)
|
9
|
+
end
|
10
|
+
File.open(filename, "w") { |f| content.each do |line| f << line end}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Crystalize
|
2
|
+
module Transform
|
3
|
+
module Line
|
4
|
+
module Literals
|
5
|
+
def transform_array_literal(line)
|
6
|
+
if lambda_call_in_line?(line)
|
7
|
+
line
|
8
|
+
else
|
9
|
+
line.gsub '[]', "Array(Anything).new"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def transform_hash_literal(line)
|
14
|
+
line.gsub '{}', 'Hash(Anything, Anything).new'
|
15
|
+
end
|
16
|
+
|
17
|
+
def lambda_call_in_line?(line)
|
18
|
+
# Here is omitting calls like
|
19
|
+
# lambda_method []
|
20
|
+
# due to bad code style of lambda call, even this
|
21
|
+
# lambda call is correct
|
22
|
+
braces = /[\[][ ]*[\]]/
|
23
|
+
line.match /(\w+|[.])#{braces}/
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Crystalize
|
2
|
+
module Transform
|
3
|
+
module Line
|
4
|
+
module PrivateMethods
|
5
|
+
def transform_private_methods(lines)
|
6
|
+
new_lines = []
|
7
|
+
current_visibility = :public
|
8
|
+
non_public_triggered = false
|
9
|
+
|
10
|
+
lines.each do |line|
|
11
|
+
if private_in_line?(line)
|
12
|
+
current_visibility = :private
|
13
|
+
non_public_triggered = true
|
14
|
+
end
|
15
|
+
if protected_in_line?(line)
|
16
|
+
current_visibility = :protected
|
17
|
+
non_public_triggered = true
|
18
|
+
end
|
19
|
+
current_visibility = :public if public_in_line?(line)
|
20
|
+
|
21
|
+
if method_in_line?(line) && !self_method_in_line?(line)
|
22
|
+
new_lines << add_visibility_prefix_to_method(current_visibility, line, non_public_triggered)
|
23
|
+
elsif private_in_line?(line) || protected_in_line?(line) || public_in_line?(line)
|
24
|
+
new_lines << line_without_private(line)
|
25
|
+
else
|
26
|
+
new_lines << line
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
new_lines
|
31
|
+
end
|
32
|
+
|
33
|
+
def line_without_private(line)
|
34
|
+
""
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_visibility_prefix_to_method(current_visibility, line, non_public_triggered)
|
38
|
+
if !non_public_triggered && current_visibility == :public
|
39
|
+
line
|
40
|
+
else
|
41
|
+
" "*tabulation(line)+current_visibility.to_s + " "+ line.slice(tabulation(line), line.length)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def tabulation(line)
|
46
|
+
spaces_count = 0
|
47
|
+
line.split("").each_with_index do |c, index|
|
48
|
+
if c != " "
|
49
|
+
spaces_count = index
|
50
|
+
break
|
51
|
+
end
|
52
|
+
end
|
53
|
+
spaces_count
|
54
|
+
end
|
55
|
+
|
56
|
+
def method_in_line?(line)
|
57
|
+
line.match /[ ]*(def).*/
|
58
|
+
end
|
59
|
+
|
60
|
+
def self_method_in_line?(line)
|
61
|
+
line.match /[ ]*(def)[ ]+self[.].*/
|
62
|
+
end
|
63
|
+
|
64
|
+
def private_in_line?(line)
|
65
|
+
!!line.match(/^[ ]*(private)[ ]*$/)
|
66
|
+
end
|
67
|
+
|
68
|
+
def protected_in_line?(line)
|
69
|
+
!!line.match(/^[ ]*(protected)[ ]*$/)
|
70
|
+
end
|
71
|
+
|
72
|
+
def public_in_line?(line)
|
73
|
+
!!line.match(/^[ ]*(public)[ ]*$/)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/crystalize/version.rb
CHANGED
data/todo.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Todo
|
2
|
+
|
3
|
+
## Checks
|
4
|
+
- File should define only 1 class
|
5
|
+
- Non basic classes are not passed into hash
|
6
|
+
|
7
|
+
## Transforms
|
8
|
+
- Transform all lambda calls from `[]` to `.call`
|
9
|
+
- Automatic definition for `Anything` generic type based on class list
|
10
|
+
- Ruby ternary to if
|
11
|
+
- lonely operator `&.method` to `.try(&method)`
|
12
|
+
- `class << self` to each `self.*` method
|
13
|
+
- All `method(key: value)` to `method({key: value})`
|
14
|
+
- Transform Hashes to Ruby compatible syntax
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crystalize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oleg Orlov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: require_all
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,20 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description: Ruby to Crystal converter
|
56
84
|
email:
|
57
85
|
- orelcokolov@gmail.com
|
@@ -65,6 +93,7 @@ files:
|
|
65
93
|
- ".gitignore"
|
66
94
|
- ".rspec"
|
67
95
|
- ".travis.yml"
|
96
|
+
- CHANGELOG.md
|
68
97
|
- Gemfile
|
69
98
|
- Gemfile.lock
|
70
99
|
- LICENSE.txt
|
@@ -75,10 +104,23 @@ files:
|
|
75
104
|
- bin/setup
|
76
105
|
- crystalize-logo.png
|
77
106
|
- crystalize.gemspec
|
107
|
+
- hashes.rb
|
78
108
|
- lib/crystalize.rb
|
79
|
-
- lib/crystalize
|
80
|
-
- lib/crystalize/literals.rb
|
109
|
+
- lib/crystalize.rb.erb
|
110
|
+
- lib/crystalize/check/lines/literals.rb
|
111
|
+
- lib/crystalize/check/lines/meta.rb
|
112
|
+
- lib/crystalize/code.rb
|
113
|
+
- lib/crystalize/code_converter.rb
|
114
|
+
- lib/crystalize/code_line.rb
|
115
|
+
- lib/crystalize/options_validator.rb
|
116
|
+
- lib/crystalize/project_converter.rb
|
117
|
+
- lib/crystalize/ruby/ruby_core_extensions.rb
|
118
|
+
- lib/crystalize/support.rb
|
119
|
+
- lib/crystalize/transform/code/semicolons.rb
|
120
|
+
- lib/crystalize/transform/lines/literals.rb
|
121
|
+
- lib/crystalize/transform/lines/private_methods.rb
|
81
122
|
- lib/crystalize/version.rb
|
123
|
+
- todo.md
|
82
124
|
homepage: https://github.com/OrelSokolov/crystalize
|
83
125
|
licenses:
|
84
126
|
- MIT
|
@@ -98,8 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
140
|
- !ruby/object:Gem::Version
|
99
141
|
version: '0'
|
100
142
|
requirements: []
|
101
|
-
|
102
|
-
rubygems_version: 2.7.10
|
143
|
+
rubygems_version: 3.0.6
|
103
144
|
signing_key:
|
104
145
|
specification_version: 4
|
105
146
|
summary: Ruby to Crystal converter
|
data/lib/crystalize/converter.rb
DELETED