import { zipArrays } from "../zip"; export const tokenizeInline = (line: string) => { line = line.trim(); const originalLine = line; const insertMarker = "\u{03A9}"; const tokens: InlineTokenInsert[] = []; for (const token of inlineTokens) { const rx = new RegExp(token.rx); let match; while ((match = rx.exec(line)) !== null) { const tokenStart = match.index; const tokenEnd = match.index + match[0].length; const wrappingToken = tokens.find((t) => t.start < tokenStart && t.end > tokenStart ); if (wrappingToken) continue; let wrappedToken; while ( (wrappedToken = tokens.findIndex((t) => t.start > tokenStart && t.start < tokenEnd )) !== -1 ) { tokens.splice(wrappedToken, 1); } token.create(match, tokenStart, tokenEnd, tokens); } } if (tokens.length) { for (const insert of tokens) { line = line.slice(0, insert.start) + "".padStart(insert.end - insert.start, insertMarker) + line.slice(insert.end, line.length); } return zipArrays( line.split(new RegExp(insertMarker + "{2,}")).map((t): InlineToken => ({ content: t, type: "text", uuid: crypto.randomUUID(), })), tokens, ).filter((t) => t.content); } return originalLine; }; const joiner = "<><>"; export const inlineTokens: { rx: RegExp; create: ( content: RegExpExecArray, start: number, end: number, tokens: InlineTokenInsert[], ) => void; replace: (line: string) => string; }[] = [ { rx: /(\*\*)(.*?)(\*\*)/g, create(content, start, end, tokens) { tokens.push({ content: this.replace(content[0]), type: "bold", end, start, uuid: crypto.randomUUID(), }); }, replace(l) { return l.replace(this.rx, (_, __, val) => val); }, }, { rx: /(? [label, href].join(joiner)); // return l }, }, { rx: /!\[(.*?)\]\((.*?)\)/g, create(content, start, end, tokens) { const [_, alt, src] = content; tokens.push({ content: alt, end, start, type: "image", data: { src, }, uuid: crypto.randomUUID(), }); }, replace(l) { return l; }, }, { rx: /\^\[(.*?)\]<<(.*?)>>/gm, create(content, start, end, tokens) { const [_, text, popover] = content; tokens.push({ content: text, end, start, type: "popover", data: { popover: tokenizeInline(popover), }, uuid: crypto.randomUUID(), }); }, replace(l) { return l; }, }, ];