Skip to content

Instantly share code, notes, and snippets.

@lukepighetti
Last active August 23, 2022 18:47
Show Gist options
  • Select an option

  • Save lukepighetti/ec4e3f90412dc2a9c7ffe08c16b6fed0 to your computer and use it in GitHub Desktop.

Select an option

Save lukepighetti/ec4e3f90412dc2a9c7ffe08c16b6fed0 to your computer and use it in GitHub Desktop.
Parse Twitch message + emote spec
import assert from "assert";
main();
function main(): void {
const parsedMessage = parseEmotes(
"Yo Kappas Kappa Kappa yo",
{
"25": ["10-15", "16-21"],
},
(e) => e,
(emoteId) => `[${emoteId}]`
);
assert.deepEqual(parsedMessage, ["Yo Kappas ", "[25]", " ", "[25]", " yo"]);
}
function parseEmotes<T>(
message: string,
emotes: { [key: string]: string[] },
onText: (text: string) => T,
onEmote: (emoteId: string) => T
): T[] {
const matches: EmoteMatch[] = [];
for (const [emoteId, spans] of Object.entries(emotes)) {
for (const span of spans) {
const [startIndex, endIndex] = span.split("-").map(Number);
matches.push({ emoteId, startIndex, endIndex });
}
}
matches.sort((a, z) => a.startIndex - z.startIndex);
const chunks: T[] = [];
let previousMatch: EmoteMatch | null = null;
for (const match of matches) {
const startIndex = previousMatch?.endIndex ?? 0;
const endIndex = match.startIndex;
chunks.push(onText(message.substring(startIndex, endIndex)));
chunks.push(onEmote(match.emoteId));
previousMatch = match;
}
if (previousMatch != null) {
const startIndex = previousMatch.endIndex;
const endIndex = message.length;
if (startIndex < endIndex) {
chunks.push(onText(message.substring(startIndex, endIndex)));
}
}
return chunks;
}
type EmoteMatch = { emoteId: string; startIndex: number; endIndex: number };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment