en Custom Tag Name Characters - chiba233/yumeDSL GitHub Wiki
Custom Tag Name Characters
Custom Syntax | Handler Helpers
Default tag name rules: a-z A-Z 0-9 _ -, first character can't be a digit or -.
Want $$ui:button(...)$$ or $$v2.1(...)$$? Just tweak the tag name character rules.
What it looks like
Default rules:
$$bold(ok)$$ ✅ works
$$ui:button(ok)$$ ❌ colon not allowed → treated as plain text
$$1tag(ok)$$ ❌ digit start not allowed → treated as plain text
With custom rules:
$$ui:button(ok)$$ ✅ colon allowed
$$1tag(ok)$$ ✅ digit start allowed
How to customize
Two functions tell the parser "which characters can appear in tag names":
Parser scans $$xxx( :
│
├─ First char → isTagStartChar("x") → true? continue : skip
│
└─ Remaining chars → isTagChar("x") → true? continue : tag name ends here
interface TagNameConfig {
isTagStartChar: (char: string) => boolean; // what can start a tag name
isTagChar: (char: string) => boolean; // what can follow
}
Simplest approach: pass a partial object
Only specify what you want to change; unspecified functions use defaults:
const dsl = createParser({
handlers,
tagName: {
isTagChar: (char) => /[A-Za-z0-9_-]/.test(char) || char === ":",
},
});
// isTagStartChar not provided → uses default (a-z, A-Z, _)
Using createTagNameConfig wrapper
Exactly the same result, just an explicit merge:
import { createTagNameConfig } from "yume-dsl-rich-text";
tagName: createTagNameConfig({
isTagChar: (char) => /[A-Za-z0-9_-]/.test(char) || char === ":",
})
Examples
Allow colon — namespaced tags ui:button
const dsl = createParser({
handlers: {
"ui:button": { inline: (value, ctx) => ({ type: "ui:button", value }) },
},
tagName: {
isTagChar: (char) => /[A-Za-z0-9_-]/.test(char) || char === ":",
},
});
dsl.parse("Click $$ui:button(Submit)$$");
// → [text("Click "), ui:button([text("Submit")])]
Allow digit start 1tag
parseRichText("$$1tag(hello)$$", {
handlers: { "1tag": { inline: (v, ctx) => ({ type: "1tag", value: v }) } },
tagName: { isTagStartChar: (char) => /[A-Za-z0-9_]/.test(char) },
});
Allow dots — version-style tags v2.1
const dsl = createParser({
handlers: {
"v2.1": { inline: (v, ctx) => ({ type: "version-note", version: "2.1", value: v }) },
},
tagName: createTagNameConfig({
isTagStartChar: (char) => /[A-Za-z0-9_]/.test(char),
isTagChar: (char) => /[A-Za-z0-9_.\-]/.test(char),
}),
});
dsl.parse("See $$v2.1(release notes)$$");
Default values reference
| Function | Default accepts | Role |
|---|---|---|
isTagStartChar |
a-z A-Z _ |
First character of tag name |
isTagChar |
a-z A-Z 0-9 _ - |
Remaining characters |
Notes
tagNameworks on all parser entry points:createParser,parseRichText,stripRichText,parseStructural- Tag name validation only controls what the parser accepts. Unregistered tag names just degrade to plain text, no errors
createTagNameConfigis a pure function, no global state