Class: HTMLPipeline::NodeFilter::MentionFilter
- Inherits:
-
HTMLPipeline::NodeFilter
- Object
- Filter
- HTMLPipeline::NodeFilter
- HTMLPipeline::NodeFilter::MentionFilter
- Defined in:
- lib/html_pipeline/node_filter/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
- MENTION_PATTERNS =
Hash that contains all of the mention patterns used by the pipeline
Hash.new do |hash, key| hash[key] = %r{ (?:^|\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
- USERNAME_PATTERN =
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-]*/
- IGNORE_PARENTS =
Don’t look for mentions in text nodes that are children of these elements
["pre", "code", "a", "style", "script"]
- SELECTOR =
Selma::Selector.new(match_text_within: "*", ignore_text_within: IGNORE_PARENTS)
Instance Attribute Summary
Attributes inherited from HTMLPipeline::NodeFilter
Attributes inherited from Filter
Class Method Summary collapse
-
.mentioned_logins_in(text, username_pattern = USERNAME_PATTERN) ⇒ Object
Public: Find user @mentions in text.
Instance Method Summary collapse
- #after_initialize ⇒ Object
- #handle_text_chunk(text) ⇒ Object
-
#info_url ⇒ Object
The URL to provide when someone @mentions a “mention” name, such as @mention or @mentioned, that will give them more info on mentions.
- #link_to_mentioned_user(base_url, login) ⇒ Object
-
#mention_link_filter(text, base_url: "/", username_pattern: USERNAME_PATTERN) ⇒ Object
Replace user @mentions in text with links to the mentioned user’s profile page.
- #selector ⇒ Object
- #username_pattern ⇒ Object
Methods inherited from HTMLPipeline::NodeFilter
call, #html, #initialize, #reset!
Methods inherited from Filter
#base_url, #call, call, #has_ancestor?, #initialize, #needs, #validate
Constructor Details
This class inherits a constructor from HTMLPipeline::NodeFilter
Class Method Details
.mentioned_logins_in(text, username_pattern = USERNAME_PATTERN) ⇒ 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.
35 36 37 38 39 40 |
# File 'lib/html_pipeline/node_filter/mention_filter.rb', line 35 def mentioned_logins_in(text, username_pattern = USERNAME_PATTERN) text.gsub(MENTION_PATTERNS[username_pattern]) do |match| login = Regexp.last_match(1) yield match, login end end |
Instance Method Details
#after_initialize ⇒ Object
66 67 68 |
# File 'lib/html_pipeline/node_filter/mention_filter.rb', line 66 def after_initialize result[:mentioned_usernames] ||= [] end |
#handle_text_chunk(text) ⇒ Object
74 75 76 77 78 79 80 81 82 |
# File 'lib/html_pipeline/node_filter/mention_filter.rb', line 74 def handle_text_chunk(text) content = text.to_s return unless content.include?("@") html = mention_link_filter(content, base_url: base_url, username_pattern: username_pattern) return if html == content text.replace(html, as: :html) end |
#info_url ⇒ Object
The URL to provide when someone @mentions a “mention” name, such as @mention or @mentioned, that will give them more info on mentions.
86 87 88 |
# File 'lib/html_pipeline/node_filter/mention_filter.rb', line 86 def info_url context[:info_url] || nil end |
#link_to_mentioned_user(base_url, login) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/html_pipeline/node_filter/mention_filter.rb', line 114 def link_to_mentioned_user(base_url, login) result[:mentioned_usernames] |= [login] url = base_url.dup excluded_prefixes = %r{[/(?:~|@]\z} url << "/" unless excluded_prefixes.match?(url) "<a href=\"#{url << login}\" class=\"user-mention\">" \ "@#{login}" \ "</a>" end |
#mention_link_filter(text, base_url: "/", username_pattern: USERNAME_PATTERN) ⇒ 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 |
# File 'lib/html_pipeline/node_filter/mention_filter.rb', line 106 def mention_link_filter(text, base_url: "/", username_pattern: USERNAME_PATTERN) self.class.mentioned_logins_in(text, username_pattern) do |match, login| link = link_to_mentioned_user(base_url, login) link ? match.sub("@#{login}", link) : match end end |
#selector ⇒ Object
70 71 72 |
# File 'lib/html_pipeline/node_filter/mention_filter.rb', line 70 def selector SELECTOR end |
#username_pattern ⇒ Object
90 91 92 |
# File 'lib/html_pipeline/node_filter/mention_filter.rb', line 90 def username_pattern context[:username_pattern] || USERNAME_PATTERN end |