happy_phone_number 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,15 +3,24 @@ Happy Phone Number [![Build Status](https://travis-ci.org/lkdjiin/happy_phone_nu
3
3
 
4
4
  Description
5
5
  ----------------------
6
- A rails plugin to happily format phone numbers.
7
6
 
8
- **Early stage. Work in progress.**
7
+ *Happy Phone Number* provides easy methods to format phone
8
+ numbers from your Rails models. Virtually any country specific
9
+ format or convention could be supported, including national and international
10
+ format. For the not (yet) supported countries, a general method
11
+ using a simple mask is also provided.
9
12
 
10
13
  Overview
11
14
  -----------------------
12
15
 
13
- Let's say you have a `Contact` model with a `phone` attribute. The phone number
14
- **must be save** without spaces, or hyphen, or dots...
16
+ ### Prerequisite
17
+
18
+ * Phone number **must be save** with digits only. So, without spaces, hyphens,
19
+ or dots. Just digits.
20
+
21
+ ### Demonstration
22
+
23
+ Let's say you have a `Contact` model with a `phone` attribute.
15
24
 
16
25
  To display the phone number you could do this:
17
26
 
@@ -30,7 +39,7 @@ Or in uppercase if you prefer:
30
39
 
31
40
  If you want an international format:
32
41
 
33
- <%= @contact.happy_phone(:international) %>
42
+ <%= @contact.happy_inter_phone(:fr) %>
34
43
  #=> "+33 1 23 45 67 89"
35
44
 
36
45
  What if you want dots as separator?
@@ -49,6 +58,29 @@ and `mobile`, or maybe `portable`?
49
58
  #=> "33 33 33 33 33"
50
59
  ...
51
60
 
61
+ Now, imagine you live in Belgium, where phone numbers could have 2 formats:
62
+
63
+ <%= @contact.happy_phone(:be) %>
64
+ #=> "03 111 22 33"
65
+
66
+ <%= @contact.happy_phone2(:be) %>
67
+ #=> "063 11 22 33"
68
+
69
+ <%= @contact.happy_inter_phone(:be) %>
70
+ #=> "+32 3 111 22 33"
71
+
72
+ <%= @contact.happy_inter_phone2(:be) %>
73
+ #=> "+32 63 11 22 33"
74
+
75
+ And if *Happy Phone Number* don't know your country, you could use a
76
+ **mask formatting**:
77
+
78
+ <%= @contact.happy_phone("#### ###-###") %>
79
+ #=> "0123 456-789"
80
+
81
+ ### Caveats
82
+
83
+ *Mask formatting* doesn't work for international phone number format.
52
84
 
53
85
  Install
54
86
  -------------------------
@@ -72,12 +104,80 @@ Now, in your views, you can use:
72
104
 
73
105
  happy_phone(:fr)
74
106
  happy_fax(:fr)
107
+ ...
108
+
109
+ Supported Countries
110
+ --------------------------
111
+
112
+ <table>
113
+ <tr>
114
+ <th>Name</th>
115
+ <th>Symbol</th>
116
+ </tr>
117
+ <tr>
118
+ <td>Belgium</td>
119
+ <td>:be</td>
120
+ </tr>
121
+ <tr>
122
+ <td>Denmark</td>
123
+ <td>:dk</td>
124
+ </tr>
125
+ <tr>
126
+ <td>France</td>
127
+ <td>:fr</td>
128
+ </tr>
129
+ <tr>
130
+ <td>Iceland</td>
131
+ <td>:is</td>
132
+ </tr>
133
+ </table>
75
134
 
76
135
  Dependencies
77
136
  --------------------------
78
137
 
79
- ruby >= 1.9.2
80
- rails >= 3.2
138
+ * ruby >= 1.9.2
139
+ * rails >= 3.2
140
+
141
+ Contributing
142
+ -------------------------
143
+
144
+ *I don't know much about format and convention for every possible country.
145
+ Feel free to send me documentation for the phone number formatting and
146
+ convention for your country. Or contribute to the code by adding any
147
+ missing formatter.*
148
+
149
+ 1. Fork it
150
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
151
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
152
+ 4. Push to the branch (`git push origin my-new-feature`)
153
+ 5. Create new Pull Request
154
+
155
+ ### How to add a formatter for your country
156
+
157
+ Name the file as follow:
158
+
159
+ aa_format.rb
160
+
161
+ where "aa" is the ISO code of the country.
162
+ See [ISO country codes] [1].
163
+
164
+ Put this file in the lib/happy_phone_number/ folder. Then follow the structure of
165
+ an existed formatter:
166
+
167
+ * fr_format.rb is a good starting point
168
+ * dk_format.rb is the simplest one
169
+ * be_format.rb is a little more complex
170
+
171
+ Feel free to ask for help if you have any troubles.
172
+
173
+
174
+ ### There is many other ways to contibute to FIXME
175
+
176
+ 1. Report any bug
177
+ 2. Give me ideas
178
+ 3. Correct my poor english syntax
179
+ 4. Blog about *Happy Phone Number*
180
+ 5. Tell *Happy Phone Number* to your friends and colleagues
81
181
 
82
182
  License
83
183
  --------------------------
@@ -89,4 +189,6 @@ Questions and/or Comments
89
189
  --------------------------
90
190
 
91
191
  Feel free to email [Xavier Nayrac](mailto:xavier.nayrac@gmail.com)
92
- with any questions.
192
+ with any questions, or contact me on [twitter](https://twitter.com/lkdjiin).
193
+
194
+ [1]: http://en.wikipedia.org/wiki/ISO_3166-1 "ISO country codes on wikipedia"
@@ -1,24 +1,69 @@
1
+ require 'happy_phone_number/formatter'
2
+ require 'happy_phone_number/mask'
3
+ require 'happy_phone_number/base_format'
4
+
5
+ # Public: Happy Phone Number provides easy methods to format phone
6
+ # numbers from your Rails models. Virtually any country specific
7
+ # format could be supported, including national and international
8
+ # format. For the not (yet) supported countries, a general method
9
+ # using a simple mask is also provided.
10
+ #
11
+ # Examples
12
+ #
13
+ # class Contact < ActiveRecord::Base
14
+ # attr_accessible :email, :name, :phone, :fax
15
+ # happy_phone_number
16
+ # end
17
+ #
18
+ # <%= @contact.happy_phone(:fr) %>
19
+ # # => "01 23 45 67 89"
20
+ #
21
+ # <%= @contact.happy_inter_phone(:fr) %>
22
+ # # => "+33 1 23 45 67 89"
23
+ #
24
+ # <%= @contact.happy_phone(:be) %>
25
+ # # => "03 111 22 33"
26
+ #
27
+ # <%= @contact.happy_phone("#### ###-###") %>
28
+ # # => "0123 456-789"
1
29
  module HappyPhoneNumber
2
30
  extend ActiveSupport::Concern
3
31
 
4
32
  included do
5
-
6
33
  end
7
34
 
8
35
  module ClassMethods
9
36
  def happy_phone_number(options = {})
10
- # your code will go here
11
37
  end
12
38
  end
13
39
 
40
+ # Public: Format a phone number from a model.
41
+ #
42
+ # args[0] - Either a Symbol country or a String formatting mask.
43
+ # A country symbol must be in ISO 3166-1-alpha-2 format,
44
+ # both lower and upper case are valids.
45
+ # block - Not used.
46
+ #
47
+ # Signature
48
+ #
49
+ # happy_<field>(country_or_mask, separator)
50
+ # happy_inter_<field>(country_or_mask, separator)
51
+ #
52
+ # field - A field name of the model that holds a phone number as a
53
+ # string.
54
+ #
55
+ # Returns the String formatted phone number.
14
56
  def method_missing(meth, *args, &block)
15
- if meth.to_s =~ /^happy_(.+)$/
16
- run_happy($1, *args, &block)
57
+ if meth.to_s =~ /^happy_inter_(.+)$/
58
+ happy_format(:international, $1, *args)
59
+ elsif meth.to_s =~ /^happy_(.+)$/
60
+ happy_format(:national, $1, *args)
17
61
  else
18
62
  super
19
63
  end
20
64
  end
21
65
 
66
+ # Public: Make the happy_* methods respond to respond_to?.
22
67
  def respond_to?(meth, include_private = false)
23
68
  if meth.to_s =~ /^happy_.*$/
24
69
  true
@@ -29,16 +74,16 @@ module HappyPhoneNumber
29
74
 
30
75
  private
31
76
 
32
- def run_happy(meth, *args, &block)
33
- type = args[0]
34
- separator = args[1] || ' '
35
- if (type == :fr) || (type == :FR)
36
- send(meth.to_sym).unpack('A2A2A2A2A2').join(separator)
37
- elsif type == :international
38
- "+33#{send(meth.to_sym)[1, 9]}".unpack('A3A1A2A2A2A2').join(separator)
39
- else
40
- send(meth.to_sym)
41
- end
77
+ # Launch the formatting process.
78
+ #
79
+ # type - Either :national or :international.
80
+ # meth - The String field from the model.
81
+ # args - Argument(s) passed to the formatting method, like a country,
82
+ # a mask string, the separator.
83
+ #
84
+ # Returns the String formatted phone number.
85
+ def happy_format(type, meth, *args)
86
+ Formatter.new(send(meth.to_sym), type, args[0], args[1]).format
42
87
  end
43
88
 
44
89
  end
@@ -0,0 +1,67 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module HappyPhoneNumber
4
+
5
+ # Internal: Base class for specific country formatter.
6
+ class BaseFormat
7
+
8
+ # Internal: Initialize a new base formatter.
9
+ #
10
+ # phone - A String phone number to format.
11
+ # type - Either :national or :international.
12
+ # separator - A String separator to put into each groups of digit.
13
+ def initialize phone, type, separator
14
+ @phone = phone
15
+ @type = type
16
+ @separator = separator
17
+ end
18
+
19
+ private
20
+
21
+ # Internal: Format the phone number using specified grouping.
22
+ #
23
+ # groups - A String set of digits.
24
+ #
25
+ # Examples
26
+ #
27
+ # @phone = "123456"
28
+ # make_happy "222"
29
+ # # => "12 34 56"
30
+ #
31
+ # @phone = "+33123456789"
32
+ # @separator = "."
33
+ # make_happy "312222"
34
+ # # => "+33.1.23.45.67.89"
35
+ #
36
+ # Returns the String formatted phone number.
37
+ def make_happy groups
38
+ unpack_string = "A#{groups.split('').join('A')}"
39
+ @phone.unpack(unpack_string).join(@separator)
40
+ end
41
+
42
+ # Internal: Internationalize a phone number with a given prefix.
43
+ #
44
+ # prefix - A String.
45
+ # block - Optional, a block to call before we add the prefix.
46
+ #
47
+ # Examples
48
+ #
49
+ # puts @phone
50
+ # # => "12345678"
51
+ # internationalize_with("45")
52
+ # # => "+4512345678"
53
+ #
54
+ # puts @phone
55
+ # # => "0123456789"
56
+ # internationalize_with("33") { @phone.slice!(0) }
57
+ # # => "+33123456789"
58
+ #
59
+ # Returns nothing.
60
+ def internationalize_with prefix, &block
61
+ block.call if block
62
+ @phone = "+#{prefix}#{@phone}"
63
+ end
64
+
65
+ end
66
+ end
67
+
@@ -0,0 +1,38 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module HappyPhoneNumber
4
+
5
+ # Format for belgian phone numbers.
6
+ class BeFormat < BaseFormat
7
+
8
+ # Format the phone number given belgian convention.
9
+ #
10
+ # Returns the String formatted phone number.
11
+ def format
12
+ case @phone[0, 2]
13
+ when "02", "03", "04", "08", "09"
14
+ if @type == :national
15
+ make_happy '2322'
16
+ else
17
+ internationalize
18
+ make_happy '31322'
19
+ end
20
+ else
21
+ if @type == :national
22
+ make_happy '3222'
23
+ else
24
+ internationalize
25
+ make_happy '32222'
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def internationalize
33
+ internationalize_with('32') { @phone.slice!(0) }
34
+ end
35
+
36
+ end
37
+ end
38
+
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module HappyPhoneNumber
4
+
5
+ # Format phone numbers from Denmark.
6
+ class DkFormat < BaseFormat
7
+
8
+ # Format the phone number given danish convention.
9
+ #
10
+ # Returns the String formatted phone number.
11
+ def format
12
+ if @type == :national
13
+ make_happy '2222'
14
+ else
15
+ internationalize_with '45'
16
+ make_happy '32222'
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,81 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module HappyPhoneNumber
4
+
5
+ # Internal: A simple facade which call the real formatter.
6
+ class Formatter
7
+
8
+ # Internal: Initialize the formatter facade.
9
+ #
10
+ # phone - A String phone number to format.
11
+ # type - Either :national or :international.
12
+ # country_or_mask - If it's a country, must be a two-letters Symbol.
13
+ # If it's a String, it is considered as a mask.
14
+ # separator - Optional, a String to separate groups of digits
15
+ # the final result.
16
+ def initialize phone, type, country_or_mask, separator
17
+ @phone = phone
18
+ @type = type
19
+ @country_or_mask = country_or_mask
20
+ @separator = separator || ' '
21
+ end
22
+
23
+ # Internal: Call the real formatter.
24
+ #
25
+ # Returns the String formatted phone number.
26
+ def format
27
+ if @country_or_mask.class == String
28
+ use_mask
29
+ else
30
+ use_formatter
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ # Format phone using a mask.
37
+ #
38
+ # Returns the String formatted phone number.
39
+ def use_mask
40
+ Mask.new(@phone, @country_or_mask).format
41
+ end
42
+
43
+ # Format phone using a country formatter.
44
+ #
45
+ # Returns the String formatted phone number.
46
+ def use_formatter
47
+ begin
48
+ require "happy_phone_number/#{formatter_filename}"
49
+ HappyPhoneNumber.const_get(formatter_classname).new(
50
+ @phone, @type, @separator).format
51
+ rescue LoadError
52
+ return @phone
53
+ end
54
+ end
55
+
56
+ # Get the formatter classname.
57
+ #
58
+ # Examples
59
+ #
60
+ # @country_or_mask = :fr
61
+ # formatter_classname # => "FrFormat"
62
+ #
63
+ # Returns the String formatter classname.
64
+ def formatter_classname
65
+ "#{@country_or_mask.to_s.capitalize}Format"
66
+ end
67
+
68
+ # Get the formatter filename.
69
+ #
70
+ # Examples
71
+ #
72
+ # @country_or_mask = :fr
73
+ # formatter_classname # => "fr_format"
74
+ #
75
+ # Returns the String formatter filename.
76
+ def formatter_filename
77
+ "#{@country_or_mask.to_s.downcase}_format"
78
+ end
79
+ end
80
+ end
81
+
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module HappyPhoneNumber
4
+
5
+ # Format for french phone numbers.
6
+ class FrFormat < BaseFormat
7
+
8
+ # Format the phone number given french convention.
9
+ #
10
+ # Returns the String formatted phone number.
11
+ def format
12
+ if @type == :national
13
+ make_happy '22222'
14
+ else
15
+ internationalize_with('33') { @phone.slice!(0) }
16
+ make_happy '312222'
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module HappyPhoneNumber
4
+
5
+ # Format phone numbers from Iceland.
6
+ class IsFormat < BaseFormat
7
+
8
+ # Format the phone number given convention for Iceland.
9
+ #
10
+ # Returns the String formatted phone number.
11
+ def format
12
+ if @type == :national
13
+ make_happy '34'
14
+ else
15
+ internationalize_with '354'
16
+ make_happy '434'
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,85 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module HappyPhoneNumber
4
+
5
+ # Internal: Phone number formatting using a mask.
6
+ #
7
+ # Examples
8
+ #
9
+ # Mask.new("123456", "### ###").format
10
+ # # => "123 456"
11
+ #
12
+ # Mask.new("123456", "## ##-##").format
13
+ # # => "12 34-56"
14
+ #
15
+ # Mask.new("123456", "##.####").format
16
+ # # => "12.3456"
17
+ class Mask
18
+
19
+ # Internal: Initialize a new mask formatter.
20
+ #
21
+ # phone - A String phone number.
22
+ # mask - A String mask.
23
+ def initialize phone, mask
24
+ @phone = phone
25
+ @mask = mask
26
+ end
27
+
28
+ # Internal: Format the phone number. If the mask is too long for the
29
+ # phone number, it will be truncated (the mask). If the mask is too
30
+ # short, the returned phone number will be left untouched.
31
+ #
32
+ # Examples
33
+ #
34
+ # Mask.new("1234", "### ###").format
35
+ # # => "123 4"
36
+ #
37
+ # Mask.new("1234", "#").format
38
+ # # => "1234"
39
+ #
40
+ # Returns the String formatted phone number.
41
+ def format
42
+ return @phone if mask_too_short?
43
+ mask_array.map do |item|
44
+ if item == "#"
45
+ next_digit
46
+ else
47
+ item
48
+ end
49
+ end.join
50
+ end
51
+
52
+ private
53
+
54
+ # Check if the mask is too short for the phone number.
55
+ #
56
+ # Returns true or false.
57
+ def mask_too_short?
58
+ @mask.split('').select {|i| i == "#" }.size < @phone.size
59
+ end
60
+
61
+ # Split the mask into single characters.
62
+ #
63
+ # Returns an Array.
64
+ def mask_array
65
+ @mask.split('')
66
+ end
67
+
68
+ # Get the next digit of the phone number.
69
+ #
70
+ # Examples
71
+ #
72
+ # @phone = "123"
73
+ # next_digit
74
+ # # => "1"
75
+ # next_digit
76
+ # # => "2"
77
+ #
78
+ # Returns a String.
79
+ def next_digit
80
+ @phone.slice!(0)
81
+ end
82
+
83
+ end
84
+ end
85
+
@@ -1,3 +1,3 @@
1
1
  module HappyPhoneNumber
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: happy_phone_number
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-03 00:00:00.000000000 Z
12
+ date: 2013-05-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -59,14 +59,31 @@ dependencies:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
- description: Rails plugin to format phone number.
62
+ description: ! 'Happy Phone Number provides easy methods to format phone
63
+
64
+ numbers from your Rails models. Virtually any country specific
65
+
66
+ format could be supported, including national and international
67
+
68
+ format. For the not (yet) supported countries, a general method
69
+
70
+ using a simple mask is also provided.
71
+
72
+ '
63
73
  email:
64
74
  - xavier.nayrac@gmail.com
65
75
  executables: []
66
76
  extensions: []
67
77
  extra_rdoc_files: []
68
78
  files:
79
+ - lib/happy_phone_number/dk_format.rb
69
80
  - lib/happy_phone_number/version.rb
81
+ - lib/happy_phone_number/fr_format.rb
82
+ - lib/happy_phone_number/mask.rb
83
+ - lib/happy_phone_number/is_format.rb
84
+ - lib/happy_phone_number/be_format.rb
85
+ - lib/happy_phone_number/base_format.rb
86
+ - lib/happy_phone_number/formatter.rb
70
87
  - lib/tasks/happy_phone_number_tasks.rake
71
88
  - lib/happy_phone_number.rb
72
89
  - MIT-LICENSE