module Twemoji
Twemoji
is a Ruby implementation, parses your text, replace emoji text with corresponding emoji image. Default emoji images are from Twiiter CDN.
Constants
- CODES
Emoji Text to Codepoint mapping constant. This hash is frozen. @private
- EMOJI_PATTERN
- EMOJI_PATTERN_ALL
- EMOJI_PATTERN_UNICODE
- PNG
- PNG_IMAGE_SIZE
- SVG
- VERSION
Public Class Methods
Emoji Text to Codepoint mappings.
@example Usage
codes[":heart_eyes:"] # => "1f60d" codes[":notebook_with_decorative_cover:"] # => "1f4d4"
@return [Hash<String => String>]
# File lib/twemoji/map.rb, line 12 def self.codes CODES end
# File lib/twemoji/configuration.rb, line 6 def self.configuration @configuration ||= Configuration.new end
# File lib/twemoji/configuration.rb, line 10 def self.configuration=(configuration) @configuration = configuration end
# File lib/twemoji/configuration.rb, line 14 def self.configure yield configuration end
Return all emoji patterns' regular expressions.
@return [RegExp] A Regular expression consists of all emojis text.
# File lib/twemoji.rb, line 128 def self.emoji_pattern EMOJI_PATTERN end
Return all emoji patterns' regular expressions in unicode and name.
@return [RegExp] A Regular expression consists of all emojis unicode codepoint and names.
# File lib/twemoji.rb, line 143 def self.emoji_pattern_all EMOJI_PATTERN_ALL end
Return all emoji patterns' regular expressions in unicode. e.g '1f1f2-1f1fe' will be converted to u{1f1f2}u{1f1fe} for RegExp matching.
@return [RegExp] A Regular expression consists of all emojis unicode.
# File lib/twemoji.rb, line 136 def self.emoji_pattern_unicode EMOJI_PATTERN_UNICODE end
Find code by text, find text by code, and find text by unicode.
@example Usage
Twemoji.find_by(text: ":heart_eyes:") # => "1f60d" Twemoji.find_by(code: "1f60d") # => ":heart_eyes:" Twemoji.find_by(unicode: "😍") # => ":heart_eyes:" Twemoji.find_by(unicode: "\u{1f60d}") # => ":heart_eyes:"
@option options [String] (optional) :text @option options [String] (optional) :code @option options [String] (optional) :unicode
@return [String] Emoji text or code.
# File lib/twemoji.rb, line 26 def self.find_by(text: nil, code: nil, unicode: nil) if [ text, code, unicode ].compact!.size > 1 fail ArgumentError, "Can only specify text, code or unicode one at a time" end case when text find_by_text text when unicode find_by_unicode unicode else find_by_code code end end
Find emoji text by emoji code.
@example Usage
Twemoji.find_by_code "1f60d" => ":heart_eyes:"
@param code [String] Emoji code to find text. @return [String] Emoji Text.
# File lib/twemoji.rb, line 61 def self.find_by_code(code) invert_codes[must_str(code)] end
Find emoji code by emoji text.
@example Usage
Twemoji.find_by_text ":heart_eyes:" => "1f60d"
@param text [String] Text to find emoji code. @return [String] Emoji Code.
# File lib/twemoji.rb, line 49 def self.find_by_text(text) codes[must_str(text)] end
Find emoji text by raw emoji unicode.
@example Usage
Twemoji.find_by_unicode "😍" => ":heart_eyes:"
@param raw [String] Emoji raw unicode to find text. @return [String] Emoji Text.
# File lib/twemoji.rb, line 73 def self.find_by_unicode(raw) invert_codes[unicode_to_str(raw)] end
Emoji Codepoint to Text mappings. This hash is frozen.
@example Usage
invert_codes["1f60d"] # => ":heart_eyes:" invert_codes["1f4d4"] # => ":notebook_with_decorative_cover:"
@return [Hash<String => String>]
# File lib/twemoji/map.rb, line 23 def self.invert_codes codes.invert.freeze end
# File lib/twemoji/configuration.rb, line 18 def self.load_yaml(path) YAML.safe_load(IO.read(path)) end
Parse string, replace emoji text with image. Parse DOM, replace emoji with image.
@example Usage
Twemoji.parse("I like chocolate :heart_eyes:!") => 'I like chocolate <img draggable="false" title=":heart_eyes:" alt="😍" src="https://twemoji.maxcdn.com/2/svg/1f60d.svg" class="emoji">!'
@param text [String] Source text to parse.
@option options [String] (optional) asset_root Asset root url to serve emoji. @option options [String] (optional) file_ext File extension. @option options [String] (optional) class_name Emoji image's tag class attribute. @option options [String] (optional) img_attrs Emoji image's img tag attributes.
@return [String] Original text with all occurrences of emoji text replaced by emoji image according to given options.
# File lib/twemoji.rb, line 109 def self.parse(text, asset_root: Twemoji.configuration.asset_root, file_ext: Twemoji.configuration.file_ext, class_name: Twemoji.configuration.class_name, img_attrs: Twemoji.configuration.img_attrs) options[:asset_root] = asset_root options[:file_ext] = file_ext options[:img_attrs] = { class: class_name }.merge(img_attrs) if text.is_a?(Nokogiri::HTML::DocumentFragment) parse_document(text) else parse_html(text) end end
# File lib/twemoji/png.rb, line 4 def self.png PNG end
Render raw emoji unicode from emoji text or emoji code.
@example Usage
Twemoji.render_unicode ":heart_eyes:" => "😍" Twemoji.render_unicode "1f60d" => "😍"
@param text_or_code [String] Emoji text or code to render as unicode. @return [String] Emoji UTF-8 Text.
# File lib/twemoji.rb, line 87 def self.render_unicode(text_or_code) text_or_code = find_by_text(text_or_code) if text_or_code[0] == ?: unicodes = text_or_code.split(?-) unicodes.map(&:hex).pack(?U*unicodes.size) end
# File lib/twemoji/svg.rb, line 4 def self.svg SVG end
Private Class Methods
Returns user customized img attributes. If attribute value is any proc-like object, will call it and the emoji name will be passed as argument.
@param name [String] Emoji name. @return Hash of customized attributes @private
# File lib/twemoji.rb, line 273 def self.customized_attrs(name) custom_img_attributes = {} options[:img_attrs].each do |key, value| # run value filters where given if value.respond_to?(:call) custom_img_attributes[key] = value.call(name) else custom_img_attributes[key] = value end end custom_img_attributes end
Default img attributes: draggable, title, alt, src.
@param name [String] Emoji name. @return Hash of default attributes @private
# File lib/twemoji.rb, line 293 def self.default_attrs(name) { draggable: "false".freeze, title: name, alt: render_unicode(name), src: emoji_url(name) } end
Default img attributes for unicode: draggable, title, alt, src.
@param unicode [String] Emoji unicode codepoint. @return Hash of default attributes @private
# File lib/twemoji.rb, line 307 def self.default_attrs_unicode(unicode) { draggable: "false".freeze, title: find_by_unicode(unicode), alt: unicode, src: emoji_url(unicode, :unicode_to_str) } end
Returns emoji url by given name and options from `Twemoji.parse`.
@param name [String] Emoji name to generate image url. @return [String] Emoji image tag generated by name and options. @private
# File lib/twemoji.rb, line 255 def self.emoji_url(name, finder = :find_by_text) code = self.send(finder, name) if options[:file_ext] == "png" File.join(options[:asset_root], PNG_IMAGE_SIZE, "#{code}.png") elsif options[:file_ext] == "svg" File.join(options[:asset_root], "svg", "#{code}.svg") else fail "Unsupported file extension: #{options[:file_ext]}" end end
Filter emoji text in content, replaced by corresponding emoji image.
@param content [String] Content to filter emoji text to image. @return [String] Returns a String just like content with all emoji text
replaced by the corresponding emoji image.
@private
# File lib/twemoji.rb, line 229 def self.filter_emojis(content, pattern = emoji_pattern_all) content.gsub(pattern) { |match| img_tag(match) } end
Find out if a node with given exclude tags has ancestors.
@param node [Nokogiri::XML::Text] Text node to find ancestor. @param tags [Array] Array of String represents tags. @return [Boolean] If has ancestor returns true, otherwise falsy (nil). @private
# File lib/twemoji.rb, line 215 def self.has_ancestor?(node, tags) while node = node.parent if tags.include?(node.name.downcase) break true end end end
Coverts hash of attributes into HTML attributes.
@param hash [Hash] Hash of attributes. @return [String] HTML attributes suitable for use in tag @private
# File lib/twemoji.rb, line 331 def self.hash_to_html_attrs(hash) hash.reject { |key, value| value.nil? || value == '' }.map { |attr, value| %(#{attr}="#{value}") }.join(" ") end
Returns emoji image tag by given name and options from `Twemoji.parse`.
@param name [String] Emoji name to generate image tag. @return [String] Emoji image tag generated by name and options. @private
# File lib/twemoji.rb, line 238 def self.img_tag(name) # choose default attributes based on name or unicode codepoint default_attrs = name.include?(":") ? default_attrs(name) : default_attrs_unicode(name) text_name = name.include?(":") ? name : find_by_unicode(name) img_attrs_hash = default_attrs.merge! customized_attrs(text_name) %(<img #{hash_to_html_attrs(img_attrs_hash)}>) end
Ensure text is a string.
@param text [String] Text to ensure to be a string. @return [String] A String. @private
# File lib/twemoji.rb, line 167 def self.must_str(text) text.respond_to?(:to_str) ? text.to_str : text.to_s end
Options hash for Twemoji
.
@return [Hash] Hash of options. @private
# File lib/twemoji.rb, line 175 def self.options @options ||= {} end
Parse a Nokogiri::HTML::DocumentFragment document, replace emoji text with corresponding emoji image.
@param doc [Nokogiri::HTML::DocumentFragment] Document to parse. @param filter [Symbol] Symbol of filter function to use. Available filters
are :filter_emoji and :filter_emoji_unicode.
@return [Nokogiri::HTML::DocumentFragment] Parsed document. @private
# File lib/twemoji.rb, line 198 def self.parse_document(doc, filter = :filter_emojis) doc.xpath(".//text() | text()").each do |node| content = node.to_html next if has_ancestor?(node, %w(pre code tt)) html = self.send(filter, content) next if html == content node.replace(html) end doc end
Parse a HTML String, replace emoji text with corresponding emoji image.
@param text [String] Text string to be parse. @param filter [Symbol] Symbol of filter function to use. Available filters
are :filter_emoji and :filter_emoji_unicode.
@return [String] Text with emoji text replaced by emoji image. @private
# File lib/twemoji.rb, line 186 def self.parse_html(text, filter = :filter_emojis) self.send(filter, text) end
Return sorted codepoint values by descending length.
@return [Array] An array of emoji codepoint values sorted by descending length
# File lib/twemoji.rb, line 152 def self.sorted_codepoint_values # has to be sorted to match the combined codepoint (2-3 char emojis) before single char emojis @sorted_codepoint_values ||= invert_codes.keys.sort_by {|key| key.length }.reverse end
Convert raw unicode to string key version.
e.g. 🇲🇾 converts to “1f1f2-1f1fe” @param unicode [String] Unicode codepoint. @return String representation of unicode codepoint @private
# File lib/twemoji.rb, line 322 def self.unicode_to_str(unicode) Twemoji::Utils::Unicode.unpack(unicode) end