class SublimeDSL::TextMate::Grammar::PListReader
Attributes
grammar[R]
Public Class Methods
new(file)
click to toggle source
# File lib/sublime_dsl/textmate/grammar/plist_reader.rb, line 14 def initialize(file) @grammar = Grammar.new(nil, nil) read_plist PList.import(file) @grammar.basename = File.basename(file, File.extname(file)) @grammar.complete! end
Private Instance Methods
assign_captures(object, captures)
click to toggle source
Assign the PList
captures
to object
(a Match
or a BeginEndRule
).
# File lib/sublime_dsl/textmate/grammar/plist_reader.rb, line 134 def assign_captures(object, captures) # get the captures, making sure the keys are in ascending order cap = [] captures.each_pair do |k,v| name = v['name'] if name.nil? warn "invalid capture in grammar #{grammar}: #{v.inspect}" next elsif v.length > 1 warn "extra capture ignored in grammar #{grammar}: #{v.inspect}" end cap[k.to_i] = name unless name.empty? end cap.each_with_index { |name, index| object.captures[index] = name if name } end
cleanup(text)
click to toggle source
Replaces tabs by 2 spaces & dedents.
# File lib/sublime_dsl/textmate/grammar/plist_reader.rb, line 151 def cleanup(text) text && text.gsub("\t", ' ').dedent end
create_match(re, captures, backref = nil)
click to toggle source
# File lib/sublime_dsl/textmate/grammar/plist_reader.rb, line 127 def create_match(re, captures, backref = nil) m = Match.new(regexp(re, backref)) assign_captures m, captures if captures m end
patterns(list, parent)
click to toggle source
# File lib/sublime_dsl/textmate/grammar/plist_reader.rb, line 56 def patterns(list, parent) list.map { |v| scan v, parent }.flatten end
read_plist(root)
click to toggle source
# File lib/sublime_dsl/textmate/grammar/plist_reader.rb, line 23 def read_plist(root) grammar.name = root.delete('name') grammar.scope = root.delete('scopeName') root.each_pair do |key, value| case key when 'comment' grammar.comment = cleanup(value) when 'fileTypes' grammar.file_types = value # an array of strings when *%w(foldingStartMarker foldingStopMarker firstLineMatch) grammar.send key.snake_case + '=', regexp(value) when *%w(keyEquivalent bundleUUID uuid) grammar.send key.snake_case + '=', value when 'patterns' grammar.patterns = patterns(value, grammar) # an array when 'repository' value.each_pair do |name, content| f = Fragment.new(name) f.patterns = scan(content, f) f.patterns = [f.patterns] unless f.patterns.is_a? Array grammar.fragments << f end when 'injections' warn "grammar #{grammar}: #{key.inspect} is not supported" else warn "unknown key in grammar #{grammar}: #{key.inspect}" end end end
regexp(str, backref = nil)
click to toggle source
# File lib/sublime_dsl/textmate/grammar/plist_reader.rb, line 155 def regexp(str, backref = nil) Tools::RegexpWannabe.new(str, backref) end
scan(value, parent)
click to toggle source
# File lib/sublime_dsl/textmate/grammar/plist_reader.rb, line 60 def scan(value, parent) value.is_a?(Hash) or raise Error, "expected a Hash: #{value.inspect}" hash = value.dup comment = cleanup(hash.delete('comment')) if (inc = hash['include']) hash.length == 1 or raise Error, "include: too many keys: #{value.inspect}" inc = Include.new(inc) inc.comment = comment return inc end # do not create a rule that just contains patterns: return the patterns instead if hash.length == 1 && hash['patterns'] if comment parent.comment and raise Error, 'comment conflict' parent.comment = comment end return patterns(hash['patterns'], parent) end if (match = hash.delete('match')) rule = MatchRule.new caps = hash.delete('captures') if hash['beginCaptures'] caps and raise Error, "both 'beginCaptures' and 'captures': " << value.inspect warn "grammar '#{grammar}': 'beginCaptures' understood as 'captures'" \ " in 'match' rule: " << value.inspect caps = hash.delete('beginCaptures') end rule.match = create_match(match, caps) elsif hash['begin'] || hash['end'] rule = BeginEndRule.new rule.content_scope = hash.delete('contentName') bcap = hash.delete('beginCaptures') ecap = hash.delete('endCaptures') caps = hash.delete('captures') assign_captures rule, caps if caps beg_re = hash.delete('begin') unless beg_re warn "no 'begin' for rule with 'end' in grammar #{grammar}" beg_re = '' end end_re = hash.delete('end') unless end_re warn "no 'end' for rule with 'begin' in grammar #{grammar}" end_re = '' end rule.from = create_match(beg_re, bcap) rule.to = create_match(end_re, ecap, rule.from.regexp) rule.to_last = hash.delete('applyEndPatternLast') else warn "grammar #{grammar}: no 'begin' nor 'match': " << hash.inspect rule = NoMatchRule.new end rule.scope = hash.delete('name') rule.comment = comment rule.disabled = hash.delete('disabled') rule.patterns = patterns(hash.delete('patterns'), rule) if hash['patterns'] hash.length == 0 or warn "invalid rule keys in grammar #{grammar}: #{hash.inspect}" rule.complete!(grammar) rule end