1:- module(bc_comment_mention, [
    2    bc_mentions_parse/3 % +Content, +Names, -Mentions
    3]).    4
    5:- use_module(library(error)).    6:- use_module(library(dcg/basics)).
 bc_mentions_parse(+Content, +Names, -Mentions) is det
Parses mentions in content. Uses names list.
   12bc_mentions_parse(Content, Names, Mentions):-
   13    must_be(string, Content),
   14    must_be(list, Names),
   15    maplist(normalize, Names, NamePairs),
   16    string_codes(Content, ContentCodes),
   17    phrase(mentions(NamePairs, Tmp), ContentCodes), !,
   18    Tmp = Mentions.
   19
   20normalize(Name, Name-NormalizedCodes):-
   21    string_codes(Name, Codes),
   22    normalize_codes(Codes, NormalizedCodes).
   23
   24normalize_codes(Codes, Normalized):-
   25    maplist(to_lower, Codes, Lower),
   26    exclude(stripped, Lower, Normalized).
   27
   28stripped(Code):-
   29    \+ code_type(Code, alnum).
   30
   31mentions(NamePairs, [Mention|Mentions]) -->
   32    mention(NamePairs, Mention), !,
   33    mentions(NamePairs, Mentions).
   34
   35mentions(NamePairs, Mentions) -->
   36    [_], !, mentions(NamePairs, Mentions).
   37
   38mentions(_, []) --> [].
   39
   40mention(NamePairs, Name) -->
   41    "@", name_match(NamePairs, Name).
   42
   43name_match(Names, Original) -->
   44    { member(Original-Test, Names) },
   45    name_match(Test), !.
   46
   47name_match([Lower|Codes]) -->
   48    [Code], { to_lower(Code, Lower) },
   49    name_match(Codes).
   50
   51name_match(Codes) -->
   52    { Codes \= [] },
   53    white, name_match(Codes).
   54
   55name_match([]) --> []