twemoji 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30d5595bf4c341a2f7b960d79941a08571184fb3
4
- data.tar.gz: 1ba40ad4ea3c925acbca7a7cdd7e3ba1bf3fa9b0
3
+ metadata.gz: 23f6e3897cb5f1b31ad0c451f43db2b9aaa0cc66
4
+ data.tar.gz: ebd4be4bf5d973818ee506f13fc9c4ec79d8ad39
5
5
  SHA512:
6
- metadata.gz: e3d2628da8e26b765f96944e8a93328cfebb747fae0c13fb88db09cf72c1fab1f0d36cb9e4a05c8e3c4f31ff56ee88bb05b0690f77a10da2b7c00ee8963b5e40
7
- data.tar.gz: 9bd3620246f497178f7f6f13997ee83834ee90b005a130a1a787e25cf4726be049700976c1588789d3efe1378fb87412f227a68d5b72f48246d9b035c345dfa4
6
+ metadata.gz: 595e24e32a9371f00baca715dbf793b04327dfda9ef66aae9bba22a5b70b7737ed07fdf6b2e3c4bca8c9f33332bbef0d9a4768cac5ec8c183adcec00fee0f721
7
+ data.tar.gz: 2ba21f666a4831af30563d3d9dd8b494947cf6c7a6969e4c4f8b0e54d8535c066e658ad4ea73abb493f7de6a0196143991ff9f2e22b3d1cb732d8bcd9402a229
@@ -0,0 +1,20 @@
1
+ language: ruby
2
+ sudo: false
3
+ bundler_args: --retry=3 --jobs=3
4
+
5
+ rvm:
6
+ - 2.0
7
+ - 2.1
8
+ - 2.2
9
+ - jruby
10
+ - jruby-19mode
11
+ - jruby-head
12
+ - ruby-head
13
+
14
+ matrix:
15
+ allow_failures:
16
+ - rvm: jruby
17
+ - rvm: jruby-19mode
18
+ - rvm: juby-head
19
+ - rvm: ruby-head
20
+ fast_finish: true
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ gemspec
6
6
  group :development do
7
7
  gem "rake"
8
8
  gem "bundler"
9
+ gem "pry"
9
10
  end
10
11
 
11
12
  group :test do
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # Twemoji
2
2
 
3
- Get imoji img by text.
3
+ [![Gem Version](http://img.shields.io/gem/v/twemoji.svg)][gem]
4
+ [![Build Status](https://travis-ci.org/jollygoodcode/twemoji.svg)][travis]
5
+
6
+ [gem]: https://rubygems.org/gems/twemoji
7
+ [travis]: https://travis-ci.org/jollygoodcode/twemoji
8
+
9
+ Twitter Emoji has a official JavaScript implementation of [twemoji](https://github.com/twitter/twemoji). This RubyGem Twemoji is a minimum implementation in Ruby, does not implement all its features.
4
10
 
5
11
  ## Installation
6
12
 
@@ -33,24 +39,24 @@ Or install it yourself as:
33
39
 
34
40
  ```ruby
35
41
  > Twemoji.find_by_code("1f60d")
36
- => "1f60d"
42
+ => ":heart_eyes:"
37
43
  ```
38
44
 
39
45
  #### `.find_by` text or code
40
46
 
41
47
  ```ruby
42
- > Twemoji.find_by(text: ':heart_eyes:')
48
+ > Twemoji.find_by(text: ":heart_eyes:")
43
49
  => 1f60d
44
50
 
45
- > Twemoji.find_by(code: '1f60d')
51
+ > Twemoji.find_by(code: "1f60d")
46
52
  => :heart_eyes:
47
53
  ```
48
54
 
49
55
  #### `.parse`
50
56
 
51
57
  ```ruby
52
- > Twemoji.parse 'I like chocolate :heart_eyes:!'
53
- => 'I like chololate <img class="emoji" draggable="false" alt=":heart_eyes:" src="https://twemoji.maxcdn.com/36x36/1f60d.png">'
58
+ > Twemoji.parse "I like chocolate :heart_eyes:!"
59
+ => 'I like chololate <img class="emoji" draggable="false" alt=":heart_eyes:" src="https://twemoji.maxcdn.com/16x16/1f60d.png">'
54
60
  ```
55
61
 
56
62
  ##### asset_root
@@ -58,42 +64,40 @@ Or install it yourself as:
58
64
  Default assets root url, by default will be `https://twemoji.maxcdn.com/`:
59
65
 
60
66
  ```ruby
61
- > Twemoji.parse 'I like chocolate :heart_eyes:!', base: 'foocdn.com'
62
- => 'I like chololate <img class="emoji" draggable="false" alt=":heart_eyes:" src="https://foocdn.com/36x36/1f60d.png">'
67
+ > Twemoji.parse 'I like chocolate :heart_eyes:!', asset_root: "foocdn.com"
68
+ => 'I like chololate <img class="emoji" draggable="false" alt=":heart_eyes:" src="https://foocdn.com/16x16/1f60d.png">'
63
69
  ```
64
70
 
65
71
  ##### file_ext
66
72
 
67
- Default assets file extensions, by default '.svg'.
73
+ Default assets file extensions, by default `.png`.
68
74
 
69
75
  ```ruby
70
- > Twemoji.parse 'I like chocolate :heart_eyes:!', ext: '.png'
71
- => 'I like chololate <img class="emoji" draggable="false" alt=":heart_eyes:" src="https://twemoji.maxcdn.com/16x16/1f60d.png">'
76
+ > Twemoji.parse 'I like chocolate :heart_eyes:!', file_ext: ".svg"
77
+ => 'I like chololate <img class="emoji" draggable="false" alt=":heart_eyes:" src="https://twemoji.maxcdn.com/svg/1f60d.svg">'
72
78
  ```
73
79
 
74
80
  ##### image_size
75
81
 
76
- Default assets/folder size, by default "36x36". Available via Twitter CDN: 16, 36, 72
77
-
78
- Only applicable when file_ext is .png.
82
+ Default assets/folder size, by default `"16x16"`. Available via Twitter CDN: `16`, `36`, `72`.
79
83
 
80
84
  ```ruby
81
- > Twemoji.parse 'I like chocolate :heart_eyes:!', size: "72x72"
82
- => 'I like chololate <img class="emoji" draggable="false" alt=":heart_eyes:" src="https://foocdn.com/72x72/1f60d.png">'
85
+ > Twemoji.parse 'I like chocolate :heart_eyes:!', image_size: "72x72"
86
+ => 'I like chololate <img class="emoji" draggable="false" alt=":heart_eyes:" src="https://twemoji.maxcdn.com/72x72/1f60d.png">'
83
87
  ```
84
88
 
85
89
  ##### class_name
86
90
 
87
- Default img css class name, by default "emoji".
91
+ Default img css class name, by default `"emoji"`.
88
92
 
89
93
  ```ruby
90
- > Twemoji.parse 'I like chocolate :heart_eyes:!', class_name: 'superemoji'
91
- => 'I like chololate <img class="superemoji" draggable="false" alt=":heart_eyes:" src="https://foocdn.com/72x72/1f60d.png">'
94
+ > Twemoji.parse 'I like chocolate :heart_eyes:!', class_name: "superemoji"
95
+ => 'I like chololate <img class="superemoji" draggable="false" alt=":heart_eyes:" src="https://twemoji.maxcdn.com/16x16/1f60d.png">'
92
96
  ```
93
97
 
94
98
  ## Contributing
95
99
 
96
- 1. Fork it ( https://github.com/[my-github-username]/twemoji/fork )
100
+ 1. Fork it ( https://github.com/jollygoodcode/twemoji/fork )
97
101
  2. Create your feature branch (`git checkout -b my-new-feature`)
98
102
  3. Commit your changes (`git commit -am 'Add some feature'`)
99
103
  4. Push to the branch (`git push origin my-new-feature`)
@@ -3,20 +3,23 @@ require "nokogiri"
3
3
  require "twemoji/version"
4
4
  require "twemoji/map"
5
5
 
6
+ # Twemoji is a Ruby implementation, parses your text, replace emoji text
7
+ # with corresponding emoji image. Default emoji images are from Twiiter CDN.
6
8
  module Twemoji
7
9
  # Find code by text and find text by code.
8
10
  #
9
11
  # @example Usage
10
- #
11
12
  # Twemoji.find_by(text: :heart_eyes:) # => "1f60d"
12
- # Twemoji.find_by(code: :1f60d:) # => "heart_eyes"
13
+ # Twemoji.find_by(code: :1f60d:) # => ":heart_eyes:"
13
14
  #
14
15
  # @option options [String] (optional) :text
15
16
  # @option options [String] (optional) :code
16
17
  #
17
- # @return [String] Text or Code
18
+ # @return [String] Text or Code.
18
19
  def self.find_by(*args, text: nil, code: nil)
19
- raise "Can only specify text or code one at a time" if text && code
20
+ if text && code
21
+ raise ArgumentError, "Can only specify text or code one at a time"
22
+ end
20
23
 
21
24
  if text
22
25
  find_by_text text
@@ -25,30 +28,26 @@ module Twemoji
25
28
  end
26
29
  end
27
30
 
28
- # Find emoji code by text
31
+ # Find emoji code by emoji text
29
32
  #
30
33
  # @example Usage
31
- #
32
34
  # Twemoji.find_by_text ":heart_eyes:"
33
35
  # => "1f60d"
34
36
  #
35
- # @param text [String] Text to find emoji code
36
- #
37
- # @return [String] Emoji Code
37
+ # @param text [String] Text to find emoji code.
38
+ # @return [String] Emoji Code.
38
39
  def self.find_by_text(text)
39
40
  CODES[must_str(text)]
40
41
  end
41
42
 
42
- # Find text by emoji code
43
+ # Find emoji text by emoji code.
43
44
  #
44
45
  # @example Usage
45
- #
46
46
  # Twemoji.find_by_code "1f60d"
47
47
  # => ":heart_eyes:"
48
48
  #
49
- # @param code [String] Emoji code to find text
50
- #
51
- # @return [String] Text
49
+ # @param code [String] Emoji code to find text.
50
+ # @return [String] Emoji Text.
52
51
  def self.find_by_code(code)
53
52
  ICODES[must_str(code)]
54
53
  end
@@ -56,63 +55,78 @@ module Twemoji
56
55
  # Parse text, replace emoji text with image.
57
56
  #
58
57
  # @example Usage
59
- #
60
58
  # Twemoji.parse("I like chocolate :heart_eyes:!")
61
59
  # => => 'I like chololate <img class="emoji" draggable="false" alt=":heart_eyes:" src="https://twemoji.maxcdn.com/svg/1f60d.svg">'
62
60
  #
63
- # @param text [String] source text to parse.
61
+ # @param text [String] Source text to parse.
64
62
  #
65
63
  # @option options [String] (optional) asset_root Asset root url to serve emoji.
66
- # @option options [String] (optional) asset_path Folder where you store your emoji images.
67
64
  # @option options [String] (optional) file_ext File extension.
68
65
  # @option options [String] (optional) image_size Emoji image's size 16, 36, 72 applicable if specify .png.
69
66
  # @option options [String] (optional) class_name Emoji image's css class name.
70
67
  #
71
- # @return [String]
68
+ # @return [String] Original text with all occurrences of emoji text
69
+ # replaced by emoji image according to given options.
72
70
  def self.parse(text, asset_root: "https://twemoji.maxcdn.com/",
73
- asset_path: "",
74
- file_ext: ".svg",
71
+ file_ext: ".png",
75
72
  image_size: "16x16",
76
73
  class_name: "emoji")
77
74
 
78
75
  options[:asset_root] = asset_root
79
- options[:asset_path] = asset_path
80
76
  options[:file_ext] = file_ext
81
77
  options[:image_size] = image_size
82
78
  options[:class_name] = class_name
83
79
 
84
- if text.kind_of?(String)
85
- parse_html(text)
86
- else
80
+ if text.kind_of?(Nokogiri::HTML::DocumentFragment)
87
81
  parse_document(text)
82
+ else
83
+ parse_html(text)
88
84
  end
89
85
  end
90
86
 
91
- # Return all emoji patterns' regexp
87
+ # Return all emoji patterns' regular expressions.
88
+ #
89
+ # @return [RegExp] A Regular expression consists of all emojis text.
92
90
  def self.emoji_pattern
93
91
  @emoji_pattern ||= /(#{CODES.keys.each { |name| Regexp.escape(name) }.join("|") })/
94
92
  end
95
93
 
96
94
  private
97
- # Ensure text is string
98
- #
99
- # @param text [String]
95
+
96
+ # Ensure text is a string.
100
97
  #
101
- # @return [String]
98
+ # @param text [String] Text to ensure to be a string.
99
+ # @return [String] A String.
100
+ # @private
102
101
  def self.must_str(text)
103
102
  text = text.respond_to?(:to_str) ? text.to_str : text.to_s
104
103
  end
105
104
 
105
+ # Options hash for Twemoji.
106
+ #
107
+ # @return [Hash] Hash of options.
108
+ # @private
106
109
  def self.options
107
110
  @options ||= {}
108
111
  end
109
112
 
113
+ # Parse a HTML String, replace emoji text with corresponding emoji image.
114
+ #
115
+ # @param text [String] Text string to be parse.
116
+ # @return [String] Text with emoji text replaced by emoji image.
117
+ # @private
110
118
  def self.parse_html(text)
111
119
  return text if !text.include?(":")
112
120
 
113
121
  filter_emojis(text)
114
122
  end
115
123
 
124
+ # Parse a Nokogiri::HTML::DocumentFragment document, replace emoji text
125
+ # with corresponding emoji image.
126
+ #
127
+ # @param doc [Nokogiri::HTML::DocumentFragment] Document to parse.
128
+ # @return [Nokogiri::HTML::DocumentFragment] Parsed document.
129
+ # @private
116
130
  def self.parse_document(doc)
117
131
  doc.search('text()').each do |node|
118
132
  content = node.to_html
@@ -125,25 +139,53 @@ module Twemoji
125
139
  doc
126
140
  end
127
141
 
142
+ # Find out if a node with given exclude tags has ancestors.
143
+ #
144
+ # @param node [Nokogiri::XML::Text] Text node to find ancestor.
145
+ # @param tags [Array] Array of String represents tags.
146
+ # @return [Boolean] If has ancestor returns true, otherwise falsy (nil).
147
+ # @private
148
+ def self.has_ancestor?(node, tags)
149
+ while node = node.parent
150
+ if tags.include?(node.name.downcase)
151
+ break true
152
+ end
153
+ end
154
+ end
155
+
156
+ # Filter emoji text in content, replaced by corresponding emoji image.
157
+ #
158
+ # @param content [String] Contetn to filter emoji text to image.
159
+ # @return [String] Returns a String just like content with all emoji text
160
+ # replaced by the corresponding emoji image.
161
+ # @private
128
162
  def self.filter_emojis(content)
129
163
  content.gsub(emoji_pattern) { |match| img_tag(match) }
130
164
  end
131
165
 
166
+ # Returns emoji image by given name and options from `Twemoji.parse`.
167
+ #
168
+ # @param name [String] Emoji name to generate image tag.
169
+ # @return [String] Emoji image tag generated by name and options.
170
+ # @private
132
171
  def self.img_tag(name)
133
172
  "<img class='#{options[:class_name]}' draggable='false' title='#{name}' alt='#{name}' src='#{emoji_url(name)}'>"
134
173
  end
135
174
 
175
+ # Returns emoji url by given name and options from `Twemoji.parse`.
176
+ #
177
+ # @param name [String] Emoji name to generate image url.
178
+ # @return [String] Emoji image tag generated by name and options.
179
+ # @private
136
180
  def self.emoji_url(name)
137
181
  code = find_by_text(name)
138
182
 
139
- if options[:file_ext] == ".svg"
140
- File.join(options[:asset_root], "svg", "#{code}.svg")
141
- elsif !options[:asset_path].empty?
142
- File.join(options[:asset_root], options[:asset_path], "#{code}.#{options[:file_ext]}")
143
- elsif options[:file_ext] == ".png"
183
+ if options[:file_ext] == ".png"
144
184
  File.join(options[:asset_root], options[:image_size], "#{code}.png")
185
+ elsif options[:file_ext] == ".svg"
186
+ File.join(options[:asset_root], "svg", "#{code}.svg")
145
187
  else
146
- File.join(options[:asset_root], options[:image_size], "#{code}.#{options[:file_ext]}")
188
+ raise RuntimeError, "Unspported file extension: #{options[:file_ext]}"
147
189
  end
148
190
  end
149
191
  end
@@ -1,14 +1,11 @@
1
1
  module Twemoji
2
- # String to hex map
3
- #
4
- # This hash is frozen.
2
+ # Emoji Text to Codepoint mappings. This hash is frozen.
5
3
  #
6
4
  # @example Usage
7
- #
8
5
  # CODES[:smile:] # => "1f604"
9
6
  # CODES[:notebook_with_decorative_cover:] # => "1f4d4"
10
- #
11
7
  # @return [Hash<String => String>]
8
+ # @private
12
9
  CODES = {
13
10
  ":smile:" => "1f604",
14
11
  ":laughing:" => "1f606",
@@ -839,15 +836,13 @@ module Twemoji
839
836
  ":zero:" => "30-20e3"
840
837
  }.each { | k, v| k.freeze; v.freeze }.freeze
841
838
 
842
- # Hex to string map
843
- #
844
- # This hash is frozen.
839
+ # Emoji Codepoint to Text mappings. This hash is frozen.
845
840
  #
846
841
  # @example Usage
847
- #
848
842
  # ICODES["1f60d"] # => ":heart_eyes:"
849
843
  # ICODES["1f4d4"] # => ":notebook_with_decorative_cover:"
850
844
  #
851
845
  # @return [Hash<String => String>]
846
+ # @private
852
847
  ICODES = CODES.invert.freeze
853
848
  end
@@ -1,3 +1,3 @@
1
1
  module Twemoji
2
- VERSION = "0.0.1"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -21,19 +21,60 @@ class TwemojiTest < Minitest::Test
21
21
  assert_equal ":heart_eyes:", Twemoji.find_by(code: "1f60d")
22
22
  end
23
23
 
24
- def test_emoji_pattern
25
- assert_kind_of Regexp, Twemoji.emoji_pattern
24
+ def test_finder_methods_cannot_find_by_both
25
+ exception = assert_raises ArgumentError do
26
+ Twemoji.find_by(text: ":heart_eyes:", code: "1f60d")
27
+ end
28
+
29
+ assert_equal "Can only specify text or code one at a time", exception.message
30
+ end
31
+
32
+ def test_parse_html_string
33
+ expected = "I like chocolate <img class='emoji' draggable='false' title=':heart_eyes:' alt=':heart_eyes:' src='https://twemoji.maxcdn.com/16x16/1f60d.png'>!"
34
+
35
+ assert_equal expected, Twemoji.parse("I like chocolate :heart_eyes:!")
36
+ end
37
+
38
+ def test_parse_document
39
+ doc = Nokogiri::HTML::DocumentFragment.parse("<p>I like chocolate :heart_eyes:!</p>")
40
+ expected = '<p>I like chocolate <img class="emoji" draggable="false" title=":heart_eyes:" alt=":heart_eyes:" src="https://twemoji.maxcdn.com/16x16/1f60d.png">!</p>'
41
+
42
+ assert_equal expected, Twemoji.parse(doc).to_html
43
+ end
44
+
45
+ def test_parse_option_asset_root
46
+ expected = "I like chocolate <img class='emoji' draggable='false' title=':heart_eyes:' alt=':heart_eyes:' src='https://emoji.bestcdn.com/16x16/1f60d.png'>!"
47
+
48
+ assert_equal expected, Twemoji.parse("I like chocolate :heart_eyes:!", asset_root: 'https://emoji.bestcdn.com')
26
49
  end
27
50
 
28
- def test_parse
51
+ def test_parse_option_file_ext_svg
29
52
  expected = "I like chocolate <img class='emoji' draggable='false' title=':heart_eyes:' alt=':heart_eyes:' src='https://twemoji.maxcdn.com/svg/1f60d.svg'>!"
30
53
 
31
- assert_equal expected, Twemoji.parse('I like chocolate :heart_eyes:!')
54
+ assert_equal expected, Twemoji.parse("I like chocolate :heart_eyes:!", file_ext: '.svg')
55
+ end
56
+
57
+ def test_parse_option_unsupport_file_ext_gif
58
+ exception = assert_raises RuntimeError do
59
+ Twemoji.parse("I like chocolate :heart_eyes:!", file_ext: '.gif')
60
+ end
61
+
62
+ assert_equal "Unspported file extension: .gif", exception.message
32
63
  end
33
64
 
34
- def test_parse_with_different_cdn
35
- expected = "I like chocolate <img class='emoji' draggable='false' title=':heart_eyes:' alt=':heart_eyes:' src='https://emoji.bestcdn.com/svg/1f60d.svg'>!"
65
+ def test_parse_option_image_size
66
+ expected = "I like chocolate <img class='emoji' draggable='false' title=':heart_eyes:' alt=':heart_eyes:' src='https://twemoji.maxcdn.com/72x72/1f60d.png'>!"
67
+
68
+ assert_equal expected, Twemoji.parse("I like chocolate :heart_eyes:!", file_ext: ".png", image_size: "72x72")
69
+ end
36
70
 
37
- assert_equal expected, Twemoji.parse('I like chocolate :heart_eyes:!', asset_root: 'https://emoji.bestcdn.com')
71
+ def test_parse_option_class_name
72
+ expected = "I like chocolate <img class='twemoji' draggable='false' title=':heart_eyes:' alt=':heart_eyes:' src='https://twemoji.maxcdn.com/16x16/1f60d.png'>!"
73
+
74
+ assert_equal expected, Twemoji.parse("I like chocolate :heart_eyes:!", class_name: 'twemoji')
75
+ end
76
+
77
+ def test_emoji_pattern
78
+ assert_kind_of Regexp, Twemoji.emoji_pattern
38
79
  end
39
80
  end
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = %w(katehuang0320@gmail.com)
11
11
  spec.summary = %q{A RubyGem to convert :heart: to Twitter cdn url}
12
12
  spec.description = spec.summary
13
- spec.homepage = "https://github.com/JuanitoFatas/twemoji"
13
+ spec.homepage = "https://github.com/jollygoodcode/twemoji"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twemoji
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juanito
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-01-11 00:00:00.000000000 Z
12
+ date: 2015-01-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -33,6 +33,7 @@ extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
35
  - ".gitignore"
36
+ - ".travis.yml"
36
37
  - Gemfile
37
38
  - LICENSE
38
39
  - README.md
@@ -43,7 +44,7 @@ files:
43
44
  - test/test_helper.rb
44
45
  - test/twemoji_test.rb
45
46
  - twemoji.gemspec
46
- homepage: https://github.com/JuanitoFatas/twemoji
47
+ homepage: https://github.com/jollygoodcode/twemoji
47
48
  licenses:
48
49
  - MIT
49
50
  metadata: {}