Class: Hijiri::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/hijiri/parser.rb

Constant Summary collapse

SUB_LIST =
{
    /さらいねん|再来年|明後年/     => "#{2.month.from_now.year}",
    /らいねん|来年|明年|翌年/      => "#{1.month.from_now.year}",
    /らいげつ|来月/                => "#{1.month.from_now.month}",
    /あした|あす|明日/             => "#{1.day.from_now.day}",
    /あさって|みょうごにち|明後日/ => "#{2.days.from_now.day}",
    /しあさって|明々後日/          => "#{3.days.from_now.day}"
}
CONJ_WORDS =
%w().join('|')
TIMER_WORDS =
%w(あとに  経った たった 経過 けいか).join('|')

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(text) ⇒ Parser

Returns a new instance of Parser.



20
21
22
23
24
25
# File 'lib/hijiri/parser.rb', line 20

def initialize(text)
  @original_text = text.dup
  @text = text.dup
  @results = []
  @current = Time.now
end

Instance Attribute Details

#currentObject (readonly)

Returns the value of attribute current.



7
8
9
# File 'lib/hijiri/parser.rb', line 7

def current
  @current
end

#original_textObject (readonly)

Returns the value of attribute original_text.



7
8
9
# File 'lib/hijiri/parser.rb', line 7

def original_text
  @original_text
end

#resultsObject (readonly)

Returns the value of attribute results.



7
8
9
# File 'lib/hijiri/parser.rb', line 7

def results
  @results
end

#textObject (readonly)

Returns the value of attribute text.



7
8
9
# File 'lib/hijiri/parser.rb', line 7

def text
  @text
end

Instance Method Details

#conv_time(y, m, d, h, n, s) ⇒ Object



133
134
135
136
137
138
139
140
141
142
# File 'lib/hijiri/parser.rb', line 133

def conv_time(y,m,d,h,n,s)
  Time.local(
    y.presence || @current.year,
    m.presence || @current.month,
    d.presence || @current.day,
    h.presence || @current.hour,
    n.presence || @current.min,
    s.presence || @current.sec
  )
end

#normalizeObject



27
28
29
30
31
32
33
# File 'lib/hijiri/parser.rb', line 27

def normalize
  %w(         ).each_with_index do |str, num|
    @text.gsub!(str, num.to_s)
  end
  SUB_LIST.each { |key, value| @text.gsub!(key, value) }
  @text
end

#parseObject



148
149
150
151
152
153
154
# File 'lib/hijiri/parser.rb', line 148

def parse
  normalize
  remove_conj
  pluck
  scan
  self
end

#pluckObject



39
40
41
42
43
44
45
# File 'lib/hijiri/parser.rb', line 39

def pluck
  words = @text
    .scan(/(?:(?:[\d]+年)?(?:[\d]+月)?(?:[\d]+日)?(?:[\d]+時間?)?(?:[\d]+分)?(?:[\d]+秒)?(?:#{TIMER_WORDS})?)+/)
    .delete_if(&:blank?)
    .delete_if{ |word| !word.match(/\d/) }
  @results = words.map{ |result| Hashie::Mash.new(word: result) }
end

#point_time(y, m, d, h, n, s) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/hijiri/parser.rb', line 103

def point_time(y,m,d,h,n,s)
  if m && y.nil? && conv_time(y,m,d,h,n,s) < @current
    y = @current.next_year.year
  end
  if d && m.nil? && y.nil? && conv_time(y,m,d,h,n,s) < @current
    m = @current.next_month.month
    return point_time(y,m,d,h,n,s)
  end
  if h && d.nil? && m.nil? && y.nil? && conv_time(y,m,d,h,n,s) < @current
    d = @current.day + 1
    if d > @current.end_of_month.day
      m = @current.next_month.month
      d = 1
    end
    return point_time(y,m,d,h,n,s)
  end
  if n && h.nil? && d.nil? && m.nil? && y.nil? && conv_time(y,m,d,h,n,s) < @current
    h = @current.hour + 1
    h = 1 if h > 24
    return point_time(y,m,d,h,n,s)
  end
  if s && n.nil? && h.nil? && d.nil? && m.nil? && y.nil? && conv_time(y,m,d,h,n,s) < @current
    n = @current.min + 1
    n = 1 if n > 60
    return point_time(y,m,d,h,n,s)
  end

  conv_time(y,m,d,h,n,s)
end

#remove_conjObject



35
36
37
# File 'lib/hijiri/parser.rb', line 35

def remove_conj
  @text.gsub!(/#{CONJ_WORDS}/, '')
end

#scanObject



47
48
49
# File 'lib/hijiri/parser.rb', line 47

def scan
  @results.map{ |result| result.datetime = scan_word(result[:word]) }
end

#scan_word(word) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/hijiri/parser.rb', line 51

def scan_word(word)
  y = word.scan(/([\d]+)年(#{TIMER_WORDS})?/).first
  m = word.scan(/([\d]+)月(#{TIMER_WORDS})?/).first
  d = word.scan(/([\d]+)日(#{TIMER_WORDS})?/).first
  h = word.scan(/([\d]+)時(#{TIMER_WORDS})?/).first
  n = word.scan(/([\d]+)分(#{TIMER_WORDS})?/).first
  s = word.scan(/([\d]+)秒(#{TIMER_WORDS})?/).first

  options = {}
  if word.match(/(?:#{TIMER_WORDS})((?:[\d]+月)?(?:[\d]+日)?)?/)
    point_word = $1
    options[:month] = $1 if point_word.match(/([\d]+)月/)
    options[:day] = $1 if point_word.match(/([\d]+)日/)
  end

  if timer?(word)
    timer_time(y.try(:first),m.try(:first),d.try(:first),h.try(:first),n.try(:first),s.try(:first),options)
  else
    point_time(y.try(:first),m.try(:first),d.try(:first),h.try(:first),n.try(:first),s.try(:first))
  end
end

#timer?(word) ⇒ Boolean

Returns:

  • (Boolean)


144
145
146
# File 'lib/hijiri/parser.rb', line 144

def timer?(word)
  !!word.match(/#{TIMER_WORDS}/)
end

#timer_time(y, m, d, h, n, s, options = {}) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/hijiri/parser.rb', line 73

def timer_time(y,m,d,h,n,s,options={})
  if options[:month]
    m = 0
    unless options[:day]
      options[:day] = 1
    end
  end

  d = 0 if options[:day]

  pass = 0
  pass += y.to_i.years.to_i
  pass += m.to_i.month.to_i
  pass += d.to_i.days.to_i
  pass += h.to_i.hours.to_i
  pass += n.to_i.minutes.to_i
  pass += s.to_i.seconds.to_i
  res = @current + pass

  if options.present?
    Time.local(
      res.year,
      options[:month].presence || res.month,
      options[:day].presence || res.day
    )
  else
    res
  end
end