class List::Matcher::Special
Attributes
engine[R]
left[RW]
list[RW]
right[RW]
special_map[R]
specials[RW]
Public Class Methods
new( engine, specials, list )
click to toggle source
# File lib/list_matcher.rb, line 336 def initialize( engine, specials, list ) @engine = engine @list = list max = 0 list.each do |w| w.chars.each{ |c| i = c.ord; max = i if i > max } end @specials = [].tap do |ar| specials.sort do |a, b| a = a.first b = b.first s1 = a.is_a?(String) || a.is_a?(Symbol) s2 = b.is_a?(String) || b.is_a?(Symbol) if s1 && s2 b.to_s <=> a.to_s elsif s1 -1 elsif s2 1 else s = a.to_s.length - b.to_s.length s == 0 ? a.to_s <=> b.to_s : s end end.each do |var, opts| c = ( max += 1 ).chr(engine.encoding) sp = if opts.is_a? Hash pat = opts.delete :pattern raise Error, "symbol #{var} requires a pattern" unless pat || var.is_a?(Regexp) pat ||= var.to_s SymbolPattern.new engine, c, var, pat, **opts elsif opts.is_a? String SymbolPattern.new engine, c, var, opts elsif var.is_a?(Regexp) && opts.nil? SymbolPattern.new engine, c, var, nil else raise Error, "symbol #{var} requires a pattern" end ar << sp end end if engine.bound if engine.left_bound c = ( max += 1 ).chr(engine.encoding) @left = SymbolPattern.new engine, c, c, engine.left_bound @specials << @left end if engine.right_bound c = ( max += 1 ).chr(engine.encoding) @right = SymbolPattern.new engine, c, c, engine.right_bound @specials << @right end end @special_map = Hash[@specials.map{ |s| [ s.char, s ] }] end
Public Instance Methods
[](s)
click to toggle source
maps a symbol character back to the symbol object
# File lib/list_matcher.rb, line 403 def [](s) special_map[s] end
normalize()
click to toggle source
reduce the list to a version ready for pattern generation
# File lib/list_matcher.rb, line 408 def normalize rx = if specials.empty? /(?!)/ else Regexp.new '(' + specials.map(&:var).map(&:to_s).join('|') + ')' end list = self.list.uniq.map do |w| parts = w.split(rx).select{ |p| p.length > 0 } e = parts.size - 1 (0..e).map do |i| p = parts[i] if rx === p p = specials.detect{ |sp| sp.var === p } if engine.bound s = p if i == 0 && engine.left_bound && engine.word_test === p.left s = "#{left}#{s}" end if i == e && engine.right_bound && engine.word_test === p.right s = "#{s}#{right}" end p = s end else p = p.downcase if engine.case_insensitive if engine.bound s = p if i == 0 && engine.left_bound && engine.word_test === p[0] s = "#{left}#{s}" end if i == e && engine.right_bound && engine.word_test === p[-1] s = "#{s}#{right}" end p = s end end p end.join end.uniq.sort list end
verify()
click to toggle source
confirm that all special patterns are legitimate regexen
# File lib/list_matcher.rb, line 392 def verify specials.each do |s| begin Regexp.new s.pat rescue raise Error, "the symbol #{s.symbol} has an ill-formed pattern: #{s.pat}" end end end