Class: Goodcheck::Pattern::Token

Inherits:
Object
  • Object
show all
Defined in:
lib/goodcheck/pattern.rb

Defined Under Namespace

Classes: VarPattern

Constant Summary collapse

%r{
  (?: ((?:ed2k|ftp|http|https|irc|mailto|news|gopher|nntp|telnet|webcal|xmpp|callto|feed|svn|urn|aim|rsync|tag|ssh|sftp|rtsp|afs|file):)// | www\. )
  [^\s<\u00A0")]+
}ix
AUTO_EMAIL_LOCAL_RE =
/[\w.!#\$%&'*\/=?^`{|}~+-]/
AUTO_EMAIL_RE =
/(?<!#{AUTO_EMAIL_LOCAL_RE})[\w.!#\$%+-]\.?#{AUTO_EMAIL_LOCAL_RE}*@[\w-]+(?:\.[\w-]+)+/
@@TYPES =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source:, variables:, case_sensitive:) ⇒ Token

Returns a new instance of Token.



42
43
44
45
46
# File 'lib/goodcheck/pattern.rb', line 42

def initialize(source:, variables:, case_sensitive:)
  @source = source
  @variables = variables
  @case_sensitive = case_sensitive
end

Instance Attribute Details

#case_sensitive ⇒ Object (readonly)

Returns the value of attribute case_sensitive.



40
41
42
# File 'lib/goodcheck/pattern.rb', line 40

def case_sensitive
  @case_sensitive
end

#source ⇒ Object (readonly)

Returns the value of attribute source.



40
41
42
# File 'lib/goodcheck/pattern.rb', line 40

def source
  @source
end

#variables ⇒ Object (readonly)

Returns the value of attribute variables.



40
41
42
# File 'lib/goodcheck/pattern.rb', line 40

def variables
  @variables
end

Class Method Details

.compile_tokens(source, variables, case_sensitive:) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/goodcheck/pattern.rb', line 172

def self.compile_tokens(source, variables, case_sensitive:)
  tokens = []
  s = StringScanner.new(source)

  until s.eos?
    case
    when s.scan(/\${(?<name>[a-zA-Z_]\w*)(?::(?<type>#{::Regexp.union(*@@TYPES.keys.map(&:to_s))}))?}/)
      name = s[:name].to_sym
      type = s[:type] && s[:type].to_sym

      if variables.key?(name)
        variables[name].type = type
        regexp = regexp_for_type(name: name, type: type).to_s
        if tokens.empty? && (type == :word || type == :identifier)
          regexp = /\b#{regexp.to_s}/
        end
        tokens << regexp.to_s
      else
        tokens << ::Regexp.escape("${")
        tokens << ::Regexp.escape(name.to_s)
        tokens << ::Regexp.escape("}")
      end
    when s.scan(/\(|\)|\{|\}|\[|\]|\<|\>/)
      tokens << ::Regexp.escape(s.matched)
    when s.scan(/\s+/)
      tokens << '\s+'
    when s.scan(/\w+|[\p{L}&&\p{^ASCII}]+/)
      tokens << ::Regexp.escape(s.matched)
    when s.scan(%r{[!"#%&'=\-^~¥\\|`@*:+;/?.,]+})
      tokens << ::Regexp.escape(s.matched.rstrip)
    when s.scan(/./)
      tokens << ::Regexp.escape(s.matched)
    end
  end

  if tokens.first =~ /\A\p{L}/
    tokens.first.prepend('\b')
  end

  if tokens.last =~ /\p{L}\Z/
    tokens.last << '\b'
  end

  options = ::Regexp::MULTILINE
  options |= ::Regexp::IGNORECASE unless case_sensitive

  ::Regexp.new(tokens.join('\s*').gsub(/\\s\*(\\s\+\\s\*)+/, '\s+'), options)
end

.regexp_for_type(name:, type:) ⇒ Object



165
166
167
168
169
170
# File 'lib/goodcheck/pattern.rb', line 165

def self.regexp_for_type(name:, type:)
  ty = type || :word
  if @@TYPES.key?(ty)
    @@TYPES[ty][name]
  end
end

Instance Method Details

#regexp ⇒ Object



48
49
50
# File 'lib/goodcheck/pattern.rb', line 48

def regexp
  @regexp ||= Token.compile_tokens(source, variables, case_sensitive: case_sensitive)
end

#test_variables(match) ⇒ Object



97
98
99
100
101
102
# File 'lib/goodcheck/pattern.rb', line 97

def test_variables(match)
  variables.all? do |name, var|
    str = match[name]
    str && var.test(str)
  end
end