-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathjekyll-mentions.rb
91 lines (82 loc) · 3.03 KB
/
jekyll-mentions.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
require "jekyll"
require "html/pipeline"
module Jekyll
class Mentions
GITHUB_DOT_COM = "https://github.com".freeze
BODY_START_TAG = "<body".freeze
InvalidJekyllMentionConfig = Class.new(Jekyll::Errors::FatalException)
class << self
# rubocop:disable Metrics/AbcSize
def mentionify(doc)
return unless doc.output.include?("@")
src = mention_base(doc.site.config)
if doc.output.include? BODY_START_TAG
parsed_doc = Nokogiri::HTML::Document.parse(doc.output)
body = parsed_doc.at_css("body")
body.children = filter_with_mention(src).call(body.inner_html)[:output].to_s
doc.output = parsed_doc.to_html
else
doc.output = filter_with_mention(src).call(doc.output)[:output].to_s
end
end
# Public: Create or fetch the filter for the given {{src}} base URL.
#
# src - the base URL (e.g. https://github.com)
#
# Returns an HTML::Pipeline instance for the given base URL.
def filter_with_mention(src)
filters[src] ||= HTML::Pipeline.new([
HTML::Pipeline::MentionFilter
], { :base_url => src, :username_pattern => mention_username_pattern })
end
def mention_username_pattern
Regexp.new(
HTML::Pipeline::MentionFilter::UsernamePattern.source,
Regexp::IGNORECASE
)
end
# Public: Filters hash where the key is the mention base URL.
# Effectively a cache.
def filters
@filters ||= {}
end
# Public: Calculate the base URL to use for mentioning.
# The custom base URL can be defined in the config as
# jekyll-mentions.base_url or jekyll-mentions, and must
# be a valid URL (i.e. it must include a protocol and valid domain)
# It should _not_ have a trailing slash.
#
# config - the hash-like configuration of the document's site
#
# Returns a URL to use as the base URL for mentions.
# Defaults to the https://github.com.
def mention_base(config = {})
mention_config = config["jekyll-mentions"]
case mention_config
when nil, NilClass
GITHUB_DOT_COM
when String
mention_config.to_s
when Hash
mention_config.fetch("base_url", GITHUB_DOT_COM)
else
raise InvalidJekyllMentionConfig,
"Your jekyll-mentions config has to either be a" \
" string or a hash. It's a #{mention_config.class} right now."
end
end
# Public: Defines the conditions for a document to be emojiable.
#
# doc - the Jekyll::Document or Jekyll::Page
#
# Returns true if the doc is written & is HTML.
def mentionable?(doc)
(doc.is_a?(Jekyll::Page) || doc.write?) &&
doc.output_ext == ".html" || (doc.permalink && doc.permalink.end_with?("/"))
end
end
end
end
Jekyll::Hooks.register [:pages, :documents], :post_render do |doc|
Jekyll::Mentions.mentionify(doc) if Jekyll::Mentions.mentionable?(doc)
end