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

codes() click to toggle source

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
configuration() click to toggle source
# File lib/twemoji/configuration.rb, line 6
def self.configuration
  @configuration ||= Configuration.new
end
configuration=(configuration) click to toggle source
# File lib/twemoji/configuration.rb, line 10
def self.configuration=(configuration)
  @configuration = configuration
end
configure() { |configuration| ... } click to toggle source
# File lib/twemoji/configuration.rb, line 14
def self.configure
  yield configuration
end
emoji_pattern() click to toggle source

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
emoji_pattern_all() click to toggle source

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
emoji_pattern_unicode() click to toggle source

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_by(text: nil, code: nil, unicode: nil) click to toggle source

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_by_code(code) click to toggle source

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_by_text(text) click to toggle source

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_by_unicode(raw) click to toggle source

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
invert_codes() click to toggle source

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
load_yaml(path) click to toggle source
# File lib/twemoji/configuration.rb, line 18
def self.load_yaml(path)
  YAML.safe_load(IO.read(path))
end
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) click to toggle source

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
png() click to toggle source
# File lib/twemoji/png.rb, line 4
def self.png
  PNG
end
render_unicode(text_or_code) click to toggle source

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
svg() click to toggle source
# File lib/twemoji/svg.rb, line 4
def self.svg
  SVG
end

Private Class Methods

customized_attrs(name) click to toggle source

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_attrs(name) click to toggle source

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_attrs_unicode(unicode) click to toggle source

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
emoji_url(name, finder = :find_by_text) click to toggle source

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_emojis(content, pattern = emoji_pattern_all) click to toggle source

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
has_ancestor?(node, tags) click to toggle source

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
hash_to_html_attrs(hash) click to toggle source

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
img_tag(name) click to toggle source

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
must_str(text) click to toggle source

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() click to toggle source

Options hash for Twemoji.

@return [Hash] Hash of options. @private

# File lib/twemoji.rb, line 175
def self.options
  @options ||= {}
end
parse_document(doc, filter = :filter_emojis) click to toggle source

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_html(text, filter = :filter_emojis) click to toggle source

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
sorted_codepoint_values() click to toggle source

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
unicode_to_str(unicode) click to toggle source

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