UNPKG

codemirror-lang-mermaid

Version:
130 lines (111 loc) 2.61 kB
import { ExternalTokenizer } from '@lezer/lr'; import { _break, _else, Activate, Actor, alt, and, As, Autonumber, box, Create, critical, Deactivate, Destroy, End, link, links, loop, messageText, NodeText, Note, opt, option, par, Participant, Position, rect, } from './sequence.grammar.terms'; const skipCodePoints = [-1, 9, 10, 13, 32, 37]; const arrowSuffixCodePoints = [43, 45]; const notAllowedCodePoints = [44, 58, 62]; const notAllowed2Chars = ['->', '-x', '-)', ' -', ' ']; const notAllowed3Chars = ['-->', '->>', '--x', '--)', ' as']; const keywordMap: { [key: string]: number } = { 'left of': Position, 'right of': Position, activate: Activate, actor: Actor, alt: alt, and: and, as: As, autonumber: Autonumber, box: box, break: _break, create: Create, critical: critical, deactivate: Deactivate, destroy: Destroy, else: _else, end: End, link: link, links: links, loop: loop, note: Note, opt: opt, option: option, over: Position, par: par, participant: Participant, rect: rect, }; const keywords = Object.keys(keywordMap); export const messageTextToken = new ExternalTokenizer((input) => { if (skipCodePoints.includes(input.next)) return; while (input.next !== 10 && input.next !== -1) { input.advance(); } input.acceptToken(messageText); }); export const textTokens = new ExternalTokenizer((input) => { if ( skipCodePoints.includes(input.next) || arrowSuffixCodePoints.includes(input.next) ) return; const isArrowNext = () => { if (input.peek(0) === -1 || input.peek(1) === -1 || input.peek(2) === -1) return false; let result = String.fromCodePoint(input.peek(0)) + String.fromCodePoint(input.peek(1)); if (notAllowed2Chars.includes(result)) return true; result += String.fromCodePoint(input.peek(2)); if (notAllowed3Chars.includes(result)) return true; return false; }; let tokens = ''; while ( !notAllowedCodePoints.includes(input.next) && !isArrowNext() && input.next !== 10 && input.next !== -1 ) { tokens += String.fromCodePoint(input.next); input.advance(); } const activeKeyword = keywords.filter((keyword) => { if (keyword === tokens) { return tokens.toLowerCase().startsWith(keyword); } return tokens.toLowerCase().startsWith(keyword + ' '); }); if (activeKeyword.length > 0) { input.acceptToken( keywordMap[activeKeyword[0]], activeKeyword[0].length - tokens.length ); return; } input.acceptToken(NodeText); });