feat: Add macro support
New: macros.ts with MacroDef, parseBlockMacro, matchInlineMacro, buildMacroTags, processInlineMacros. Macro syntax: @user — bare, no args @user() — empty parens, same as bare @npc(Goblin King) — self-closing with args @style(box center — block: no closing paren on first line Content here. — content on subsequent lines ) — closing paren on its own line Unknown macro names now render as an error: <span class="ribbit-error">Unknown macro: @bogus</span> The verbatim keyword causes the contents to render as literals and also preserves line breaks.
This commit is contained in:
+8
-4
@@ -6,6 +6,7 @@ import { HopDown } from './hopdown';
|
||||
import { defaultTheme } from './default-theme';
|
||||
import { ThemeManager } from './theme-manager';
|
||||
import { RibbitEmitter, type RibbitEventMap } from './events';
|
||||
import { buildMacroTags, type MacroDef } from './macros';
|
||||
import type { RibbitTheme } from './types';
|
||||
|
||||
export interface RibbitSettings {
|
||||
@@ -15,6 +16,7 @@ export interface RibbitSettings {
|
||||
currentTheme?: string;
|
||||
themes?: RibbitTheme[];
|
||||
themesPath?: string;
|
||||
macros?: MacroDef[];
|
||||
on?: Partial<RibbitEventMap>;
|
||||
}
|
||||
|
||||
@@ -71,12 +73,14 @@ export class Ribbit {
|
||||
converter: HopDown;
|
||||
themesPath: string;
|
||||
private emitter: RibbitEmitter;
|
||||
private macros: MacroDef[];
|
||||
|
||||
constructor(settings: RibbitSettings) {
|
||||
this.api = settings.api || null;
|
||||
this.element = document.getElementById(settings.editorId || 'ribbit')!;
|
||||
this.themesPath = settings.themesPath || './themes';
|
||||
this.emitter = new RibbitEmitter();
|
||||
this.macros = settings.macros || [];
|
||||
this.states = {
|
||||
VIEW: 'view',
|
||||
};
|
||||
@@ -89,8 +93,8 @@ export class Ribbit {
|
||||
this.themes = new ThemeManager(defaultTheme, this.themesPath, (theme, previous) => {
|
||||
this.theme = theme;
|
||||
this.converter = theme.tags
|
||||
? new HopDown({ tags: theme.tags })
|
||||
: new HopDown();
|
||||
? new HopDown({ tags: theme.tags, macros: this.macros })
|
||||
: new HopDown({ macros: this.macros });
|
||||
this.cachedHTML = null;
|
||||
this.emitter.emit('themeChange', {
|
||||
current: theme,
|
||||
@@ -110,8 +114,8 @@ export class Ribbit {
|
||||
this.themes.set(activeName);
|
||||
this.theme = this.themes.current();
|
||||
this.converter = this.theme.tags
|
||||
? new HopDown({ tags: this.theme.tags })
|
||||
: new HopDown();
|
||||
? new HopDown({ tags: this.theme.tags, macros: this.macros })
|
||||
: new HopDown({ macros: this.macros });
|
||||
|
||||
(settings.plugins || []).forEach(plugin => {
|
||||
this.enabledPlugins[plugin.name] = new plugin({
|
||||
|
||||
Reference in New Issue
Block a user