social_snippet 0.0.7 → 0.0.8
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 +8 -8
- data/.travis.yml +1 -2
- data/Rakefile +12 -0
- data/lib/social_snippet/api.rb +4 -4
- data/lib/social_snippet/api/completion_api.rb +1 -1
- data/lib/social_snippet/api/config_api.rb +3 -3
- data/lib/social_snippet/api/insert_snippet_api.rb +1 -1
- data/lib/social_snippet/api/install_repository_api.rb +5 -5
- data/lib/social_snippet/api/manifest_api.rb +5 -5
- data/lib/social_snippet/api/registry_api.rb +1 -1
- data/lib/social_snippet/api/search_api.rb +2 -2
- data/lib/social_snippet/api/show_api.rb +1 -1
- data/lib/social_snippet/api/update_repository_api.rb +9 -9
- data/lib/social_snippet/command_line/command.rb +2 -2
- data/lib/social_snippet/command_line/ssnip/main_command.rb +1 -1
- data/lib/social_snippet/command_line/sspm/sub_commands/complete_command.rb +1 -1
- data/lib/social_snippet/command_line/sspm/sub_commands/config_command.rb +3 -3
- data/lib/social_snippet/command_line/sspm/sub_commands/info_command.rb +1 -1
- data/lib/social_snippet/command_line/sspm/sub_commands/init_command.rb +1 -1
- data/lib/social_snippet/command_line/sspm/sub_commands/install_command.rb +4 -4
- data/lib/social_snippet/command_line/sspm/sub_commands/publish_command.rb +2 -2
- data/lib/social_snippet/command_line/sspm/sub_commands/search_command.rb +1 -1
- data/lib/social_snippet/command_line/sspm/sub_commands/update_command.rb +2 -2
- data/lib/social_snippet/config.rb +3 -3
- data/lib/social_snippet/context.rb +32 -11
- data/lib/social_snippet/registry/registry_client.rb +4 -4
- data/lib/social_snippet/registry/registry_resources/base.rb +13 -13
- data/lib/social_snippet/repository/repository_installer.rb +6 -6
- data/lib/social_snippet/repository/repository_manager.rb +11 -12
- data/lib/social_snippet/resolvers/base_resolver.rb +25 -11
- data/lib/social_snippet/resolvers/dep_resolver.rb +4 -4
- data/lib/social_snippet/resolvers/insert_resolver.rb +14 -13
- data/lib/social_snippet/snippet.rb +76 -55
- data/lib/social_snippet/tag.rb +28 -7
- data/lib/social_snippet/tag_parser.rb +47 -38
- data/lib/social_snippet/version.rb +1 -1
- data/spec/lib/api_spec.rb +4 -4
- data/spec/lib/command_line/sspm_config_spec.rb +3 -3
- data/spec/lib/command_line/sspm_init_spec.rb +1 -1
- data/spec/lib/command_line/sspm_install_spec.rb +5 -5
- data/spec/lib/command_line/sspm_search_spec.rb +1 -1
- data/spec/lib/context_spec.rb +29 -22
- data/spec/lib/core_spec.rb +12 -12
- data/spec/lib/insert_resolver_spec.rb +7 -7
- data/spec/lib/repository/repository_manager_spec.rb +1 -0
- data/spec/spec_helper.rb +15 -15
- data/test/core_test.rb +1062 -428
- metadata +2 -2
@@ -1,7 +1,10 @@
|
|
1
1
|
class SocialSnippet::Context
|
2
2
|
|
3
|
+
require "pathname"
|
4
|
+
|
3
5
|
attr_reader :flag_absolute
|
4
6
|
attr_reader :path
|
7
|
+
attr_reader :pathname
|
5
8
|
attr_reader :repo
|
6
9
|
attr_reader :ref
|
7
10
|
|
@@ -9,12 +12,18 @@ class SocialSnippet::Context
|
|
9
12
|
#
|
10
13
|
# @param new_path [String] The path of context
|
11
14
|
def initialize(new_path, new_repo = nil, new_ref = nil)
|
12
|
-
|
13
|
-
@path = new_path
|
15
|
+
set_path new_path
|
14
16
|
@repo = new_repo
|
15
17
|
@ref = new_ref
|
16
18
|
end
|
17
19
|
|
20
|
+
def set_path(new_path)
|
21
|
+
return if new_path.nil?
|
22
|
+
@path = new_path
|
23
|
+
@pathname = ::Pathname.new(path)
|
24
|
+
@flag_absolute = is_absolute_path(path)
|
25
|
+
end
|
26
|
+
|
18
27
|
# Check context in repo
|
19
28
|
#
|
20
29
|
# @return [Boolean]
|
@@ -31,25 +40,36 @@ class SocialSnippet::Context
|
|
31
40
|
if new_repo.nil?
|
32
41
|
if is_absolute_path(new_path)
|
33
42
|
@flag_absolute = true
|
34
|
-
|
43
|
+
set_path new_path
|
35
44
|
else
|
36
|
-
|
45
|
+
set_path move_path(new_path)
|
37
46
|
end
|
38
47
|
else
|
39
48
|
@flag_absolute = false
|
40
|
-
|
49
|
+
set_path new_path
|
41
50
|
@repo = new_repo
|
42
51
|
@ref = new_ref
|
43
52
|
end
|
44
53
|
end
|
45
54
|
|
55
|
+
def basename
|
56
|
+
pathname.basename.to_s unless path.nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
def dirname
|
60
|
+
pathname.dirname.to_s unless path.nil?
|
61
|
+
end
|
62
|
+
|
63
|
+
def root_text?
|
64
|
+
path.nil?
|
65
|
+
end
|
66
|
+
|
46
67
|
private
|
47
68
|
|
48
|
-
def
|
49
|
-
source =
|
50
|
-
source_file = source.pop
|
69
|
+
def move_path(new_path)
|
70
|
+
source = dirname.split("/")
|
51
71
|
dest = new_path.split("/")
|
52
|
-
|
72
|
+
destname = dest.pop
|
53
73
|
|
54
74
|
if is_absolute_path(path)
|
55
75
|
source.shift
|
@@ -64,13 +84,14 @@ class SocialSnippet::Context
|
|
64
84
|
end
|
65
85
|
|
66
86
|
if flag_absolute
|
67
|
-
"/" + source.join("/") + "/" +
|
87
|
+
"/" + source.join("/") + "/" + destname
|
68
88
|
else
|
69
|
-
source.join("/") + "/" +
|
89
|
+
source.join("/") + "/" + destname
|
70
90
|
end
|
71
91
|
end
|
72
92
|
|
73
93
|
private
|
94
|
+
|
74
95
|
# Check given text is absolute path
|
75
96
|
def is_absolute_path(s)
|
76
97
|
s[0] === "/"
|
@@ -2,12 +2,12 @@ module SocialSnippet::Registry
|
|
2
2
|
|
3
3
|
class RegistryClient
|
4
4
|
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :core
|
6
6
|
attr_reader :repositories
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@
|
10
|
-
@repositories = RegistryResources::Repositories.new(
|
8
|
+
def initialize(new_core)
|
9
|
+
@core = new_core
|
10
|
+
@repositories = RegistryResources::Repositories.new(core)
|
11
11
|
end
|
12
12
|
|
13
13
|
end
|
@@ -5,27 +5,27 @@ module SocialSnippet::Registry::RegistryResources
|
|
5
5
|
|
6
6
|
class Base
|
7
7
|
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :core
|
9
9
|
attr_reader :rest_client
|
10
10
|
attr_reader :end_point
|
11
11
|
attr_reader :cookies
|
12
12
|
attr_reader :default_headers
|
13
13
|
|
14
|
-
def initialize(
|
15
|
-
@
|
16
|
-
@end_point =
|
14
|
+
def initialize(new_core)
|
15
|
+
@core = new_core
|
16
|
+
@end_point = core.config.sspm_url
|
17
17
|
@rest_client = ::RestClient::Resource.new(end_point)
|
18
18
|
@cookies = {}
|
19
19
|
@default_headers = {
|
20
20
|
:accept => :json,
|
21
21
|
}
|
22
22
|
|
23
|
-
|
23
|
+
core.logger.debug "registry: end-point = #{end_point}"
|
24
24
|
end
|
25
25
|
|
26
26
|
def post(req_path, params, headers = {})
|
27
|
-
|
28
|
-
|
27
|
+
core.logger.debug "registry: post: #{req_path}"
|
28
|
+
core.logger.debug params
|
29
29
|
csrf_token = fetch_csrf_token
|
30
30
|
|
31
31
|
# set headers
|
@@ -34,18 +34,18 @@ module SocialSnippet::Registry::RegistryResources
|
|
34
34
|
headers["X-CSRF-Token"] = csrf_token
|
35
35
|
|
36
36
|
# debug output
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
core.logger.debug "registry: post: csrf_token = #{csrf_token}"
|
38
|
+
core.logger.debug "registry: post: headers:"
|
39
|
+
core.logger.debug headers
|
40
40
|
|
41
41
|
parse_response rest_client[req_path].post(params.to_json, headers)
|
42
42
|
end
|
43
43
|
|
44
44
|
def get(req_path, headers = {})
|
45
|
-
|
45
|
+
core.logger.debug "registry: get #{req_path}"
|
46
46
|
headers.merge! default_headers
|
47
|
-
|
48
|
-
|
47
|
+
core.logger.debug "registry: headers:"
|
48
|
+
core.logger.debug headers
|
49
49
|
parse_response rest_client[req_path].get(headers)
|
50
50
|
end
|
51
51
|
|
@@ -4,20 +4,20 @@ module SocialSnippet::Repository
|
|
4
4
|
|
5
5
|
class RepositoryInstaller
|
6
6
|
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :core
|
8
8
|
attr_reader :data
|
9
9
|
|
10
|
-
def initialize(
|
11
|
-
@
|
10
|
+
def initialize(new_core)
|
11
|
+
@core = new_core
|
12
12
|
init_data
|
13
13
|
end
|
14
14
|
|
15
15
|
def path
|
16
|
-
|
16
|
+
core.config.install_path
|
17
17
|
end
|
18
18
|
|
19
19
|
def data_file
|
20
|
-
|
20
|
+
core.config.installed_repos_file
|
21
21
|
end
|
22
22
|
|
23
23
|
def init_data
|
@@ -61,7 +61,7 @@ module SocialSnippet::Repository
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def copy_repository(repo, options = {})
|
64
|
-
|
64
|
+
core.logger.debug "repository_installer: repo.path = #{repo.path}"
|
65
65
|
::FileUtils.cp_r repo.path, repo_path(repo.name)
|
66
66
|
end
|
67
67
|
|
@@ -5,15 +5,15 @@ module SocialSnippet::Repository
|
|
5
5
|
attr_reader :installer
|
6
6
|
attr_reader :repo_paths
|
7
7
|
attr_reader :repo_cache_path
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :core
|
9
9
|
|
10
10
|
# Constructor
|
11
11
|
#
|
12
|
-
# @param
|
13
|
-
def initialize(
|
14
|
-
@
|
15
|
-
@installer = ::SocialSnippet::Repository::RepositoryInstaller.new(
|
16
|
-
@repo_cache_path =
|
12
|
+
# @param new_core [::SocialSnippet::Core]
|
13
|
+
def initialize(new_core)
|
14
|
+
@core = new_core
|
15
|
+
@installer = ::SocialSnippet::Repository::RepositoryInstaller.new(core)
|
16
|
+
@repo_cache_path = core.config.repository_cache_path
|
17
17
|
@repo_paths = []
|
18
18
|
|
19
19
|
init_repo_paths
|
@@ -47,19 +47,18 @@ module SocialSnippet::Repository
|
|
47
47
|
::SocialSnippet::Snippet.new(resolve_snippet_path(context, tag))
|
48
48
|
end
|
49
49
|
|
50
|
-
# Resolve snippet path
|
50
|
+
# Resolve snippet path by context and tag
|
51
51
|
#
|
52
52
|
# @param context [::SocialSnippet::Context] The context of snippet
|
53
53
|
# @param tag [::SocialSnippet::Tag] The tag of snippet
|
54
54
|
def resolve_snippet_path(context, tag)
|
55
55
|
if tag.has_repo?
|
56
56
|
repo = find_repository_by_tag(tag)
|
57
|
-
|
57
|
+
repo.real_path tag.path
|
58
|
+
else
|
59
|
+
new_context = context.clone
|
60
|
+
new_context.dirname + "/" + tag.filename
|
58
61
|
end
|
59
|
-
|
60
|
-
new_context = context.clone
|
61
|
-
new_context.move tag.path
|
62
|
-
return new_context.path
|
63
62
|
end
|
64
63
|
|
65
64
|
# Find repository by tag
|
@@ -2,14 +2,14 @@ module SocialSnippet
|
|
2
2
|
|
3
3
|
class Resolvers::BaseResolver
|
4
4
|
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :core
|
6
6
|
attr_reader :visited
|
7
7
|
|
8
8
|
# Constructor
|
9
9
|
#
|
10
|
-
# @param
|
11
|
-
def initialize(
|
12
|
-
@
|
10
|
+
# @param new_core [::SocialSnippet::Core]
|
11
|
+
def initialize(new_core)
|
12
|
+
@core = new_core
|
13
13
|
@visited = Set.new
|
14
14
|
end
|
15
15
|
|
@@ -25,21 +25,35 @@ module SocialSnippet
|
|
25
25
|
t = tag_info[:tag].set_by_tag(base_tag)
|
26
26
|
new_context = context.clone
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
if new_context.root_text?
|
29
|
+
new_context.set_path ""
|
30
|
+
move_context_by_tag! new_context, t
|
31
|
+
else
|
32
|
+
move_context_by_tag! new_context, t
|
33
|
+
overwrite_tag_in_same_repository! new_context, t
|
34
|
+
update_tag_path_by_context! new_context, t
|
35
|
+
resolve_tag_repo_ref! t
|
36
|
+
end
|
32
37
|
|
33
|
-
|
38
|
+
resolve_tag_repo_ref! t
|
39
|
+
child_snippet = core.repo_manager.get_snippet(new_context, t)
|
40
|
+
t.set_path new_context.path
|
34
41
|
|
35
42
|
if block_given?
|
36
|
-
yield
|
43
|
+
yield t, tag_info[:line_no], child_snippet, new_context
|
37
44
|
end
|
38
45
|
end
|
39
46
|
end
|
40
47
|
|
41
48
|
private
|
42
49
|
|
50
|
+
def resolve_tag_repo_ref!(t)
|
51
|
+
if t.has_repo?
|
52
|
+
repo = core.repo_manager.find_repository_by_tag(t)
|
53
|
+
t.set_ref repo.latest_version(t.ref)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
43
57
|
def move_context_by_tag!(context, tag)
|
44
58
|
if tag.has_repo?
|
45
59
|
if tag.has_ref?
|
@@ -69,7 +83,7 @@ module SocialSnippet
|
|
69
83
|
|
70
84
|
# Resolve tag's ref
|
71
85
|
def resolve_tag_repo_ref!(tag)
|
72
|
-
repo =
|
86
|
+
repo = core.repo_manager.find_repository_by_tag(tag)
|
73
87
|
|
74
88
|
# not found
|
75
89
|
return if repo.nil?
|
@@ -6,10 +6,10 @@ module SocialSnippet
|
|
6
6
|
|
7
7
|
# Constructor
|
8
8
|
#
|
9
|
-
# @param
|
10
|
-
def initialize(
|
9
|
+
# @param core [::SocialSnippet::Core]
|
10
|
+
def initialize(core)
|
11
11
|
@dep_to = {} # dep_to[tag_from] = tag_to
|
12
|
-
super(
|
12
|
+
super(core)
|
13
13
|
end
|
14
14
|
|
15
15
|
# Find all missing depended snippets
|
@@ -20,7 +20,7 @@ module SocialSnippet
|
|
20
20
|
def find(snippet, context_from, tag_from)
|
21
21
|
raise "must be passed snippet" unless snippet.is_a?(Snippet)
|
22
22
|
|
23
|
-
found_tags = find_func
|
23
|
+
found_tags = find_func(snippet, context_from, tag_from)
|
24
24
|
found_tags.each do |tag_info|
|
25
25
|
# remove self from deps graph
|
26
26
|
tag = tag_info[:tag]
|
@@ -7,11 +7,11 @@ module SocialSnippet
|
|
7
7
|
|
8
8
|
# Constructor
|
9
9
|
#
|
10
|
-
# @param
|
11
|
-
def initialize(
|
10
|
+
# @param core [::SocialSnippet::Core]
|
11
|
+
def initialize(core, new_options = {})
|
12
12
|
@options = new_options
|
13
|
-
@deps_resolver = Resolvers::DepResolver.new(
|
14
|
-
super(
|
13
|
+
@deps_resolver = Resolvers::DepResolver.new(core)
|
14
|
+
super(core)
|
15
15
|
init_options
|
16
16
|
end
|
17
17
|
|
@@ -26,15 +26,13 @@ module SocialSnippet
|
|
26
26
|
def insert(text)
|
27
27
|
raise "must be passed string" unless text.is_a?(String)
|
28
28
|
|
29
|
-
context = Context.new("")
|
30
29
|
snippet = Snippet.new_text(text)
|
31
|
-
|
32
30
|
snippet.snippet_tags.each do |tag_info|
|
33
31
|
visit tag_info[:tag]
|
34
32
|
end
|
35
33
|
|
36
|
-
|
37
|
-
|
34
|
+
context = Context.new(nil)
|
35
|
+
insert_func(snippet, context).join($/)
|
38
36
|
end
|
39
37
|
|
40
38
|
private
|
@@ -68,7 +66,9 @@ module SocialSnippet
|
|
68
66
|
src = insert_func(snippet, context, tag)
|
69
67
|
|
70
68
|
options[:margin_top].times { inserter.insert "" }
|
71
|
-
|
69
|
+
# @snip -> @snippet
|
70
|
+
inserter.insert tag.to_snippet_tag unless snippet.no_tag?
|
71
|
+
# insert snippet text
|
72
72
|
inserter.insert src
|
73
73
|
options[:margin_bottom].times { inserter.insert "" }
|
74
74
|
|
@@ -85,11 +85,12 @@ module SocialSnippet
|
|
85
85
|
dep_tags.each do |tag_info|
|
86
86
|
sub_t = tag_info[:tag]
|
87
87
|
sub_c = tag_info[:context]
|
88
|
+
resolve_tag_repo_ref! sub_t
|
88
89
|
|
89
|
-
visit(tag) if is_self(
|
90
|
+
visit(tag) if is_self(sub_t, sub_c)
|
90
91
|
next if is_visited(sub_t)
|
91
92
|
|
92
|
-
next_snippet =
|
93
|
+
next_snippet = core.repo_manager.get_snippet(sub_c, sub_t)
|
93
94
|
insert_by_tag_and_context! inserter, next_snippet, sub_c, sub_t
|
94
95
|
end
|
95
96
|
end
|
@@ -109,10 +110,10 @@ module SocialSnippet
|
|
109
110
|
dep_tags.each do |tag_info|
|
110
111
|
tag = tag_info[:tag].to_path
|
111
112
|
dep_ind = dep_tags_index[tag]
|
112
|
-
dep_tags_hash[dep_ind] = deps_resolver.dep_to[tag].to_a.map {|tag| dep_tags_index[tag] }
|
113
|
+
dep_tags_hash[dep_ind] = deps_resolver.dep_to[tag].to_a.map {|tag| dep_tags_index[tag] }.reject(&:nil?)
|
113
114
|
end
|
114
115
|
|
115
|
-
dep_tags_hash.tsort.map {|k| dep_tags[k]}
|
116
|
+
dep_tags_hash.tsort.map {|k| dep_tags[k] }
|
116
117
|
end
|
117
118
|
|
118
119
|
end # BaseResolver
|
@@ -1,75 +1,96 @@
|
|
1
|
-
|
1
|
+
module SocialSnippet
|
2
2
|
|
3
|
-
|
4
|
-
attr_reader :code
|
3
|
+
class Snippet
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
read_file unless filepath.nil?
|
10
|
-
end
|
5
|
+
attr_reader :filepath
|
6
|
+
attr_reader :code
|
7
|
+
attr_reader :flag_no_tag
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
# Constructor
|
10
|
+
def initialize(snippet_path)
|
11
|
+
@filepath = snippet_path
|
12
|
+
read_file unless filepath.nil?
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
15
|
+
def read_file
|
16
|
+
@code = ::File.read(filepath).split($/)
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
def read_text(s)
|
20
|
+
raise "must be passed string" unless s.is_a?(String)
|
21
|
+
@code = s.split($/)
|
22
|
+
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
def lines
|
25
|
+
@lines ||= new_lines
|
26
|
+
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
def snippet_tags
|
29
|
+
TagParser.find_snippet_tags lines
|
30
|
+
end
|
32
31
|
|
33
|
-
|
32
|
+
def snip_tags
|
33
|
+
TagParser.find_snip_tags lines
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
raise "must be passed string" unless s.is_a?(String)
|
38
|
-
snippet = self.new(nil)
|
39
|
-
snippet.read_text s
|
40
|
-
snippet
|
36
|
+
def no_tag?
|
37
|
+
flag_no_tag
|
41
38
|
end
|
42
39
|
|
43
|
-
|
40
|
+
class << self
|
44
41
|
|
45
|
-
|
42
|
+
# Create instance by text
|
43
|
+
def new_text(s)
|
44
|
+
raise "must be passed string" unless s.is_a?(String)
|
45
|
+
snippet = self.new(nil)
|
46
|
+
snippet.read_text s
|
47
|
+
snippet
|
48
|
+
end
|
46
49
|
|
47
|
-
|
48
|
-
def new_lines
|
49
|
-
tmp = code.clone
|
50
|
-
tmp = filter(tmp)
|
51
|
-
tmp
|
52
|
-
end
|
50
|
+
end
|
53
51
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
52
|
+
private
|
53
|
+
|
54
|
+
# Return filtered and styled lines
|
55
|
+
def new_lines
|
56
|
+
tmp = code.clone
|
57
|
+
tmp = filter(tmp)
|
58
|
+
tmp
|
59
|
+
end
|
60
|
+
|
61
|
+
# @param lines [Array<String>]
|
62
|
+
def filter(lines)
|
63
|
+
lines = filter_range_cut(lines)
|
64
|
+
lines = filter_line_cut(lines)
|
65
|
+
lines = resolve_control_tags(lines)
|
66
|
+
lines
|
67
|
+
end
|
68
|
+
|
69
|
+
def resolve_control_tags(lines)
|
70
|
+
@flag_no_tag = (false === TagParser.find_no_tags(lines).empty?)
|
71
|
+
lines.reject {|s| Tag.is_control_tag? s }
|
72
|
+
end
|
59
73
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
74
|
+
def filter_line_cut(lines)
|
75
|
+
lines.select {|s| not Tag.is_cut? s }
|
76
|
+
end
|
77
|
+
|
78
|
+
def filter_range_cut(lines)
|
79
|
+
cut_level = 0
|
80
|
+
lines.select do |line|
|
81
|
+
if Tag.is_begin_cut?(line)
|
82
|
+
cut_level += 1
|
83
|
+
false
|
84
|
+
elsif Tag.is_end_cut?(line)
|
85
|
+
cut_level -= 1
|
86
|
+
false
|
87
|
+
else
|
88
|
+
cut_level === 0
|
89
|
+
end
|
71
90
|
end
|
72
91
|
end
|
92
|
+
|
73
93
|
end
|
74
94
|
|
75
95
|
end
|
96
|
+
|