Module: Collavre::MentionParser
- Defined in:
- app/services/collavre/mention_parser.rb
Overview
Centralized mention parsing and resolution. All @mention logic should go through this module so changes to the mention format only need to be made in one place.
Constant Summary collapse
- MENTION_PREFIX_CHARS =
Characters allowed before @ in mentions (besides start-of-text)
/[\s:.,;\n\r]/- MENTION_PATTERN =
Canonical mention: @name: (with colon separator) Matches at start of text or after whitespace/punctuation/newline
/(?:\A|(?<=#{MENTION_PREFIX_CHARS}))@([^:]+?):\s*/- MENTION_LOOSE_PATTERN =
Mention without colon: @name followed by whitespace (start-of-text only to avoid false positives like email addresses)
/\A@(\S+)\s+/- MENTION_SCAN_PATTERN =
Scan pattern: finds all @name: mentions anywhere in text
/(?:^|(?<=#{MENTION_PREFIX_CHARS}))@([^:]+?):/
Class Method Summary collapse
-
.extract_all_names(text) ⇒ Object
Extract all mentioned names from text.
-
.extract_name(text) ⇒ Object
Extract the first mentioned name from text (returns nil if no mention found).
-
.find_user_by_name(name) ⇒ Object
Find a User by case-insensitive name match.
-
.resolve_all_users(text) ⇒ Object
Resolve all mentioned users from text (finds mentions anywhere).
-
.resolve_user(text) ⇒ Object
Extract mention and resolve to a User in one step.
-
.strip_self_mention(text, agent_name) ⇒ Object
Strip self-mention prefix from text (both @name: and @name formats).
Class Method Details
.extract_all_names(text) ⇒ Object
Extract all mentioned names from text
29 30 31 32 33 |
# File 'app/services/collavre/mention_parser.rb', line 29 def self.extract_all_names(text) return [] if text.blank? text.scan(MENTION_SCAN_PATTERN).flatten.map(&:strip).uniq end |
.extract_name(text) ⇒ Object
Extract the first mentioned name from text (returns nil if no mention found)
21 22 23 24 25 26 |
# File 'app/services/collavre/mention_parser.rb', line 21 def self.extract_name(text) return nil if text.blank? match = text.match(MENTION_PATTERN) || text.match(MENTION_LOOSE_PATTERN) match ? match[1].strip : nil end |
.find_user_by_name(name) ⇒ Object
Find a User by case-insensitive name match
36 37 38 39 40 |
# File 'app/services/collavre/mention_parser.rb', line 36 def self.find_user_by_name(name) return nil if name.blank? User.where("LOWER(name) = ?", name.strip.downcase).first end |
.resolve_all_users(text) ⇒ Object
Resolve all mentioned users from text (finds mentions anywhere)
49 50 51 |
# File 'app/services/collavre/mention_parser.rb', line 49 def self.resolve_all_users(text) extract_all_names(text).filter_map { |name| find_user_by_name(name) }.uniq end |
.resolve_user(text) ⇒ Object
Extract mention and resolve to a User in one step
43 44 45 46 |
# File 'app/services/collavre/mention_parser.rb', line 43 def self.resolve_user(text) name = extract_name(text) name ? find_user_by_name(name) : nil end |
.strip_self_mention(text, agent_name) ⇒ Object
Strip self-mention prefix from text (both @name: and @name formats)
54 55 56 57 58 59 60 61 |
# File 'app/services/collavre/mention_parser.rb', line 54 def self.strip_self_mention(text, agent_name) return text if text.blank? || agent_name.blank? escaped = Regexp.escape(agent_name) text .sub(/\A@#{escaped}:\s*/i, "") .sub(/\A@#{escaped}\s+/i, "") end |