Class: HTML::Pipeline::MentionFilter
- Defined in:
- lib/html/pipeline_plus/@mention_filter.rb
Overview
HTML filter that replaces @user mentions with links. Mentions within <pre>, <code>, and <a> elements are ignored. Mentions that reference users that do not exist are ignored.
Context options:
:base_url - Used to construct links to user profile pages for each
mention.
:info_url - Used to link to "more info" when someone mentions @mention
or @mentioned.
:username_pattern - Used to provide a custom regular expression to
identify usernames
Constant Summary collapse
- MentionPatterns =
Hash that contains all of the mention patterns used by the pipeline
Hash.new do |hash, key| hash[key] = / (?:^|\W) # beginning of string or non-word char @((?>#{key})) # @username (?!\/) # without a trailing slash (?= \.+[ \t\W]| # dots followed by space or non-word character \.+$| # dots at end of line [^0-9a-zA-Z_.]| # non-word character except dot $ # end of line ) /ix end
- UsernamePattern =
Default pattern used to extract usernames from text. The value can be overriden by providing the username_pattern variable in the context.
/[a-z0-9][a-z0-9-]*/
- MentionLogins =
List of username logins that, when mentioned, link to the blog post about @mentions instead of triggering a real mention.
%w[ mention mentions mentioned mentioning ].freeze
- IGNORE_PARENTS =
Don’t look for mentions in text nodes that are children of these elements
%w(pre code a style script).to_set
Instance Attribute Summary
Attributes inherited from Filter
Class Method Summary collapse
-
.mentioned_logins_in(text, username_pattern = UsernamePattern) ⇒ Object
Public: Find user @mentions in text.
Instance Method Summary collapse
- #call ⇒ Object
-
#info_url ⇒ Object
The URL to provide when someone @mentions a “mention” name, such as.
- #link_to_mention_info(text, info_url = nil) ⇒ Object
- #link_to_mentioned_user(login) ⇒ Object
-
#mention_link_filter(text, _base_url = '/', info_url = nil, username_pattern = UsernamePattern) ⇒ Object
Replace user @mentions in text with links to the mentioned user’s profile page.
- #username_pattern ⇒ Object
Methods inherited from Filter
#base_url, call, #current_user, #doc, #has_ancestor?, #html, #initialize, #needs, #parse_html, #repository, to_document, to_html, #validate
Constructor Details
This class inherits a constructor from HTML::Pipeline::Filter
Class Method Details
.mentioned_logins_in(text, username_pattern = UsernamePattern) ⇒ Object
Public: Find user @mentions in text. See MentionFilter#mention_link_filter.
MentionFilter.mentioned_logins_in(text) do |match, login, is_mentioned|
"<a href=...>#{login}</a>"
end
text - String text to search.
Yields the String match, the String login name, and a Boolean determining if the match = “@mention”. The yield’s return replaces the match in the original text.
Returns a String replaced with the return of the block.
32 33 34 35 36 37 |
# File 'lib/html/pipeline_plus/@mention_filter.rb', line 32 def self.mentioned_logins_in(text, username_pattern = UsernamePattern) text.gsub MentionPatterns[username_pattern] do |match| login = Regexp.last_match(1) yield match, login, MentionLogins.include?(login.downcase) end end |
Instance Method Details
#call ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/html/pipeline_plus/@mention_filter.rb', line 70 def call result[:mentioned_usernames] ||= [] doc.search('.//text()').each do |node| content = node.to_html next unless content.include?('@') next if has_ancestor?(node, IGNORE_PARENTS) html = mention_link_filter(content, base_url, info_url, username_pattern) next if html == content node.replace(html) end doc end |
#info_url ⇒ Object
The URL to provide when someone @mentions a “mention” name, such as
86 87 88 |
# File 'lib/html/pipeline_plus/@mention_filter.rb', line 86 def info_url context[:info_url] || nil end |
#link_to_mention_info(text, info_url = nil) ⇒ Object
119 120 121 122 123 124 |
# File 'lib/html/pipeline_plus/@mention_filter.rb', line 119 def link_to_mention_info(text, info_url = nil) return "@#{text}" if info_url.nil? "<a href='#{info_url}' class='user-mention'>" \ "@#{text}" \ '</a>' end |
#link_to_mentioned_user(login) ⇒ Object
126 127 128 129 130 131 132 133 134 135 |
# File 'lib/html/pipeline_plus/@mention_filter.rb', line 126 def link_to_mentioned_user(login) result[:mentioned_usernames] |= [login] url = base_url.dup url << '/' unless url =~ /[\/~]\z/ "<a href='#{url << login}' class='user-mention'>" \ "@#{login}" \ '</a>' end |
#mention_link_filter(text, _base_url = '/', info_url = nil, username_pattern = UsernamePattern) ⇒ Object
Replace user @mentions in text with links to the mentioned user’s profile page.
text - String text to replace @mention usernames in. base_url - The base URL used to construct user profile URLs. info_url - The “more info” URL used to link to more info on @mentions.
If nil we don't link @mention or @mentioned.
username_pattern - Regular expression used to identify usernames in
text
Returns a string with @mentions replaced with links. All links have a ‘user-mention’ class name attached for styling.
106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/html/pipeline_plus/@mention_filter.rb', line 106 def mention_link_filter(text, _base_url = '/', info_url = nil, username_pattern = UsernamePattern) self.class.mentioned_logins_in(text, username_pattern) do |match, login, is_mentioned| link = if is_mentioned link_to_mention_info(login, info_url) else link_to_mentioned_user(login) end link ? match.sub("@#{login}", link) : match end end |
#username_pattern ⇒ Object
90 91 92 |
# File 'lib/html/pipeline_plus/@mention_filter.rb', line 90 def username_pattern context[:username_pattern] || UsernamePattern end |