xrt 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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +85 -0
- data/Rakefile +8 -0
- data/bin/xrt +10 -0
- data/lib/xrt/cli.rb +22 -0
- data/lib/xrt/commands.rb +70 -0
- data/lib/xrt/depth_checker.rb +51 -0
- data/lib/xrt/parser.rb +79 -0
- data/lib/xrt/statement.rb +145 -0
- data/lib/xrt/syntax.rb +40 -0
- data/lib/xrt/version.rb +3 -0
- data/lib/xrt.rb +5 -0
- data/sketch/dump_blocks.rb +22 -0
- data/sketch/dump_max_depth.rb +16 -0
- data/sketch/dump_tree.rb +17 -0
- data/sketch/find_block.rb +24 -0
- data/sketch/replace_block.rb +31 -0
- data/test/run-test.rb +16 -0
- data/test/test-depth_checker.rb +25 -0
- data/test/test-parser.rb +89 -0
- data/test/test-statement.rb +157 -0
- data/test/test-syntax.rb +47 -0
- data/xrt.gemspec +24 -0
- metadata +118 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4f297398d1b9757376b533d456353e069ad6c852
|
4
|
+
data.tar.gz: a953d05e896c259e4c46fa2414cff70d66407969
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d0ed3a59d292aa21d82f91d7c6277a19793d0f0fd8f9c7c1c7008a557f7408628d7e6355b922d0e5ff2fb4cd4642039ee2032aa8ffd77e88e20ca99f17f738fa
|
7
|
+
data.tar.gz: 4a39005f378374d91efcda18bf016744873bb07778c5e1579b90f00e06516796e40b38a4484b9c71322c189653f0ae5d7dfce52dcc1710c0bdb0bc1cc9f80c52
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 hitode909
|
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,85 @@
|
|
1
|
+
[](https://travis-ci.org/hitode909/xrt)
|
2
|
+
|
3
|
+
# XRT
|
4
|
+
|
5
|
+
Refactoring Tool for [Text::Xslate](https://metacpan.org/pod/Text::Xslate).
|
6
|
+
Currently aim to refactor [Syntax::TTerse](https://metacpan.org/pod/Text::Xslate::Syntax::TTerse) templates.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
```
|
11
|
+
$ gem install xrt
|
12
|
+
```
|
13
|
+
|
14
|
+
## Commands
|
15
|
+
|
16
|
+
`XRT` provides `xrt` command.
|
17
|
+
|
18
|
+
### Dump
|
19
|
+
|
20
|
+
`xrt dump` command annotates the template with nested levels of control statements.
|
21
|
+
|
22
|
+
```
|
23
|
+
$ xrt dump TARGET_TEMPLATE
|
24
|
+
```
|
25
|
+
|
26
|
+
#### Example
|
27
|
+
|
28
|
+
`FOR` locates on nested level 1, and inner `IF` locates on nested level is 2.
|
29
|
+
Valid templates must end with nested level is 0.
|
30
|
+
|
31
|
+
```
|
32
|
+
% xrt dump templates/sample.html
|
33
|
+
Dumping templates/sample.html
|
34
|
+
<html>
|
35
|
+
<body>
|
36
|
+
0[% FOR item IN items %]1
|
37
|
+
1[% IF item.title %]2
|
38
|
+
<h1>2[% title %]2</h1>
|
39
|
+
2[% END %]1
|
40
|
+
1[% END %]0
|
41
|
+
</body>
|
42
|
+
</html>
|
43
|
+
0
|
44
|
+
```
|
45
|
+
|
46
|
+
### Extract
|
47
|
+
|
48
|
+
`xrt extract` extracts the specified block from target template to another new template.
|
49
|
+
|
50
|
+
```
|
51
|
+
$ xrt extract TARGET_TEMPLATE TARGET_BLOCK TEMPLATES_DIRECTORY NEW_TEMPLATE_NAME
|
52
|
+
```
|
53
|
+
|
54
|
+
#### Example
|
55
|
+
|
56
|
+
When you want to extract `FOR` block to new template `templates/_items.tt`,
|
57
|
+
|
58
|
+
- `TARGET_TEMPLATE` is the path of original template.
|
59
|
+
- Set `TARGET_BLOCK` like `[% FOR item IN items %]`, `[% FOR item IN` or `[% FOR`. This must match with a beginning of only one block.
|
60
|
+
- `TEMPLATES_DIRECTORY` is the directory which the template is located. Usually it may be `templates/` or `views/`.
|
61
|
+
- `NEW_TEMPLATE_NAME` is the new template. This parameter is used to generate new `[% INCLUDE %]` directive. New template will stored in `TEMPLATES_DIRECTORY`.
|
62
|
+
|
63
|
+
```
|
64
|
+
% xrt extract templates/sample.html '[% FOR item IN items %]' templates/ _items.tt
|
65
|
+
```
|
66
|
+
|
67
|
+
The result is below.
|
68
|
+
|
69
|
+
```
|
70
|
+
# tempaltes/sample.html
|
71
|
+
<html>
|
72
|
+
<body>
|
73
|
+
[% INCLUDE "_items.tt" %]
|
74
|
+
</body>
|
75
|
+
</html>
|
76
|
+
```
|
77
|
+
|
78
|
+
```
|
79
|
+
# templates/_items.tt
|
80
|
+
[% FOR item IN items %]
|
81
|
+
[% IF item.title %]
|
82
|
+
<h1>[% title %]</h1>
|
83
|
+
[% END %]
|
84
|
+
[% END %]
|
85
|
+
```
|
data/Rakefile
ADDED
data/bin/xrt
ADDED
data/lib/xrt/cli.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'xrt/commands'
|
2
|
+
|
3
|
+
module XRT
|
4
|
+
class CLI
|
5
|
+
def execute(args)
|
6
|
+
command_name = args.shift
|
7
|
+
|
8
|
+
case command_name
|
9
|
+
when 'dump'
|
10
|
+
success = XRT::Command::Dump.new.execute(args)
|
11
|
+
exit success ? 0 : 1
|
12
|
+
when 'extract'
|
13
|
+
success = XRT::Command::Extract.new.execute(*args)
|
14
|
+
exit success ? 0 : 1
|
15
|
+
else
|
16
|
+
warn "command not found"
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
data/lib/xrt/commands.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'xrt/depth_checker'
|
3
|
+
|
4
|
+
module XRT
|
5
|
+
module Command
|
6
|
+
class Dump
|
7
|
+
def execute(files)
|
8
|
+
files.each{|file|
|
9
|
+
dump_file file
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def dump_file target_file
|
14
|
+
warn "Dumping #{target_file}"
|
15
|
+
checker = XRT::DepthChecker.new
|
16
|
+
parsed, annotated_source = checker.check open(target_file).read
|
17
|
+
puts annotated_source
|
18
|
+
unless parsed
|
19
|
+
raise "Failed to parser #{target_file} (#{index}/#{target_files.length})"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Extract
|
25
|
+
# xrt extract templates/blogs/index.html '[% IF pager' 'templates/' 'blogs/_pager.tt'
|
26
|
+
def execute(from_file, target_block, templates_directory, to_file_name)
|
27
|
+
from_source = open(from_file).read
|
28
|
+
parser = XRT::Parser.new(from_source)
|
29
|
+
from_doc = parser.document
|
30
|
+
|
31
|
+
found_blocks = from_doc.find_blocks.select{|block|
|
32
|
+
block.content.index(target_block) == 0
|
33
|
+
}
|
34
|
+
|
35
|
+
if found_blocks.length == 0
|
36
|
+
raise "target_block not found"
|
37
|
+
end
|
38
|
+
|
39
|
+
if found_blocks.length > 1
|
40
|
+
raise "ambiguous target_block"
|
41
|
+
end
|
42
|
+
|
43
|
+
found_block = found_blocks.first
|
44
|
+
|
45
|
+
replace_to_node = XRT::Parser.new(%Q{[% INCLUDE "#{to_file_name}" %]}).document
|
46
|
+
|
47
|
+
from_doc.replace_child(replace_to_node, found_block)
|
48
|
+
|
49
|
+
content_to_overwrite = from_doc.content
|
50
|
+
content_for_new_file = found_block.auto_indent
|
51
|
+
|
52
|
+
open(from_file, 'w'){|f|
|
53
|
+
f.write content_to_overwrite
|
54
|
+
}
|
55
|
+
|
56
|
+
new_file = Pathname(templates_directory).join(to_file_name)
|
57
|
+
|
58
|
+
if new_file.exist?
|
59
|
+
raise 'TO_FILE_NAME exists.'
|
60
|
+
end
|
61
|
+
|
62
|
+
open(new_file, 'w'){|f|
|
63
|
+
f.puts content_for_new_file
|
64
|
+
}
|
65
|
+
|
66
|
+
true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'xrt/parser'
|
2
|
+
require 'xrt/syntax'
|
3
|
+
|
4
|
+
module XRT
|
5
|
+
class DepthChecker
|
6
|
+
def check source
|
7
|
+
annotated_source = ''
|
8
|
+
parser = XRT::Parser.new(source)
|
9
|
+
syntax = XRT::Syntax.new
|
10
|
+
|
11
|
+
current_level = 0
|
12
|
+
parser.tokens.each{|statement|
|
13
|
+
diff = syntax.block_level statement
|
14
|
+
current_level += diff
|
15
|
+
annotated_source += statement
|
16
|
+
|
17
|
+
color = 44 + diff
|
18
|
+
if STDOUT.tty?
|
19
|
+
annotated_source += "\e[#{color}m#{current_level}\e[0m"
|
20
|
+
else
|
21
|
+
annotated_source += current_level.to_s
|
22
|
+
end
|
23
|
+
}
|
24
|
+
if current_level == 0
|
25
|
+
return true, annotated_source
|
26
|
+
else
|
27
|
+
return false, annotated_source
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def max_depth source
|
32
|
+
parser = XRT::Parser.new(source)
|
33
|
+
syntax = XRT::Syntax.new
|
34
|
+
|
35
|
+
max_level = 0
|
36
|
+
current_level = 0
|
37
|
+
|
38
|
+
parser.tokens.each{|statement|
|
39
|
+
diff = syntax.block_level statement
|
40
|
+
current_level += diff
|
41
|
+
max_level = [ current_level, max_level].max
|
42
|
+
}
|
43
|
+
|
44
|
+
if current_level != 0
|
45
|
+
raise 'failed to parse'
|
46
|
+
end
|
47
|
+
|
48
|
+
max_level
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/xrt/parser.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'xrt/statement'
|
2
|
+
|
3
|
+
module XRT
|
4
|
+
class Parser
|
5
|
+
def initialize(source='')
|
6
|
+
@source = source
|
7
|
+
end
|
8
|
+
|
9
|
+
def document
|
10
|
+
doc = XRT::Statement::Document.new
|
11
|
+
|
12
|
+
tokenized = self.tokens
|
13
|
+
|
14
|
+
parse_contents(tokenized, doc)
|
15
|
+
doc
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_contents(tokenized, node)
|
19
|
+
while tokenized.length > 0
|
20
|
+
statement = XRT::Statement::Factory.new_from_content(tokenized.shift)
|
21
|
+
case statement
|
22
|
+
when XRT::Statement::Block
|
23
|
+
parse_contents(tokenized, statement)
|
24
|
+
node << statement
|
25
|
+
when XRT::Statement::End
|
26
|
+
node << statement
|
27
|
+
break
|
28
|
+
when XRT::Statement::Text
|
29
|
+
node << statement
|
30
|
+
when XRT::Statement::Directive
|
31
|
+
node << statement
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
node
|
36
|
+
end
|
37
|
+
|
38
|
+
def tokens
|
39
|
+
reading = @source.dup
|
40
|
+
result = []
|
41
|
+
|
42
|
+
while reading.length > 0
|
43
|
+
got = read_directive(reading) || read_text(reading)
|
44
|
+
unless got
|
45
|
+
raise "failed to parse #{@source}"
|
46
|
+
end
|
47
|
+
result << got
|
48
|
+
end
|
49
|
+
|
50
|
+
result
|
51
|
+
end
|
52
|
+
|
53
|
+
def read_directive source
|
54
|
+
return nil unless source[0...2] == '[%'
|
55
|
+
|
56
|
+
buffer = ''
|
57
|
+
while source[0...2] != '%]'
|
58
|
+
buffer << source.slice!(0)
|
59
|
+
end
|
60
|
+
buffer << source.slice!(0, 2)
|
61
|
+
buffer
|
62
|
+
end
|
63
|
+
|
64
|
+
def read_text source
|
65
|
+
return nil if source[0...2] == '[%'
|
66
|
+
|
67
|
+
buffer = ''
|
68
|
+
while true
|
69
|
+
return buffer if source[0...2] == '[%'
|
70
|
+
break if source.length < 2
|
71
|
+
buffer << source.slice!(0)
|
72
|
+
end
|
73
|
+
|
74
|
+
buffer << source.slice!(0, source.length)
|
75
|
+
|
76
|
+
buffer
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'xrt/syntax'
|
2
|
+
|
3
|
+
module XRT
|
4
|
+
class Statement
|
5
|
+
def initialize(content)
|
6
|
+
@content = content
|
7
|
+
end
|
8
|
+
|
9
|
+
def content
|
10
|
+
@content
|
11
|
+
end
|
12
|
+
|
13
|
+
def == other
|
14
|
+
self.class == other.class && self.content == other.content
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect
|
18
|
+
"<#{self.class}:#{self.content}>"
|
19
|
+
end
|
20
|
+
|
21
|
+
def children
|
22
|
+
[]
|
23
|
+
end
|
24
|
+
|
25
|
+
def replace_child(new_child, old_child)
|
26
|
+
children.each_with_index{|child, index|
|
27
|
+
if child.equal? old_child
|
28
|
+
children[index] = new_child
|
29
|
+
return old_child
|
30
|
+
elsif child.replace_child(new_child, old_child)
|
31
|
+
return old_child
|
32
|
+
end
|
33
|
+
}
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def depth(target)
|
38
|
+
children.each{|child|
|
39
|
+
return 0 if child.equal? target
|
40
|
+
d = child.depth(target)
|
41
|
+
if d
|
42
|
+
return d + 1
|
43
|
+
end
|
44
|
+
}
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_blocks
|
49
|
+
children.select{|child|
|
50
|
+
child.kind_of? XRT::Statement::Block
|
51
|
+
}.concat(children.map{|child| child.find_blocks }.flatten)
|
52
|
+
end
|
53
|
+
|
54
|
+
def auto_indent
|
55
|
+
lines = content.split(/\n/)[1..-1]
|
56
|
+
whitespaces = lines.map{|line| line.scan(/^\s+/).first }.compact
|
57
|
+
indent = whitespaces.sort_by{|whitespace| whitespace.length }.first
|
58
|
+
content.gsub(/^#{indent}/, '')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Statement
|
63
|
+
module Factory
|
64
|
+
def self.new_from_content content
|
65
|
+
syntax = XRT::Syntax.new
|
66
|
+
|
67
|
+
block_level = syntax.block_level content
|
68
|
+
|
69
|
+
if block_level == 1
|
70
|
+
XRT::Statement::Block.new content
|
71
|
+
elsif block_level == -1
|
72
|
+
XRT::Statement::End.new content
|
73
|
+
elsif syntax.block? content
|
74
|
+
XRT::Statement::Directive.new content
|
75
|
+
else
|
76
|
+
XRT::Statement::Text.new content
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
class Document < Statement
|
83
|
+
def initialize
|
84
|
+
@children = []
|
85
|
+
end
|
86
|
+
|
87
|
+
def << statement
|
88
|
+
@children << statement
|
89
|
+
end
|
90
|
+
|
91
|
+
def children
|
92
|
+
@children
|
93
|
+
end
|
94
|
+
|
95
|
+
def content
|
96
|
+
children.map{|c| c.content }.join
|
97
|
+
end
|
98
|
+
|
99
|
+
def == other
|
100
|
+
self.content == other.content && self.children.zip(other.children).all{|a, b| p [a, b]; a == b }
|
101
|
+
end
|
102
|
+
|
103
|
+
def inspect
|
104
|
+
"<#{self.class}:#{self.children}>"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class Text < Statement
|
109
|
+
end
|
110
|
+
|
111
|
+
class Directive < Statement
|
112
|
+
end
|
113
|
+
|
114
|
+
class End < Directive
|
115
|
+
end
|
116
|
+
|
117
|
+
class Block < Directive
|
118
|
+
def initialize(content)
|
119
|
+
super
|
120
|
+
@children = []
|
121
|
+
end
|
122
|
+
|
123
|
+
def closed?
|
124
|
+
children.last.kind_of? End
|
125
|
+
end
|
126
|
+
|
127
|
+
def << statement
|
128
|
+
raise 'trying to push_child to closed block' if closed?
|
129
|
+
@children << statement
|
130
|
+
end
|
131
|
+
|
132
|
+
def children
|
133
|
+
@children
|
134
|
+
end
|
135
|
+
|
136
|
+
def content
|
137
|
+
@content + children.map{|c| c.content }.join
|
138
|
+
end
|
139
|
+
|
140
|
+
def inspect
|
141
|
+
"<#{self.class}:#{@content},#{self.children}>"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
data/lib/xrt/syntax.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module XRT
|
2
|
+
class Syntax
|
3
|
+
def block? statement
|
4
|
+
statement =~ /\A\[%.+%\]\Z/m
|
5
|
+
end
|
6
|
+
|
7
|
+
def beginning_block? statement
|
8
|
+
without_comment = remove_comment statement
|
9
|
+
without_comment =~ beginning_block_regexp
|
10
|
+
end
|
11
|
+
|
12
|
+
def end_block? statement
|
13
|
+
return unless block? statement
|
14
|
+
without_comment = remove_comment statement
|
15
|
+
without_comment =~ end_block_regexp
|
16
|
+
end
|
17
|
+
|
18
|
+
def beginning_block_regexp
|
19
|
+
keywords = %w(IF UNLESS FOR FOREACH WHILE SWITCH MACRO BLOCK WRAPPER FILTER)
|
20
|
+
/\[%.?\s*\b(#{keywords.join('|')})\b/i
|
21
|
+
end
|
22
|
+
|
23
|
+
def end_block_regexp
|
24
|
+
/\bEND\b/i
|
25
|
+
end
|
26
|
+
|
27
|
+
def remove_comment(statement)
|
28
|
+
statement.gsub(/\s*#.*$/, '')
|
29
|
+
end
|
30
|
+
|
31
|
+
def block_level(statement)
|
32
|
+
stripped = statement.strip
|
33
|
+
return 0 unless block? stripped
|
34
|
+
level = 0
|
35
|
+
level += 1 if beginning_block? stripped
|
36
|
+
level -= 1 if end_block? stripped
|
37
|
+
level
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/xrt/version.rb
ADDED
data/lib/xrt.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
base_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
2
|
+
lib_dir = File.join(base_dir, "lib")
|
3
|
+
$LOAD_PATH.unshift(lib_dir)
|
4
|
+
|
5
|
+
require 'xrt/parser'
|
6
|
+
require 'pp'
|
7
|
+
|
8
|
+
target_files = ARGV
|
9
|
+
|
10
|
+
target_files.each_with_index{|target_file, index|
|
11
|
+
warn "Dumping #{target_file}"
|
12
|
+
source = open(target_file).read
|
13
|
+
parser = XRT::Parser.new(source)
|
14
|
+
doc = parser.document
|
15
|
+
doc.find_blocks.each{|block|
|
16
|
+
p "depth: #{doc.depth(block)}"
|
17
|
+
|
18
|
+
puts block.content
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
exit 0
|
@@ -0,0 +1,16 @@
|
|
1
|
+
base_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
2
|
+
lib_dir = File.join(base_dir, "lib")
|
3
|
+
$LOAD_PATH.unshift(lib_dir)
|
4
|
+
|
5
|
+
require 'xrt/depth_checker'
|
6
|
+
|
7
|
+
target_files = ARGV
|
8
|
+
|
9
|
+
checker = XRT::DepthChecker.new
|
10
|
+
|
11
|
+
target_files.each{|target_file|
|
12
|
+
level = checker.max_depth open(target_file).read
|
13
|
+
puts [level, target_file].join("\t")
|
14
|
+
}
|
15
|
+
|
16
|
+
exit 0
|
data/sketch/dump_tree.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
base_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
2
|
+
lib_dir = File.join(base_dir, "lib")
|
3
|
+
$LOAD_PATH.unshift(lib_dir)
|
4
|
+
|
5
|
+
require 'xrt/parser'
|
6
|
+
require 'pp'
|
7
|
+
|
8
|
+
target_files = ARGV
|
9
|
+
|
10
|
+
target_files.each_with_index{|target_file, index|
|
11
|
+
warn "Dumping #{target_file}"
|
12
|
+
source = open(target_file).read
|
13
|
+
parser = XRT::Parser.new(source)
|
14
|
+
pp parser.document
|
15
|
+
}
|
16
|
+
|
17
|
+
exit 0
|
@@ -0,0 +1,24 @@
|
|
1
|
+
base_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
2
|
+
lib_dir = File.join(base_dir, "lib")
|
3
|
+
$LOAD_PATH.unshift(lib_dir)
|
4
|
+
|
5
|
+
require 'xrt/parser'
|
6
|
+
|
7
|
+
target_file, target_block = *ARGV
|
8
|
+
|
9
|
+
warn "target_file: #{target_file}"
|
10
|
+
warn "target_block: #{target_block}"
|
11
|
+
|
12
|
+
source = open(target_file).read
|
13
|
+
parser = XRT::Parser.new(source)
|
14
|
+
doc = parser.document
|
15
|
+
found = doc.find_blocks.select{|block|
|
16
|
+
block.content.index(target_block) == 0
|
17
|
+
}.first
|
18
|
+
|
19
|
+
if found
|
20
|
+
puts found.auto_indent
|
21
|
+
else
|
22
|
+
warn 'not found'
|
23
|
+
exit 1
|
24
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
base_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
2
|
+
lib_dir = File.join(base_dir, "lib")
|
3
|
+
$LOAD_PATH.unshift(lib_dir)
|
4
|
+
|
5
|
+
require 'xrt/parser'
|
6
|
+
|
7
|
+
target_file, target_block, replace_to = *ARGV
|
8
|
+
|
9
|
+
warn "target_file: #{target_file}"
|
10
|
+
warn "target_block: #{target_block}"
|
11
|
+
warn "replace_to: #{replace_to}"
|
12
|
+
|
13
|
+
source = open(target_file).read
|
14
|
+
parser = XRT::Parser.new(source)
|
15
|
+
doc = parser.document
|
16
|
+
found = doc.find_blocks.select{|block|
|
17
|
+
block.content.index(target_block) == 0
|
18
|
+
}.first
|
19
|
+
|
20
|
+
if found
|
21
|
+
puts found.content
|
22
|
+
else
|
23
|
+
warn 'not found'
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
|
27
|
+
replace_to_node = XRT::Parser.new(replace_to).document
|
28
|
+
|
29
|
+
doc.replace_child(replace_to_node, found)
|
30
|
+
|
31
|
+
puts doc.content
|
data/test/run-test.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$VERBOSE = true
|
4
|
+
|
5
|
+
base_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
6
|
+
lib_dir = File.join(base_dir, "lib")
|
7
|
+
test_dir = File.join(base_dir, "test")
|
8
|
+
|
9
|
+
require "test-unit"
|
10
|
+
|
11
|
+
$LOAD_PATH.unshift(lib_dir)
|
12
|
+
$LOAD_PATH.unshift(test_dir)
|
13
|
+
|
14
|
+
ENV["TEST_UNIT_MAX_DIFF_TARGET_STRING_SIZE"] ||= "5000"
|
15
|
+
|
16
|
+
exit Test::Unit::AutoRunner.run(true, test_dir)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'xrt/depth_checker'
|
3
|
+
|
4
|
+
class TestDepthChecker < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@checker = XRT::DepthChecker.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_check
|
10
|
+
assert_equal true, @checker.check(%q{[% IF a %]1[% END %]})[0]
|
11
|
+
assert_equal true, @checker.check(%q{hi})[0]
|
12
|
+
assert_equal false, @checker.check(%q{[% IF a %]})[0]
|
13
|
+
|
14
|
+
assert_equal true, @checker.check(%q{[% IF a %]1[% END %]})[1].kind_of?(String)
|
15
|
+
assert_equal true, @checker.check(%q{[% IF a %]})[1].kind_of?(String)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_max_depth
|
19
|
+
assert_equal 0, @checker.max_depth(%q{foo})
|
20
|
+
assert_equal 0, @checker.max_depth(%q{[% foo %]})
|
21
|
+
assert_equal 1, @checker.max_depth(%q{[% IF a %]1[% END %]})
|
22
|
+
|
23
|
+
assert_raises { @checker.max_depth(%q{[% IF a %]}) }
|
24
|
+
end
|
25
|
+
end
|
data/test/test-parser.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'xrt/parser'
|
3
|
+
|
4
|
+
class TestParser < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@parser = XRT::Parser.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_document_empty
|
10
|
+
parser = XRT::Parser.new('')
|
11
|
+
doc = parser.document
|
12
|
+
assert doc.kind_of? XRT::Statement::Document
|
13
|
+
assert_equal [], doc.children
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_document_text_directive
|
17
|
+
parser = XRT::Parser.new('1[% 2 %]3')
|
18
|
+
doc = parser.document
|
19
|
+
assert doc.kind_of? XRT::Statement::Document
|
20
|
+
assert_equal [
|
21
|
+
XRT::Statement::Text.new('1'),
|
22
|
+
XRT::Statement::Directive.new('[% 2 %]'),
|
23
|
+
XRT::Statement::Text.new('3'),
|
24
|
+
], doc.children
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_document_block
|
28
|
+
parser = XRT::Parser.new('[% IF a %]1[% END %]')
|
29
|
+
doc = parser.document
|
30
|
+
assert doc.kind_of? XRT::Statement::Document
|
31
|
+
if_block = XRT::Statement::Block.new('[% IF a %]')
|
32
|
+
if_block << XRT::Statement::Text.new('1')
|
33
|
+
if_block << XRT::Statement::Text.new('[% END %]')
|
34
|
+
assert_equal [
|
35
|
+
if_block
|
36
|
+
], doc.children
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_document_nested_block
|
40
|
+
parser = XRT::Parser.new('[% IF a %][% IF b %]1[% END %][% END %]')
|
41
|
+
doc = parser.document
|
42
|
+
assert doc.kind_of? XRT::Statement::Document
|
43
|
+
if_block1 = XRT::Statement::Block.new('[% IF a %]')
|
44
|
+
if_block2 = XRT::Statement::Block.new('[% IF b %]')
|
45
|
+
if_block2 << XRT::Statement::Text.new('1')
|
46
|
+
if_block2 << XRT::Statement::Text.new('[% END %]')
|
47
|
+
if_block1 << if_block2
|
48
|
+
if_block1 << XRT::Statement::Text.new('[% END %]')
|
49
|
+
assert_equal [
|
50
|
+
if_block1
|
51
|
+
], doc.children
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_read_directive
|
55
|
+
assert_equal '[% %]', @parser.read_directive('[% %]')
|
56
|
+
assert_equal '[% [ ] %]', @parser.read_directive('[% [ ] %]')
|
57
|
+
assert_nil @parser.read_directive('hi')
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_read_text
|
61
|
+
assert_equal 'hi', @parser.read_text('hi')
|
62
|
+
assert_equal 'hi[', @parser.read_text('hi[')
|
63
|
+
assert_equal 'hi', @parser.read_text('hi[%')
|
64
|
+
assert_nil @parser.read_text('[% %]')
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_tokens
|
68
|
+
test_cases = [
|
69
|
+
['<html>', ['<html>']],
|
70
|
+
['a [% b %] c', ['a ', '[% b %]', ' c']],
|
71
|
+
['[% a %] [% b %] [% c %]', ['[% a %]', ' ', '[% b %]', ' ', '[% c %]']],
|
72
|
+
['[% FOR k IN [1, 2, 3] %]', ['[% FOR k IN [1, 2, 3] %]']],
|
73
|
+
[
|
74
|
+
%q([% WRAPPER "wrapper.tt" WITH args = [1,2,3] %]<div></div>[% END %]),
|
75
|
+
[
|
76
|
+
%q([% WRAPPER "wrapper.tt" WITH args = [1,2,3] %]),
|
77
|
+
%q(<div></div>),
|
78
|
+
%q([% END %]),
|
79
|
+
]
|
80
|
+
],
|
81
|
+
]
|
82
|
+
|
83
|
+
test_cases.each{|test_case|
|
84
|
+
input, expected = *test_case
|
85
|
+
parser = XRT::Parser.new(input)
|
86
|
+
assert_equal expected, parser.tokens
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'xrt/statement'
|
3
|
+
|
4
|
+
class TestStatementFactory < Test::Unit::TestCase
|
5
|
+
def test_new_from_string
|
6
|
+
assert XRT::Statement::Factory.new_from_content('hi').kind_of? XRT::Statement::Text
|
7
|
+
assert XRT::Statement::Factory.new_from_content('[% foo %]').kind_of? XRT::Statement::Directive
|
8
|
+
assert XRT::Statement::Factory.new_from_content('[% IF 1 %]').kind_of? XRT::Statement::Block
|
9
|
+
assert XRT::Statement::Factory.new_from_content('[% foo IF 1 %]').kind_of? XRT::Statement::Directive
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class TestStatement < Test::Unit::TestCase
|
14
|
+
def test_text
|
15
|
+
text = XRT::Statement::Text.new('hi')
|
16
|
+
assert text.kind_of? XRT::Statement
|
17
|
+
assert_equal text.content, 'hi'
|
18
|
+
assert_equal text.children, []
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_text_auto_indent
|
22
|
+
text = XRT::Statement::Text.new(<<'HTML')
|
23
|
+
<html>
|
24
|
+
<body>
|
25
|
+
|
26
|
+
</body>
|
27
|
+
</html>
|
28
|
+
HTML
|
29
|
+
|
30
|
+
assert_equal text.auto_indent, <<'HTML'
|
31
|
+
<html>
|
32
|
+
<body>
|
33
|
+
|
34
|
+
</body>
|
35
|
+
</html>
|
36
|
+
HTML
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_directive
|
40
|
+
text = XRT::Statement::End.new('[% foo() %]')
|
41
|
+
assert text.kind_of? XRT::Statement
|
42
|
+
assert_equal text.content, '[% foo() %]'
|
43
|
+
assert_equal text.children, []
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_end
|
47
|
+
text = XRT::Statement::End.new('[% END %]')
|
48
|
+
assert text.kind_of? XRT::Statement
|
49
|
+
assert_equal text.content, '[% END %]'
|
50
|
+
assert_equal text.children, []
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_block
|
54
|
+
text = XRT::Statement::Block.new('[% IF 1 %]')
|
55
|
+
assert text.kind_of? XRT::Statement
|
56
|
+
assert_equal text.content, '[% IF 1 %]'
|
57
|
+
assert_equal text.children, []
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_document
|
61
|
+
document = XRT::Statement::Document.new
|
62
|
+
s1 = XRT::Statement::Text.new('ok')
|
63
|
+
s2 = XRT::Statement::Directive.new('[% foo %]')
|
64
|
+
document << s1
|
65
|
+
document << s2
|
66
|
+
|
67
|
+
assert_equal document.children, [s1, s2]
|
68
|
+
|
69
|
+
assert_equal document.content, %q{ok[% foo %]}
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_replace_child
|
73
|
+
document = XRT::Statement::Document.new
|
74
|
+
s1 = XRT::Statement::Text.new('1')
|
75
|
+
s2 = XRT::Statement::Text.new('2')
|
76
|
+
s3 = XRT::Statement::Text.new('3')
|
77
|
+
document << s1
|
78
|
+
|
79
|
+
assert_nil document.replace_child(s2, s3),'when not found'
|
80
|
+
assert_equal '1', document.content, 'not changed'
|
81
|
+
|
82
|
+
replaced = document.replace_child(s2, s1)
|
83
|
+
assert_same replaced, s1
|
84
|
+
assert_equal '2', document.content, 'replaced'
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_replace_child_for_descendant
|
88
|
+
document = XRT::Statement::Document.new
|
89
|
+
if_block = XRT::Statement::Block.new('[% IF a %]')
|
90
|
+
if_block_inner_text = XRT::Statement::Text.new('1')
|
91
|
+
new_if_block_inner_text = XRT::Statement::Text.new('2')
|
92
|
+
if_block << if_block_inner_text
|
93
|
+
if_block << XRT::Statement::Text.new('[% END %]')
|
94
|
+
document << if_block
|
95
|
+
|
96
|
+
assert document.replace_child(new_if_block_inner_text, if_block_inner_text)
|
97
|
+
assert_equal '[% IF a %]2[% END %]', document.content
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_depth
|
101
|
+
document = XRT::Statement::Document.new
|
102
|
+
s1 = XRT::Statement::Text.new('1')
|
103
|
+
if_block = XRT::Statement::Block.new('[% IF a %]')
|
104
|
+
if_block_inner_text = XRT::Statement::Text.new('1')
|
105
|
+
if_block << if_block_inner_text
|
106
|
+
if_block << XRT::Statement::Text.new('[% END %]')
|
107
|
+
not_child = XRT::Statement::Text.new('not_child')
|
108
|
+
document << s1
|
109
|
+
document << if_block
|
110
|
+
|
111
|
+
assert_equal 0, document.depth(s1)
|
112
|
+
assert_equal 0, document.depth(if_block)
|
113
|
+
assert_equal 1, document.depth(if_block_inner_text)
|
114
|
+
assert_equal nil, document.depth(not_child)
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_find_blocks
|
118
|
+
document = XRT::Statement::Document.new
|
119
|
+
assert_equal [], document.find_blocks, 'when there is no block'
|
120
|
+
|
121
|
+
document << XRT::Statement::Text.new('1')
|
122
|
+
if_block = XRT::Statement::Block.new('[% IF a %]')
|
123
|
+
document << if_block
|
124
|
+
|
125
|
+
assert_equal [ if_block ], document.find_blocks, 'returns block'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
class TestBlock < Test::Unit::TestCase
|
130
|
+
def test_push_child
|
131
|
+
block = XRT::Statement::Block.new('[% IF 1 %]')
|
132
|
+
assert_equal false, block.closed?
|
133
|
+
|
134
|
+
statement_ok = XRT::Statement::Text.new('ok')
|
135
|
+
statement_end = XRT::Statement::End.new('[% END %]')
|
136
|
+
|
137
|
+
block << statement_ok
|
138
|
+
assert_equal false, block.closed?
|
139
|
+
|
140
|
+
block << statement_end
|
141
|
+
assert_equal true, block.closed?
|
142
|
+
|
143
|
+
assert_equal block.children, [statement_ok, statement_end]
|
144
|
+
|
145
|
+
assert_raises {
|
146
|
+
block << statement_ok
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_content
|
151
|
+
block = XRT::Statement::Block.new('[% IF 1 %]')
|
152
|
+
block << XRT::Statement::Text.new('ok')
|
153
|
+
block << XRT::Statement::End.new('[% END %]')
|
154
|
+
|
155
|
+
assert_equal block.content, %q{[% IF 1 %]ok[% END %]}
|
156
|
+
end
|
157
|
+
end
|
data/test/test-syntax.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'xrt/syntax'
|
3
|
+
|
4
|
+
class TestSyntax < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@syntax = XRT::Syntax.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_remove_comment
|
10
|
+
assert_equal 'foo', @syntax.remove_comment('foo # bar')
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_beginning_block?
|
14
|
+
assert @syntax.beginning_block? '[% IF 1 %]'
|
15
|
+
assert @syntax.beginning_block? '[% if 1 %]'
|
16
|
+
assert @syntax.beginning_block? '[% WHILE 1 %]'
|
17
|
+
assert_nil @syntax.beginning_block? '[% END # WRAPPER "wrapper.tt" WITH %]'
|
18
|
+
assert_nil @syntax.beginning_block? '[% "true" UNLESS false %]'
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_block?
|
22
|
+
assert @syntax.beginning_block? '[% IF 1 %]'
|
23
|
+
assert @syntax.beginning_block? '[%- IF 1 -%]'
|
24
|
+
assert @syntax.beginning_block? "[% IF 1\nfoo\nEND %]"
|
25
|
+
assert_nil @syntax.beginning_block? "hi"
|
26
|
+
assert_nil @syntax.beginning_block? "[%"
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_end_block?
|
30
|
+
assert @syntax.end_block? '[% END %]'
|
31
|
+
assert @syntax.end_block? '[% end %]'
|
32
|
+
assert @syntax.end_block? '[% END # WRAPPER "wrapper.tt" WITH %]'
|
33
|
+
assert_nil @syntax.end_block? ' END '
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_block_level
|
37
|
+
assert_equal(0, @syntax.block_level('[% foo %]'))
|
38
|
+
assert_equal(1, @syntax.block_level('[% IF 1 %]'))
|
39
|
+
assert_equal(1, @syntax.block_level('[%- IF 1 -%]'))
|
40
|
+
assert_equal(0, @syntax.block_level('[% IF a THEN 1 END %]'))
|
41
|
+
assert_equal(0, @syntax.block_level('[% IF a THEN 1 ELSE 0 END %]'))
|
42
|
+
assert_equal(0, @syntax.block_level('[% a ? 1 : 0 %]'))
|
43
|
+
assert_equal(-1, @syntax.block_level('[% END # WRAPPER "wrapper.tt" WITH %]'))
|
44
|
+
assert_equal(0, @syntax.block_level('[% 2 UNLESS a %]'))
|
45
|
+
assert_equal(0, @syntax.block_level('[% 1 IF a %]'))
|
46
|
+
end
|
47
|
+
end
|
data/xrt.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'xrt/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "xrt"
|
8
|
+
spec.version = Xrt::VERSION
|
9
|
+
spec.authors = ["hitode909"]
|
10
|
+
spec.email = ["hitode909@gmail.com"]
|
11
|
+
spec.summary = %q{Refactoring Tool for Text::Xslate}
|
12
|
+
spec.homepage = 'https://github.com/hitode909/xrt'
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
21
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
22
|
+
|
23
|
+
spec.add_development_dependency("test-unit")
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xrt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- hitode909
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-11-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: test-unit
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- hitode909@gmail.com
|
58
|
+
executables:
|
59
|
+
- xrt
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- ".travis.yml"
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- bin/xrt
|
70
|
+
- lib/xrt.rb
|
71
|
+
- lib/xrt/cli.rb
|
72
|
+
- lib/xrt/commands.rb
|
73
|
+
- lib/xrt/depth_checker.rb
|
74
|
+
- lib/xrt/parser.rb
|
75
|
+
- lib/xrt/statement.rb
|
76
|
+
- lib/xrt/syntax.rb
|
77
|
+
- lib/xrt/version.rb
|
78
|
+
- sketch/dump_blocks.rb
|
79
|
+
- sketch/dump_max_depth.rb
|
80
|
+
- sketch/dump_tree.rb
|
81
|
+
- sketch/find_block.rb
|
82
|
+
- sketch/replace_block.rb
|
83
|
+
- test/run-test.rb
|
84
|
+
- test/test-depth_checker.rb
|
85
|
+
- test/test-parser.rb
|
86
|
+
- test/test-statement.rb
|
87
|
+
- test/test-syntax.rb
|
88
|
+
- xrt.gemspec
|
89
|
+
homepage: https://github.com/hitode909/xrt
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.4.5.1
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: Refactoring Tool for Text::Xslate
|
113
|
+
test_files:
|
114
|
+
- test/run-test.rb
|
115
|
+
- test/test-depth_checker.rb
|
116
|
+
- test/test-parser.rb
|
117
|
+
- test/test-statement.rb
|
118
|
+
- test/test-syntax.rb
|