maca-eventual 0.4.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: ""