Class: Jekyll::Spaceship::EmojiProcessor

Inherits:
Processor
  • Object
show all
Defined in:
lib/jekyll-spaceship/processors/emoji-processor.rb

Constant Summary

Constants inherited from Processor

Processor::DEFAULT_PRIORITY, Processor::PRIORITY_MAP

Instance Attribute Summary

Attributes inherited from Processor

#config, #exclusions, #handled, #logger, #page, #priority, #registers

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Processor

class_name, #converter, #dispatch, escape_html, exclude, #exclusion_regexs, #ext, fetch_img_data, #filename, #get_exclusion, handle_bang_link, #initialize, #initialize_exclusions, #initialize_priority, #initialize_register, make_img_tag, #name, #next?, #on_handle_html_block, #on_handled, #output_ext, #post_exclude, #pre_exclude, priority, #process?, register

Constructor Details

This class inherits a constructor from Jekyll::Spaceship::Processor

Class Method Details

.configObject



9
10
11
12
13
14
15
16
# File 'lib/jekyll-spaceship/processors/emoji-processor.rb', line 9

def self.config
  {
    'css' => {
      'class' => 'emoji'
    },
    'src' => 'https://github.githubassets.com/images/icons/emoji/'
  }
end

Instance Method Details

#emoji_filter(content, selector) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/jekyll-spaceship/processors/emoji-processor.rb', line 37

def emoji_filter(content, selector)
  # use nokogiri to parse html
  doc = Nokogiri::HTML(content)

  body = doc.at('body')

  # in case of a page has no the body node, especially when your
  # page's layout field of front matter is nil or unavailable
  return content if body.nil?

  # Count for restoration
  escaped_count = 0

  # filter nodes (pre, code)
  body.css(selector).each do |node|
    count = escaped_count

    # handle emoji markup
    inner_html = node.inner_html.gsub(
      /(?<!\\):([\w\d+-]+?)(?<!\\):/
    ) do |match|
      escaped_count += 1
      "\\:#{match[1..-2]}\\:"
    end

    if escaped_count > count
      node.inner_html = inner_html
    end
  end

  # parse the emoji
  content = body.inner_html
  content.scan(/(?<!\\):([\w\d+-]+?)(?<!\\):/) do |match|
    # Skip invalid emoji name
    emoji = Emoji.find_by_alias match[0]
    next if emoji.nil?

    # escape plus sign
    emoji_name = emoji.name.gsub('+', '\\\+')

    result = yield emoji
    next if result.nil?

    content = content.gsub(
      /(?<!\=")\s*:#{emoji_name}:\s*(?!"\s)/,
      result)
  end

  body.inner_html = content

  return doc.to_html if escaped_count.zero?

  # restore nodes (pre, code)
  body.css(selector).each do |node|
    # handle emoji markup
    node.inner_html = node.inner_html.gsub(
      /\\:([\w\d+-]+?)\\:/, ':\1:'
    )
  end

  doc.to_html
end

#on_handle_html(content) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/jekyll-spaceship/processors/emoji-processor.rb', line 18

def on_handle_html(content)
  emoji_filter(content, 'pre code') do |emoji|
    # mark current file has been handled
    self.handled = true

    # here is the replacement content
    "<img class=\"#{config['css']['class']}\""\
      " title=\":#{emoji.name}:\""\
      " alt=\":#{emoji.name}:\""\
      " raw=\"#{emoji.raw}\""\
      " src=\"#{config['src']}#{emoji.image_filename}\""\
      " style=\"vertical-align: middle; display: inline;"\
      " max-width: 1em; visibility: hidden;\""\
      " onload=\"this.style.visibility='visible'\""\
      " onerror=\"this.replaceWith(this.getAttribute('raw'))\">"\
      "</img>"
  end
end