2017-04-04 04:36:03 +00:00
|
|
|
// Escapes the RegExp special characters "^", "$", "", ".", "*", "+", "?", "(",
|
|
|
|
// ")", "[", "]", "{", "}", and "|" in string.
|
|
|
|
// See https://lodash.com/docs/#escapeRegExp
|
2019-11-16 17:24:03 +00:00
|
|
|
import escapeRegExp from "lodash/escapeRegExp";
|
2022-06-19 00:25:21 +00:00
|
|
|
import {Part} from "./merge";
|
|
|
|
|
|
|
|
export type ChannelPart = Part & {
|
|
|
|
channel: string;
|
|
|
|
};
|
2017-03-18 08:35:17 +00:00
|
|
|
|
2017-04-04 04:36:03 +00:00
|
|
|
// Given an array of channel prefixes (such as "#" and "&") and an array of user
|
|
|
|
// modes (such as "@" and "+"), this function extracts channels and nicks from a
|
|
|
|
// text.
|
|
|
|
// It returns an array of objects for each channel found with their start index,
|
|
|
|
// end index and channel name.
|
2022-06-19 00:25:21 +00:00
|
|
|
function findChannels(text: string, channelPrefixes: string[], userModes: string[]) {
|
2017-04-04 04:36:03 +00:00
|
|
|
// `userModePattern` is necessary to ignore user modes in /whois responses.
|
|
|
|
// For example, a voiced user in #thelounge will have a /whois response of:
|
|
|
|
// > foo is on the following channels: +#thelounge
|
|
|
|
// We need to explicitly ignore user modes to parse such channels correctly.
|
2017-03-18 08:35:17 +00:00
|
|
|
const userModePattern = userModes.map(escapeRegExp).join("");
|
|
|
|
const channelPrefixPattern = channelPrefixes.map(escapeRegExp).join("");
|
2017-04-04 04:36:03 +00:00
|
|
|
const channelPattern = `(?:^|\\s)[${userModePattern}]*([${channelPrefixPattern}][^ \u0007]+)`;
|
2017-03-18 08:35:17 +00:00
|
|
|
const channelRegExp = new RegExp(channelPattern, "g");
|
|
|
|
|
2022-06-19 00:25:21 +00:00
|
|
|
const result: ChannelPart[] = [];
|
|
|
|
let match: RegExpExecArray | null;
|
2017-03-18 08:35:17 +00:00
|
|
|
|
|
|
|
do {
|
2017-04-04 04:36:03 +00:00
|
|
|
// With global ("g") regexes, calling `exec` multiple times will find
|
|
|
|
// successive matches in the same string.
|
2017-03-18 08:35:17 +00:00
|
|
|
match = channelRegExp.exec(text);
|
|
|
|
|
|
|
|
if (match) {
|
|
|
|
result.push({
|
|
|
|
start: match.index + match[0].length - match[1].length,
|
|
|
|
end: match.index + match[0].length,
|
2017-11-15 06:35:15 +00:00
|
|
|
channel: match[1],
|
2017-03-18 08:35:17 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
} while (match);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-11-16 17:24:03 +00:00
|
|
|
export default findChannels;
|