ruby_grammar_builder 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/LICENSE +21 -0
- data/lib/textmate_grammar/generated/grammar.rb +32 -0
- data/lib/textmate_grammar/generated/rule.rb +144 -0
- data/lib/textmate_grammar/grammar.rb +670 -0
- data/lib/textmate_grammar/grammar_plugin.rb +189 -0
- data/lib/textmate_grammar/import_patterns.rb +14 -0
- data/lib/textmate_grammar/linters/flat_includes.rb +32 -0
- data/lib/textmate_grammar/linters/includes_then_tag_as.rb +48 -0
- data/lib/textmate_grammar/linters/standard_naming.rb +226 -0
- data/lib/textmate_grammar/linters/start_match_empty.rb +49 -0
- data/lib/textmate_grammar/linters/tests.rb +19 -0
- data/lib/textmate_grammar/linters/unused_unresolved.rb +9 -0
- data/lib/textmate_grammar/pattern_extensions/look_ahead_for.rb +32 -0
- data/lib/textmate_grammar/pattern_extensions/look_ahead_to_avoid.rb +31 -0
- data/lib/textmate_grammar/pattern_extensions/look_behind_for.rb +31 -0
- data/lib/textmate_grammar/pattern_extensions/look_behind_to_avoid.rb +31 -0
- data/lib/textmate_grammar/pattern_extensions/lookaround_pattern.rb +169 -0
- data/lib/textmate_grammar/pattern_extensions/match_result_of.rb +67 -0
- data/lib/textmate_grammar/pattern_extensions/maybe.rb +50 -0
- data/lib/textmate_grammar/pattern_extensions/one_of.rb +107 -0
- data/lib/textmate_grammar/pattern_extensions/one_or_more_of.rb +42 -0
- data/lib/textmate_grammar/pattern_extensions/or_pattern.rb +55 -0
- data/lib/textmate_grammar/pattern_extensions/placeholder.rb +102 -0
- data/lib/textmate_grammar/pattern_extensions/recursively_match.rb +76 -0
- data/lib/textmate_grammar/pattern_extensions/zero_or_more_of.rb +50 -0
- data/lib/textmate_grammar/pattern_variations/base_pattern.rb +870 -0
- data/lib/textmate_grammar/pattern_variations/legacy_pattern.rb +61 -0
- data/lib/textmate_grammar/pattern_variations/pattern.rb +9 -0
- data/lib/textmate_grammar/pattern_variations/pattern_range.rb +233 -0
- data/lib/textmate_grammar/pattern_variations/repeatable_pattern.rb +204 -0
- data/lib/textmate_grammar/regex_operator.rb +182 -0
- data/lib/textmate_grammar/regex_operators/alternation.rb +24 -0
- data/lib/textmate_grammar/regex_operators/concat.rb +23 -0
- data/lib/textmate_grammar/stdlib/common.rb +20 -0
- data/lib/textmate_grammar/tokens.rb +110 -0
- data/lib/textmate_grammar/transforms/add_ending.rb +25 -0
- data/lib/textmate_grammar/transforms/bailout.rb +92 -0
- data/lib/textmate_grammar/transforms/fix_repeated_tag_as.rb +75 -0
- data/lib/textmate_grammar/transforms/resolve_placeholders.rb +121 -0
- data/lib/textmate_grammar/util.rb +198 -0
- data/lib/textmate_grammar.rb +4 -0
- metadata +85 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# tag_as: inside a quantifier does not work as expected, this fixes it
|
5
|
+
#
|
6
|
+
class FixRepeatedTagAs < GrammarTransform
|
7
|
+
#
|
8
|
+
# Does pattern or any of its children / siblings have a tag_as
|
9
|
+
#
|
10
|
+
# @param [PatternBase, String] pattern the pattern to check
|
11
|
+
#
|
12
|
+
# @return [Boolean] if any of the patterns have a tag_as
|
13
|
+
#
|
14
|
+
def tag_as?(pattern)
|
15
|
+
return false unless pattern.is_a? PatternBase
|
16
|
+
|
17
|
+
pattern.each do |s|
|
18
|
+
return true if s.arguments[:tag_as]
|
19
|
+
end
|
20
|
+
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# fixes tag_as when it is inside a quantifier
|
26
|
+
# see https://github.com/jeff-hykin/cpp-textmate-grammar/issues/339#issuecomment-543285390
|
27
|
+
# for an explanation of why and how
|
28
|
+
#
|
29
|
+
def pre_transform(pattern, options)
|
30
|
+
return pattern.map { |v| pre_transform(v, options) } if pattern.is_a? Array
|
31
|
+
return pattern unless pattern.is_a? PatternBase
|
32
|
+
return pattern if pattern.is_a? PatternRange
|
33
|
+
|
34
|
+
pattern.map do |pat|
|
35
|
+
next pat unless pat.respond_to? :self_capture_group_rematch
|
36
|
+
next pat unless pat.self_capture_group_rematch
|
37
|
+
next pat unless tag_as?(pat.match)
|
38
|
+
|
39
|
+
unless pat.arguments[:includes].nil? || pat.arguments[:includes].empty?
|
40
|
+
raise "Cannot transform a Repeated pattern that has non empty includes"
|
41
|
+
end
|
42
|
+
|
43
|
+
pat.arguments[:includes] = [pat.match.__deep_clone__]
|
44
|
+
pat.match.map! do |pm|
|
45
|
+
pm.arguments.delete(:tag_as)
|
46
|
+
pm.arguments.delete(:includes)
|
47
|
+
next unless options[:preserve_references?] || pm.arguments[:preserve_references?]
|
48
|
+
|
49
|
+
pm.self_scramble_references
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Contributes the option :preserve_references?
|
56
|
+
#
|
57
|
+
# :preserve_references? disables the scrambling of references
|
58
|
+
#
|
59
|
+
# @return (see GrammarPlugin.options)
|
60
|
+
#
|
61
|
+
def self.options
|
62
|
+
[:preserve_references?]
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Displays the state of the options
|
67
|
+
#
|
68
|
+
# @return (see GrammarPlugin.display_options)
|
69
|
+
#
|
70
|
+
def self.display_options(indent, options)
|
71
|
+
",\n#{indent}preserve_references?: #{options[:preserve_references?]}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
Grammar.register_transform(FixRepeatedTagAs.new, 99)
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Resolves any embedded placeholders
|
5
|
+
#
|
6
|
+
class ResolvePlaceholders < GrammarTransform
|
7
|
+
def pre_transform(pattern, options)
|
8
|
+
return pattern unless pattern.is_a? PatternBase
|
9
|
+
pattern_copy = pattern.__deep_clone__
|
10
|
+
pattern_copy.map!(true) do |each_pattern_like|
|
11
|
+
|
12
|
+
arguments = each_pattern_like.arguments
|
13
|
+
repository = options[:repository]
|
14
|
+
|
15
|
+
if each_pattern_like.is_a?(PlaceholderPattern)
|
16
|
+
|
17
|
+
unless repository[arguments[:placeholder]].is_a? PatternBase
|
18
|
+
raise ":#{arguments[:placeholder]} is not a pattern and cannot be substituted"
|
19
|
+
end
|
20
|
+
|
21
|
+
each_pattern_like.match = repository[arguments[:placeholder]].__deep_clone__
|
22
|
+
#
|
23
|
+
# token pattern
|
24
|
+
#
|
25
|
+
elsif each_pattern_like.is_a?(TokenPattern)
|
26
|
+
qualifying_patterns = []
|
27
|
+
for each_key, each_value in repository
|
28
|
+
next unless each_value.is_a?(PatternBase)
|
29
|
+
qualifying_patterns << each_value if arguments[:pattern_filter][each_value]
|
30
|
+
end
|
31
|
+
if qualifying_patterns.size == 0
|
32
|
+
raise <<-HEREDOC.remove_indent
|
33
|
+
|
34
|
+
|
35
|
+
When creating a token filter #{arguments[:pattern_filter]}
|
36
|
+
all the patterns that are in the grammar repository were searched
|
37
|
+
but none of thier adjective lists matched the token filter
|
38
|
+
HEREDOC
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# change this pattern right before the grammar is generated
|
43
|
+
each_pattern_like.match = oneOf(qualifying_patterns)
|
44
|
+
end
|
45
|
+
each_pattern_like
|
46
|
+
end
|
47
|
+
pattern_copy.freeze
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# resolving placeholders has no dependencies and makes analyzing patterns much nicer
|
52
|
+
# so it happens fairly early
|
53
|
+
Grammar.register_transform(ResolvePlaceholders.new, 0)
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
# # frozen_string_literal: true
|
60
|
+
|
61
|
+
# #
|
62
|
+
# # Resolves any embedded placeholders
|
63
|
+
# #
|
64
|
+
# class ResolvePlaceholders < GrammarTransform
|
65
|
+
# def pre_transform(pattern, options)
|
66
|
+
# # skip past anything that isn't a pattern
|
67
|
+
# return pattern unless pattern.is_a? PatternBase
|
68
|
+
|
69
|
+
# pattern_copy = pattern.__deep_clone__
|
70
|
+
# # recursively fill in all of the placeholders by looking them up
|
71
|
+
# repository = options[:repository]
|
72
|
+
# pattern_copy.map!(true) do |each_pattern_like|
|
73
|
+
# arguments = each_pattern_like.arguments
|
74
|
+
# name_of_placeholder = arguments[:placeholder]
|
75
|
+
# #
|
76
|
+
# # placeholder pattern
|
77
|
+
# #
|
78
|
+
# if each_pattern_like.is_a?(PlaceholderPattern)
|
79
|
+
# # error if can't find thing the placeholder is reffering to
|
80
|
+
# if !repository[name_of_placeholder].is_a?(PatternBase)
|
81
|
+
# raise "\n#{arguments[:placeholder]} is not a pattern and cannot be substituted"
|
82
|
+
# end
|
83
|
+
|
84
|
+
# # if the pattern exists though, make the substitution
|
85
|
+
# arguments = { match:repository[arguments[:placeholder]].__deep_clone__ }
|
86
|
+
# for each_key, each_value in each_pattern_like.arguments
|
87
|
+
# arguments[each_key] = each_value
|
88
|
+
# end
|
89
|
+
# each_pattern_like = Pattern.new(arguments)
|
90
|
+
# #
|
91
|
+
# # token pattern
|
92
|
+
# #
|
93
|
+
# elsif each_pattern_like.is_a?(TokenPattern)
|
94
|
+
# qualifying_patterns = []
|
95
|
+
# for each_key, each_value in repository
|
96
|
+
# next unless each_value.is_a?(PatternBase)
|
97
|
+
# qualifying_patterns << each_value if arguments[:pattern_filter][each_value]
|
98
|
+
# end
|
99
|
+
# if qualifying_patterns.size == 0
|
100
|
+
# raise <<-HEREDOC.remove_indent
|
101
|
+
|
102
|
+
|
103
|
+
# When creating a token filter #{arguments[:pattern_filter]}
|
104
|
+
# all the patterns that are in the grammar repository were searched
|
105
|
+
# but none of thier adjective lists matched the token filter
|
106
|
+
# HEREDOC
|
107
|
+
# end
|
108
|
+
|
109
|
+
|
110
|
+
# # change this pattern right before the grammar is generated
|
111
|
+
# each_pattern_like.match = oneOf(qualifying_patterns)
|
112
|
+
# end
|
113
|
+
# each_pattern_like
|
114
|
+
# end
|
115
|
+
# return pattern_copy
|
116
|
+
# end
|
117
|
+
# end
|
118
|
+
|
119
|
+
# # resolving placeholders has no dependencies and makes analyzing patterns much nicer
|
120
|
+
# # so it happens fairly early
|
121
|
+
# Grammar.register_transform(ResolvePlaceholders.new, 0)
|
@@ -0,0 +1,198 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Disables warnings for the block
|
5
|
+
#
|
6
|
+
# @return [void]
|
7
|
+
#
|
8
|
+
def with_no_warnings
|
9
|
+
old_verbose = $VERBOSE
|
10
|
+
$VERBOSE = nil
|
11
|
+
yield
|
12
|
+
ensure
|
13
|
+
$VERBOSE = old_verbose
|
14
|
+
end
|
15
|
+
|
16
|
+
# Add remove indent to the String class
|
17
|
+
class String
|
18
|
+
# a helper for writing multi-line strings for error messages
|
19
|
+
# example usage
|
20
|
+
# puts <<-HEREDOC.remove_indent
|
21
|
+
# This command does such and such.
|
22
|
+
# this part is extra indented
|
23
|
+
# HEREDOC
|
24
|
+
# @return [String]
|
25
|
+
def remove_indent
|
26
|
+
gsub(/^[ \t]{#{match(/^[ \t]*/)[0].length}}/, '')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Provides to_s
|
32
|
+
#
|
33
|
+
class Enumerator
|
34
|
+
#
|
35
|
+
# Converts Enumerator to a string representing Integer.times
|
36
|
+
#
|
37
|
+
# @return [String] the Enumerator as a string
|
38
|
+
#
|
39
|
+
def to_s
|
40
|
+
size.to_s + ".times"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# determines if a regex string is a single entity
|
45
|
+
#
|
46
|
+
# @note single entity means that for the purposes of modification, the expression is
|
47
|
+
# atomic, for example if appending a +*+ to the end of +regex_string+ matches only
|
48
|
+
# a part of regex string multiple times then it is not a single_entity
|
49
|
+
# @param regex_string [String] a string representing a regular expression, without the
|
50
|
+
# forward slash "/" at the beginning and
|
51
|
+
# @return [Boolean] if the string represents an single regex entity
|
52
|
+
def string_single_entity?(regex_string)
|
53
|
+
escaped = false
|
54
|
+
in_set = false
|
55
|
+
depth = 0
|
56
|
+
regex_string.each_char.with_index do |c, index|
|
57
|
+
# allow the first character to be at depth 0
|
58
|
+
# NOTE: this automatically makes a single char regexp a single entity
|
59
|
+
return false if depth == 0 && index != 0
|
60
|
+
|
61
|
+
if escaped
|
62
|
+
escaped = false
|
63
|
+
next
|
64
|
+
end
|
65
|
+
if c == '\\'
|
66
|
+
escaped = true
|
67
|
+
next
|
68
|
+
end
|
69
|
+
if in_set
|
70
|
+
if c == ']'
|
71
|
+
in_set = false
|
72
|
+
depth -= 1
|
73
|
+
end
|
74
|
+
next
|
75
|
+
end
|
76
|
+
case c
|
77
|
+
when "(" then depth += 1
|
78
|
+
when ")" then depth -= 1
|
79
|
+
when "["
|
80
|
+
depth += 1
|
81
|
+
in_set = true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
# sanity check
|
85
|
+
if depth != 0 or escaped or in_set
|
86
|
+
puts "Internal error: when determining if a Regexp is a single entity"
|
87
|
+
puts "an unexpected sequence was found. This is a bug with the gem."
|
88
|
+
puts "This will not effect the validity of the produced grammar"
|
89
|
+
puts "Regexp: #{inspect} depth: #{depth} escaped: #{escaped} in_set: #{in_set}"
|
90
|
+
return false
|
91
|
+
end
|
92
|
+
true
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Wraps a pattern in start and end anchors
|
97
|
+
#
|
98
|
+
# @param [PatternBase] pat the pattern to wrap
|
99
|
+
#
|
100
|
+
# @return [PatternBase] the wrapped pattern
|
101
|
+
#
|
102
|
+
def wrap_with_anchors(pat)
|
103
|
+
Pattern.new(/^/).then(Pattern.new(pat)).then(/$/)
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# Fixes value to be either a PatternBase, Symbol, or Array of either
|
108
|
+
#
|
109
|
+
# @param [*] value The value to fixup
|
110
|
+
#
|
111
|
+
# @return [PatternBase,Symbol,Array<PatternBase,Symbol>] the fixed value
|
112
|
+
#
|
113
|
+
def fixup_value(value)
|
114
|
+
is_array = value.is_a? Array
|
115
|
+
# ensure array is flat and only contains patterns or symbols
|
116
|
+
value = [value].flatten.map do |v|
|
117
|
+
next v if v.is_a? Symbol
|
118
|
+
|
119
|
+
if v.is_a? String
|
120
|
+
next v if v.start_with?("source.", "text.", "$")
|
121
|
+
end
|
122
|
+
|
123
|
+
if v.is_a? Hash
|
124
|
+
# check for an implicit legacy pattern
|
125
|
+
legacy_keys = [
|
126
|
+
:name,
|
127
|
+
:contentName,
|
128
|
+
:begin,
|
129
|
+
:end,
|
130
|
+
:while,
|
131
|
+
:comment,
|
132
|
+
:disabled,
|
133
|
+
:patterns,
|
134
|
+
]
|
135
|
+
v = LegacyPattern.new(v) unless (v.keys.map(&:to_sym) & legacy_keys).empty?
|
136
|
+
end
|
137
|
+
|
138
|
+
v = Pattern.new(v) unless v.is_a? PatternBase
|
139
|
+
v
|
140
|
+
end
|
141
|
+
|
142
|
+
value = value[0] unless is_array
|
143
|
+
value
|
144
|
+
end
|
145
|
+
|
146
|
+
#
|
147
|
+
# Determine the absolute path that a require statement resolves to
|
148
|
+
#
|
149
|
+
# @note this assumes path was successfully required previously
|
150
|
+
#
|
151
|
+
# @param [String] path the path to resolve
|
152
|
+
#
|
153
|
+
# @return [String] the resolved path
|
154
|
+
#
|
155
|
+
def resolve_require(path)
|
156
|
+
path = Pathname.new path
|
157
|
+
return path.to_s if path.absolute? && path.extname != ""
|
158
|
+
|
159
|
+
return path.dirname.glob("#{path.basename}.{rb,so,dll}")[0].to_s if path.absolute?
|
160
|
+
|
161
|
+
$LOAD_PATH.each do |p|
|
162
|
+
test_path = Pathname.new(p).join(path)
|
163
|
+
return test_path.to_s if path.extname != "" && test_path.exist?
|
164
|
+
|
165
|
+
test_paths = test_path.dirname.glob("#{test_path.basename}.{rb,so,dll}")
|
166
|
+
return test_paths[0].to_s unless test_paths.empty?
|
167
|
+
end
|
168
|
+
|
169
|
+
""
|
170
|
+
end
|
171
|
+
|
172
|
+
#
|
173
|
+
# Converts an output into a set of tags
|
174
|
+
#
|
175
|
+
# @param [Hash] output output of Grammar#generate
|
176
|
+
#
|
177
|
+
# @return [Set<String>] The tags in the grammar
|
178
|
+
#
|
179
|
+
def get_tags(output)
|
180
|
+
repository = output[:repository]
|
181
|
+
repository[:$initial_context] = {patterns: output[:patterns]}
|
182
|
+
tags = Set.new
|
183
|
+
add_tags = lambda do |rule|
|
184
|
+
rule = rule.transform_keys(&:to_sym)
|
185
|
+
tags.merge(rule[:name].split(" ")) if rule[:name]
|
186
|
+
tags.merge(rule[:contentName].split(" ")) if rule[:contentName]
|
187
|
+
|
188
|
+
rule[:patterns]&.each { |p| add_tags.call(p) }
|
189
|
+
rule[:captures]&.values&.each { |p| add_tags.call(p) }
|
190
|
+
rule[:beginCaptures]&.values&.each { |p| add_tags.call(p) }
|
191
|
+
rule[:endCaptures]&.values&.each { |p| add_tags.call(p) }
|
192
|
+
rule[:whileCaptures]&.values&.each { |p| add_tags.call(p) }
|
193
|
+
end
|
194
|
+
|
195
|
+
repository.values.each { |p| add_tags.call(p) }
|
196
|
+
|
197
|
+
tags
|
198
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby_grammar_builder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeff Hykin
|
8
|
+
- Matthew Fosdick
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2019-09-16 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email:
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- LICENSE
|
21
|
+
- lib/textmate_grammar.rb
|
22
|
+
- lib/textmate_grammar/generated/grammar.rb
|
23
|
+
- lib/textmate_grammar/generated/rule.rb
|
24
|
+
- lib/textmate_grammar/grammar.rb
|
25
|
+
- lib/textmate_grammar/grammar_plugin.rb
|
26
|
+
- lib/textmate_grammar/import_patterns.rb
|
27
|
+
- lib/textmate_grammar/linters/flat_includes.rb
|
28
|
+
- lib/textmate_grammar/linters/includes_then_tag_as.rb
|
29
|
+
- lib/textmate_grammar/linters/standard_naming.rb
|
30
|
+
- lib/textmate_grammar/linters/start_match_empty.rb
|
31
|
+
- lib/textmate_grammar/linters/tests.rb
|
32
|
+
- lib/textmate_grammar/linters/unused_unresolved.rb
|
33
|
+
- lib/textmate_grammar/pattern_extensions/look_ahead_for.rb
|
34
|
+
- lib/textmate_grammar/pattern_extensions/look_ahead_to_avoid.rb
|
35
|
+
- lib/textmate_grammar/pattern_extensions/look_behind_for.rb
|
36
|
+
- lib/textmate_grammar/pattern_extensions/look_behind_to_avoid.rb
|
37
|
+
- lib/textmate_grammar/pattern_extensions/lookaround_pattern.rb
|
38
|
+
- lib/textmate_grammar/pattern_extensions/match_result_of.rb
|
39
|
+
- lib/textmate_grammar/pattern_extensions/maybe.rb
|
40
|
+
- lib/textmate_grammar/pattern_extensions/one_of.rb
|
41
|
+
- lib/textmate_grammar/pattern_extensions/one_or_more_of.rb
|
42
|
+
- lib/textmate_grammar/pattern_extensions/or_pattern.rb
|
43
|
+
- lib/textmate_grammar/pattern_extensions/placeholder.rb
|
44
|
+
- lib/textmate_grammar/pattern_extensions/recursively_match.rb
|
45
|
+
- lib/textmate_grammar/pattern_extensions/zero_or_more_of.rb
|
46
|
+
- lib/textmate_grammar/pattern_variations/base_pattern.rb
|
47
|
+
- lib/textmate_grammar/pattern_variations/legacy_pattern.rb
|
48
|
+
- lib/textmate_grammar/pattern_variations/pattern.rb
|
49
|
+
- lib/textmate_grammar/pattern_variations/pattern_range.rb
|
50
|
+
- lib/textmate_grammar/pattern_variations/repeatable_pattern.rb
|
51
|
+
- lib/textmate_grammar/regex_operator.rb
|
52
|
+
- lib/textmate_grammar/regex_operators/alternation.rb
|
53
|
+
- lib/textmate_grammar/regex_operators/concat.rb
|
54
|
+
- lib/textmate_grammar/stdlib/common.rb
|
55
|
+
- lib/textmate_grammar/tokens.rb
|
56
|
+
- lib/textmate_grammar/transforms/add_ending.rb
|
57
|
+
- lib/textmate_grammar/transforms/bailout.rb
|
58
|
+
- lib/textmate_grammar/transforms/fix_repeated_tag_as.rb
|
59
|
+
- lib/textmate_grammar/transforms/resolve_placeholders.rb
|
60
|
+
- lib/textmate_grammar/util.rb
|
61
|
+
homepage: https://github.com/jeff-hykin/cpp-textmate-grammar
|
62
|
+
licenses:
|
63
|
+
- MIT
|
64
|
+
metadata:
|
65
|
+
yard.run: yri
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 2.5.0
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubygems_version: 3.2.16
|
82
|
+
signing_key:
|
83
|
+
specification_version: 4
|
84
|
+
summary: A library to generate textmate grammars
|
85
|
+
test_files: []
|