| interface LiquidToken { |
| name: string |
| getText(): string |
| } |
|
|
| interface LiquidTemplate { |
| [key: string]: unknown |
| } |
|
|
| interface LiquidStream { |
| on(event: string, callback: () => void): LiquidStream |
| stop(): void |
| start(): void |
| } |
|
|
| interface LiquidEngine { |
| parser: { |
| parseStream(tokens: LiquidToken[]): LiquidStream |
| } |
| renderer: { |
| renderTemplates(templates: LiquidTemplate[], scope: Record<string, unknown>): string |
| } |
| parseAndRender(template: string, context: Record<string, string>): string |
| } |
|
|
| export const tags: Record<string, string> = { |
| note: 'accent', |
| tip: 'success', |
| warning: 'attention', |
| danger: 'danger', |
| } |
|
|
| const template: string = |
| '<div class="ghd-alert ghd-alert-{{ color }} ghd-spotlight-{{ color }}">{{ output }}</div>' |
|
|
| export const Spotlight = { |
| type: 'block' as const, |
| tagName: '' as string, |
| templates: [] as LiquidTemplate[], |
| liquid: null as LiquidEngine | null, |
|
|
| parse(tagToken: LiquidToken, remainTokens: LiquidToken[]): void { |
| this.tagName = tagToken.name |
| this.templates = [] |
|
|
| const stream = this.liquid!.parser.parseStream(remainTokens) |
| stream |
| .on(`tag:end${this.tagName}`, () => stream.stop()) |
| .on('template', (tpl: LiquidTemplate) => this.templates.push(tpl)) |
| .on('end', () => { |
| throw new Error(`tag ${tagToken.getText()} not closed`) |
| }) |
| stream.start() |
| }, |
|
|
| *render(scope: Record<string, unknown>): Generator<unknown, unknown, unknown> { |
| const output = yield this.liquid!.renderer.renderTemplates(this.templates, scope) |
|
|
| return yield this.liquid!.parseAndRender(template, { |
| color: tags[this.tagName], |
| output, |
| }) |
| }, |
| } |
|
|