maca-eventual 0.4.3 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  == DESCRIPCIÓN:
6
6
 
7
- Reconocimiento de fechas y periodos en lenguaje natural.
7
+ Reconocimiento de fechas y periodos en lenguaje natural. Útil para crear interfaces de usuario basadas en texto.
8
8
 
9
9
  == SINOPSIS:
10
10
 
@@ -49,9 +49,17 @@ Para activar el parche:
49
49
  => [#<Date: 4909975/2,0,2299161>, #<Date: 4909977/2,0,2299161>, #<Date: 4909979/2,0,2299161>]
50
50
 
51
51
 
52
- == ETC:
52
+ Si se pasa un bloque se puede especificar si se desea usar el texto que sigue a la definición de fechas mediante pasando la opción _use_trailing_ => _true_:
53
53
 
54
- * No estoy seguro de que Iconv funcione en windows
54
+ str = "1 de enero del 2009\nSede:El tercer lugar\n2 de enero del 2009\nSede:El tercer lugar"
55
+ Eventual.event_parse( str, :use_trailing => true ) do |dia, texto_extra|
56
+ [dia.to_s, texto_extra]
57
+ end
58
+ => [["2009-01-01T00:00:00+00:00", "Sede:El tercer lugar"], ["2009-01-02T00:00:00+00:00", "Sede:El tercer lugar"]]
59
+
60
+ == TODO:
61
+
62
+ * No estoy seguro de que Iconv funcione en windows, lo arreglaré pronto
55
63
 
56
64
  Formatos a reconocer
57
65
 
data/eventual.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{eventual}
5
- s.version = "0.4.3"
5
+ s.version = "0.4.5"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Macario Ortega"]
data/lib/eventual.rb CHANGED
@@ -1,60 +1,63 @@
1
1
  require 'date'
2
2
  require 'iconv'
3
+ require 'strscan'
3
4
 
4
5
  $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
5
6
 
6
7
 
7
8
  module Eventual
8
- VERSION = '0.4.3'
9
+ VERSION = '0.4.5'
9
10
  extend self
10
11
 
11
12
  WDAY_LIST = %w(domingo lunes martes miercoles jueves viernes sabado)
12
13
  MNAMES = %w(enero febrero marzo abril mayo junio julio agosto septiembre octubre noviembre diciembre).unshift(nil)
13
-
14
- DAY_LIST = %r{
15
- (
16
- (?:\d{1,2}(?-mix: |, | y ))+ # Lista de número de día
17
- )
18
- de\s(#{ MNAMES.compact.join('|') }) # Lista de mes
19
- (?-mix: (?:del|de) (\d{4}))? # Año opcional
20
- (?-mix: a las (.*))? # Hora opcional
21
- }ixo
22
14
 
23
-
24
- DAY_PERIOD = %r{
25
- (
26
- (?: # Dia de la semana opcional
27
- (?:#{ WDAY_LIST.join('|') }) # Nombre del día
28
- (?-mix: |, | y ) # Concatenador
29
- )*
30
- )
31
- (?-mix:del (\d{1,2}))\s # Comienzo del periodo
32
- (?:de\s # Mes opcional
33
- (#{ MNAMES.compact.join('|') }) # Nombre del mes
34
- (?-mix: (?:del|de) (\d{4}))? # Año opcional
35
- \s)?
36
- (?-mix:al (\d{1,2}) de (#{ MNAMES.compact.join('|') })) # Mes requerido
37
- (?-mix: (?:del|de) (\d{4}))? # Año opcional
38
- (?-mix: a las (.*))? # Hora opcional
39
- }ixo
40
-
41
-
15
+ year = /(?: (?:del|de))? (\d{4})/
16
+ horarios = / a las (.*)/
17
+ DAY_LIST = %r{
18
+ (
19
+ (?:
20
+ \d{1,2}
21
+ (?-mix: |, | y )
22
+ )+ # Lista de número de día
23
+ )
24
+ de\s(#{ MNAMES.compact.join('|') }) # Lista de mes
25
+ (?:#{ year })? # Año opcional
26
+ (#{ horarios })? # Hora opcional
27
+ }ixo
28
+
29
+ DAY_PERIOD = %r{
30
+ (
31
+ (?: # Dia de la semana opcional
32
+ (?:#{ WDAY_LIST.join('|') }) # Nombre del día
33
+ (?-mix: |, | y ) # Concatenador
34
+ )*
35
+ )
36
+ (?-mix:del (\d{1,2}))\s # Comienzo del periodo
37
+ (?:de\s # Mes opcional
38
+ (#{ MNAMES.compact.join('|') }) # Nombre del mes
39
+ (?:#{ year })? # Año opcional
40
+ \s)?
41
+ (?-mix:al (\d{1,2}) de (#{ MNAMES.compact.join('|') })) # Mes requerido
42
+ (?:#{ year })? # Año opcional
43
+ (#{ horarios })? # Hora opcional
44
+ }ixo
42
45
 
43
- def event_parse string, parser = nil, &block
44
- parser ||= ( self == Eventual ? DateTime : self )
45
- string = Iconv.iconv("ASCII//IGNORE//TRANSLIT", "UTF-8", string).join.gsub(/'/, '')
46
- results = []
47
-
48
- string = string
46
+ def event_parse string, opts = {}, &block
47
+ parser = opts.delete(:parser) || (self == Eventual ? DateTime : self)
48
+ use_trailing = opts.delete(:use_trailing)
49
+ string = Iconv.iconv("ASCII//IGNORE//TRANSLIT", "UTF-8", string).join.gsub(/'/, '')
50
+ results = []
51
+ scanner = StringScanner.new string
49
52
 
50
- while true
51
- case string
53
+ until scanner.eos?
54
+ case match = scanner.scan(/.*?(?:#{DAY_LIST}|#{DAY_PERIOD})/m)
52
55
 
53
56
  when DAY_PERIOD
54
57
  wdays, first_day, first_month, first_year, last_day, last_month, last_year, times = $1, $2, $3, $4, $5, $6, $7, $8
55
58
  match = $&
56
- wdays = wdays.scan( Regexp.new( WDAY_LIST.join('|') ) ).collect{ |d| WDAY_LIST.index d }
57
- last_year ||= string.match(/\d{4,4}/) ? $& : Date.today.year
59
+ wdays = wdays.scan( Regexp.new(WDAY_LIST.join('|')) ).collect{ |d| WDAY_LIST.index d }
60
+ last_year ||= string.match(/\d{4}/) ? $& : Date.today.year
58
61
  first_year ||= last_year
59
62
  first_month ||= last_month
60
63
  last_month = MNAMES.index last_month
@@ -70,22 +73,20 @@ module Eventual
70
73
  end
71
74
 
72
75
  when DAY_LIST
73
- days, month, year, times = $1, MNAMES.index( $2 ), $3, $4
76
+ days, month, year, times = $1, MNAMES.index($2), $3, $4
74
77
  match = $&
75
78
  days = days.scan(/\d{1,2}/)
76
- year ||= string.match(/\d{4,4}/) ? $& : Date.today.year
79
+ year ||= string.match(/\d{4}/) ? $& : Date.today.year
77
80
  make_days = lambda do |hour, minute|
78
81
  days.map do |day|
79
82
  make_day parser, year, month, day, hour, minute
80
83
  end
81
84
  end
82
-
83
85
  else
84
86
  break
85
87
  end
86
-
87
- string.gsub!( match.to_s, '' )
88
88
 
89
+ extra = scanner.scan(/.*?(?=#{DAY_LIST}|#{DAY_PERIOD}|\n{2}|\z)/m)
89
90
  results +=
90
91
  if times
91
92
  times.scan( /(\d{2}):(\d{2})/ ).map do |hour, minute|
@@ -95,16 +96,21 @@ module Eventual
95
96
  make_days.call nil, nil
96
97
  end
97
98
  end
98
-
99
+
100
+ raise ArgumentError.new( 'El formato de las fechas parece ser incorrecto' ) if results.empty?
99
101
  results.uniq!
100
102
  results.sort!
101
- raise ArgumentError.new( 'El formato de las fechas parece ser incorrecto' ) if results.empty?
102
- results.map!{ |day| yield( day ) } if block_given?
103
+
104
+ results.map! do |day|
105
+ if use_trailing
106
+ yield day, extra.to_s.gsub(/^[\n|.|,]*/, '')
107
+ else
108
+ yield day
109
+ end
110
+ end if block_given?
103
111
 
104
112
  results
105
113
  end
106
-
107
-
108
114
 
109
115
  protected
110
116
  def make_day *args
@@ -115,6 +121,5 @@ module Eventual
115
121
  maker.civil *args.compact.collect{ |a| a.to_i }
116
122
  end
117
123
  end
118
-
119
124
  end
120
125
 
@@ -61,7 +61,7 @@ describe 'event parsing' do
61
61
  r = ( DateTime.parse('2008-1-1T16:00')..DateTime.parse('2008-12-31T16:00') ).reject{ |day| not [2,4].include?(day.wday) }
62
62
  e.should map_times( *r )
63
63
  end
64
-
64
+
65
65
  it "should parse a long period" do
66
66
  e = Eventual.event_parse( 'martes y jueves del 1 de enero del 2000 al 31 de diciembre del 2010' )
67
67
  r = (DateTime.parse('2000-1-1T00:00')..DateTime.parse('2010-12-31T00:00') ).reject{ |day| not [2,4].include?(day.wday) }
@@ -84,7 +84,36 @@ describe 'event parsing' do
84
84
  end
85
85
 
86
86
  it "should event_parse period spanning more than one month" do
87
- Eventual.event_parse( '1 de enero, del 29 de enero al 3 de febrero, y 2 de febrero del 2008' ).should map_times( '2008-1-1', '2008-1-29', '2008-1-30', '2008-1-31', '2008-2-1', '2008-2-2', '2008-2-3' )
87
+ Eventual.event_parse( '1 de enero, del 29 de enero al 3 de febrero y 2 de febrero del 2008' ).should map_times( '2008-1-1', '2008-1-29', '2008-1-30', '2008-1-31', '2008-2-1', '2008-2-2', '2008-2-3' )
88
+ end
89
+
90
+ it "should event_parse a several dates separated by \\n" do |d, extra|
91
+ Eventual.event_parse( "1 de enero del 2009\n2 de enero del 2009" ) do |d|
92
+ d.to_s
93
+ end.should == ["2009-01-01T00:00:00+00:00", "2009-01-02T00:00:00+00:00"]
94
+ end
95
+
96
+ describe 'With extra data' do
97
+ it "should event_parse one day with one time" do
98
+ Eventual.event_parse( "1 de enero del 2009 a las 16:00 horas\nSede:El tercer lugar\nCupo: limitado", :use_trailing => true ) do |day, extra|
99
+ day.to_s.should == "2009-01-01T16:00:00+00:00"
100
+ extra.should == "Sede:El tercer lugar\nCupo: limitado"
101
+ end
102
+ end
103
+
104
+ it "should event_parse a period with block" do
105
+ Eventual.event_parse( "del 5 al 7 de junio 2009\nSede:El tercer lugar\nCupo: limitado", :use_trailing => true ) do |d, extra|
106
+ extra.should == "Sede:El tercer lugar\nCupo: limitado"
107
+ Eventual::WDAY_LIST[ d.wday ]
108
+ end.should == ['viernes', 'sabado', 'domingo']
109
+ end
110
+
111
+ it "should event_parse a several dates" do |d, extra|
112
+ Eventual.event_parse( "1 de enero del 2009\nSede:El tercer lugar\nCupo: limitado\n2 de enero del 2009\nSede:El tercer lugar\nCupo: limitado", :use_trailing => true ) do |d, extra|
113
+ extra.should == "Sede:El tercer lugar\nCupo: limitado"
114
+ d.to_s
115
+ end.should == ["2009-01-01T00:00:00+00:00", "2009-01-02T00:00:00+00:00"]
116
+ end
88
117
  end
89
118
 
90
119
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maca-eventual
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Macario Ortega
@@ -47,6 +47,7 @@ files:
47
47
  - eventual.gemspec
48
48
  has_rdoc: true
49
49
  homepage: http://github.com/maca/eventual
50
+ licenses:
50
51
  post_install_message:
51
52
  rdoc_options:
52
53
  - --main
@@ -68,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
69
  requirements: []
69
70
 
70
71
  rubyforge_project: eventual
71
- rubygems_version: 1.2.0
72
+ rubygems_version: 1.3.5
72
73
  signing_key:
73
74
  specification_version: 2
74
75
  summary: ""