decode 0.12.0 → 0.15.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bake/decode/index.rb +1 -1
- data/lib/decode/comment/attribute.rb +53 -0
- data/lib/decode/comment/node.rb +90 -0
- data/lib/decode/comment/parameter.rb +58 -0
- data/lib/decode/comment/pragma.rb +50 -0
- data/lib/decode/comment/raises.rb +32 -0
- data/lib/decode/comment/returns.rb +32 -0
- data/lib/decode/comment/tag.rb +50 -0
- data/lib/decode/comment/tags.rb +80 -0
- data/lib/decode/comment/text.rb +37 -0
- data/lib/decode/comment/throws.rb +32 -0
- data/lib/decode/comment/yields.rb +52 -0
- data/lib/decode/definition.rb +26 -19
- data/lib/decode/documentation.rb +21 -66
- data/lib/decode/index.rb +16 -8
- data/lib/decode/language.rb +1 -19
- data/lib/decode/language/generic.rb +51 -0
- data/lib/decode/language/reference.rb +108 -0
- data/lib/decode/language/ruby.rb +50 -8
- data/lib/decode/language/ruby/block.rb +1 -1
- data/lib/decode/language/ruby/class.rb +2 -2
- data/lib/decode/language/ruby/code.rb +85 -0
- data/lib/decode/language/ruby/definition.rb +1 -1
- data/lib/decode/language/ruby/method.rb +7 -1
- data/lib/decode/language/ruby/parser.rb +11 -3
- data/lib/decode/language/ruby/reference.rb +29 -30
- data/lib/decode/language/ruby/segment.rb +1 -1
- data/lib/decode/languages.rb +92 -0
- data/lib/decode/scope.rb +3 -0
- data/lib/decode/segment.rb +4 -4
- data/lib/decode/source.rb +26 -16
- data/lib/decode/syntax/link.rb +44 -0
- data/lib/decode/syntax/match.rb +53 -0
- data/lib/decode/syntax/rewriter.rb +70 -0
- data/lib/decode/trie.rb +13 -13
- data/lib/decode/version.rb +1 -1
- metadata +27 -16
- data/.github/workflows/development.yml +0 -50
- data/.gitignore +0 -13
- data/.rspec +0 -2
- data/README.md +0 -47
- data/decode.gemspec +0 -33
- data/gems.rb +0 -3
- data/guides/extract-symbols/extract.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d503df4edff393db446c6c310b6eea0ecbfe16cf10192a835b92a1685ca7c9bf
|
4
|
+
data.tar.gz: 57bc7884dd02e59b9564c1acbafc037a0dc73c458b8d986febecb5a81f4b250b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10ddb407f54f4091a3a0b876f6a971e9b5c83e68aab21d1255261306e5e15c4d74e063bb3da26e30cd20dfa24c46721d05966b25c5ed537a3e976f16cb8a9fca
|
7
|
+
data.tar.gz: fa41898224db150d5fd491f91d494878336edce0cceecb98a91e6187df6bd55dca9582149028bbefd58587796bbb3b2b629d710c4ef3408d005bd75e30dbf2d0
|
data/bake/decode/index.rb
CHANGED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'tag'
|
22
|
+
|
23
|
+
module Decode
|
24
|
+
module Comment
|
25
|
+
# Describes an attribute type.
|
26
|
+
#
|
27
|
+
# - `@attribute [Integer] The person's age.`
|
28
|
+
#
|
29
|
+
class Attribute < Tag
|
30
|
+
PATTERN = /\A\[(?<type>.*?)\](\s+(?<details>.*?))?\Z/
|
31
|
+
|
32
|
+
def self.build(directive, match)
|
33
|
+
node = self.new(directive, match[:type])
|
34
|
+
|
35
|
+
if details = match[:details]
|
36
|
+
node.add(Text.new(details))
|
37
|
+
end
|
38
|
+
|
39
|
+
return node
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(directive, type)
|
43
|
+
super(directive)
|
44
|
+
|
45
|
+
@type = type
|
46
|
+
end
|
47
|
+
|
48
|
+
# The type of the attribute.
|
49
|
+
# @attribute [String]
|
50
|
+
attr :type
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Decode
|
22
|
+
module Comment
|
23
|
+
class Node
|
24
|
+
# Initialize the node.
|
25
|
+
# @parameter children [Array(Node) | Nil]
|
26
|
+
def initialize(children = nil)
|
27
|
+
@children = children
|
28
|
+
end
|
29
|
+
|
30
|
+
# Whether this node has any children nodes.
|
31
|
+
# Ignores {Text} instances.
|
32
|
+
# @returns [Boolean]
|
33
|
+
def children?
|
34
|
+
@children&.any?{|child| child.is_a?(Node)}
|
35
|
+
end
|
36
|
+
|
37
|
+
# Add a child node to this node.
|
38
|
+
# @parameter child [Node] The node to add.
|
39
|
+
def add(child)
|
40
|
+
@children ||= []
|
41
|
+
@children << child
|
42
|
+
end
|
43
|
+
|
44
|
+
# Any children of this node.
|
45
|
+
# @attribute [Array(Node | Text) | Nil]
|
46
|
+
attr :children
|
47
|
+
|
48
|
+
# Enumerate all non-text children nodes.
|
49
|
+
def each(&block)
|
50
|
+
return to_enum unless block_given?
|
51
|
+
|
52
|
+
@children&.each do |child|
|
53
|
+
yield child if child.is_a?(Node)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Any lines of text associated wtih this node.
|
58
|
+
# @returns [Array(String) | Nil] The lines of text.
|
59
|
+
def text
|
60
|
+
if text = self.extract_text
|
61
|
+
return text if text.any?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Traverse the tags from this node using {each}.
|
66
|
+
# Invoke `descend.call(child)` to recursively traverse the specified child.
|
67
|
+
#
|
68
|
+
# @yields {|node, descend| descend.call}
|
69
|
+
# @parameter node [Node] The current node which is being traversed.
|
70
|
+
# @parameter descend [Proc | Nil] The recursive method for traversing children.
|
71
|
+
def traverse(&block)
|
72
|
+
descend = ->(node){
|
73
|
+
node.traverse(&block)
|
74
|
+
}
|
75
|
+
|
76
|
+
yield(self, descend)
|
77
|
+
end
|
78
|
+
|
79
|
+
protected
|
80
|
+
|
81
|
+
def extract_text
|
82
|
+
if children = @children
|
83
|
+
@children.select{|child| child.kind_of?(Text)}.map(&:line)
|
84
|
+
else
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'tag'
|
22
|
+
|
23
|
+
module Decode
|
24
|
+
module Comment
|
25
|
+
# Describes a named method parameter.
|
26
|
+
#
|
27
|
+
# - `@parameter age [Float] The users age.`
|
28
|
+
#
|
29
|
+
class Parameter < Tag
|
30
|
+
PATTERN = /\A(?<name>.*?)\s+\[(?<type>.*?)\](\s+(?<details>.*?))?\Z/
|
31
|
+
|
32
|
+
def self.build(directive, match)
|
33
|
+
node = self.new(directive, match[:name], match[:type])
|
34
|
+
|
35
|
+
if details = match[:details]
|
36
|
+
node.add(Text.new(details))
|
37
|
+
end
|
38
|
+
|
39
|
+
return node
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(directive, name, type)
|
43
|
+
super(directive)
|
44
|
+
|
45
|
+
@name = name
|
46
|
+
@type = type
|
47
|
+
end
|
48
|
+
|
49
|
+
# The name of the parameter.
|
50
|
+
# @attribute [String]
|
51
|
+
attr :name
|
52
|
+
|
53
|
+
# The type of the attribute.
|
54
|
+
# @attribute [String]
|
55
|
+
attr :type
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'tag'
|
22
|
+
|
23
|
+
module Decode
|
24
|
+
module Comment
|
25
|
+
# Asserts a specific property about the method signature.
|
26
|
+
#
|
27
|
+
# - `@reentrant This method is thread-safe.`
|
28
|
+
# - `@deprecated Please use {other_method} instead.`
|
29
|
+
# - `@blocking This method may block.`
|
30
|
+
# - `@asynchronous This method may yield.`
|
31
|
+
#
|
32
|
+
class Pragma < Tag
|
33
|
+
PATTERN = /\A(?<details>.*?)?\Z/
|
34
|
+
|
35
|
+
def self.build(directive, match)
|
36
|
+
node = self.new(directive)
|
37
|
+
|
38
|
+
if details = match[:details]
|
39
|
+
node.add(Text.new(details))
|
40
|
+
end
|
41
|
+
|
42
|
+
return node
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize(directive)
|
46
|
+
super(directive)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'attribute'
|
22
|
+
|
23
|
+
module Decode
|
24
|
+
module Comment
|
25
|
+
# Identifies that a method might raise an exception.
|
26
|
+
#
|
27
|
+
# - `@raises [ArgumentError] If the argument cannot be coerced.`
|
28
|
+
#
|
29
|
+
class Raises < Attribute
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'attribute'
|
22
|
+
|
23
|
+
module Decode
|
24
|
+
module Comment
|
25
|
+
# Describes a return value.
|
26
|
+
#
|
27
|
+
# - `@returns [Integer] The person's age.`
|
28
|
+
#
|
29
|
+
class Returns < Attribute
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'node'
|
22
|
+
|
23
|
+
module Decode
|
24
|
+
module Comment
|
25
|
+
class Tag < Node
|
26
|
+
def self.parse(directive, text, lines, tags, level = 0)
|
27
|
+
if match = self::PATTERN.match(text)
|
28
|
+
node = self.build(directive, match)
|
29
|
+
|
30
|
+
tags.parse(lines, level + 1) do |child|
|
31
|
+
node.add(child)
|
32
|
+
end
|
33
|
+
|
34
|
+
return node
|
35
|
+
else
|
36
|
+
# Consume all nested nodes:
|
37
|
+
tags.ignore(lines, level + 1)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(directive)
|
42
|
+
@directive = directive
|
43
|
+
end
|
44
|
+
|
45
|
+
# The directive that generated the tag.
|
46
|
+
# @attribute [String]
|
47
|
+
attr :directive
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'text'
|
22
|
+
|
23
|
+
module Decode
|
24
|
+
module Comment
|
25
|
+
class Tags
|
26
|
+
def self.build
|
27
|
+
directives = Hash.new
|
28
|
+
|
29
|
+
yield directives
|
30
|
+
|
31
|
+
return self.new(directives)
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(directives)
|
35
|
+
@directives = directives
|
36
|
+
end
|
37
|
+
|
38
|
+
def valid_indentation?(line, level)
|
39
|
+
line.start_with?(' ' * level) || line.start_with?("\t" * level)
|
40
|
+
end
|
41
|
+
|
42
|
+
PATTERN = /\A\s*@(?<directive>.*?)(\s+(?<remainder>.*?))?\Z/
|
43
|
+
|
44
|
+
def parse(lines, level = 0, &block)
|
45
|
+
while line = lines.first
|
46
|
+
# Is it at the right indentation level:
|
47
|
+
return unless valid_indentation?(line, level)
|
48
|
+
|
49
|
+
# We are going to consume the line:
|
50
|
+
lines.shift
|
51
|
+
|
52
|
+
# Match it against a tag:
|
53
|
+
if match = PATTERN.match(line)
|
54
|
+
if klass = @directives[match[:directive]]
|
55
|
+
yield klass.parse(
|
56
|
+
match[:directive], match[:remainder],
|
57
|
+
lines, self, level
|
58
|
+
)
|
59
|
+
else
|
60
|
+
# Ignore unknown directive.
|
61
|
+
end
|
62
|
+
|
63
|
+
# Or it's just text:
|
64
|
+
else
|
65
|
+
yield Text.new(line.strip)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def ignore(lines, level = 0)
|
71
|
+
if line = lines.first
|
72
|
+
# Is it at the right indentation level:
|
73
|
+
return unless valid_indentation?(line, level)
|
74
|
+
|
75
|
+
lines.shift
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|