diff --git a/README.md b/README.md index a67747e..70a4a7b 100644 --- a/README.md +++ b/README.md @@ -3,37 +3,3 @@ ```sh pnpm install https://git.methanium.net/methanium/ui/releases/download/latest/methanium-ui.tgz ``` - -## Markdown - -The renderer is available from the package root. The live editor, compact text -renderer, and emoji APIs use the `@methanium/ui/markdown` entry point. - -```tsx -import { Markdown } from "@methanium/ui"; -import { - EmojiProvider, - Input, - createEmojiRegistry, -} from "@methanium/ui/markdown"; - -const registry = createEmojiRegistry({ - customEmojis: [ - { - shortcode: ":party_parrot:", - aliases: [":parrot_party:"], - src: "/emoji/party-parrot.webp", - }, - ], -}); - - - - -; -``` - -Custom shortcodes and aliases must be unique and may not collide with built-in -Twemoji names. Twemoji graphics are bundled locally and do not use a CDN. The -graphics are provided by the [Twemoji project](https://github.com/jdecked/twemoji) -under CC-BY 4.0; code is licensed under MIT. diff --git a/package.json b/package.json index 60b620c..adaec3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@methanium/ui", - "version": "0.0.25", + "version": "0.0.26", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/src/markdown/markdown.tsx b/src/markdown/markdown.tsx index 07caf8c..99a3338 100644 --- a/src/markdown/markdown.tsx +++ b/src/markdown/markdown.tsx @@ -38,6 +38,7 @@ import { EmojiProvider, useEmojiRegistry } from "./emoji-context"; import type { EmojiRegistry } from "./emoji-data"; import { parseCodeMeta, remarkCodeMeta } from "./markdown-meta"; import { remarkEmoji } from "./remark-emoji"; +import { remarkSmallMuted } from "./remark-small-muted"; export type MarkdownTheme = "light" | "dark"; export type MarkdownVariant = "article" | "compact"; @@ -147,6 +148,7 @@ function Markdown({ remarkMath, remarkBreaks, remarkCodeMeta, + remarkSmallMuted, [remarkEmoji, { registry }], ]; diff --git a/src/markdown/remark-small-muted.ts b/src/markdown/remark-small-muted.ts new file mode 100644 index 0000000..6beadd1 --- /dev/null +++ b/src/markdown/remark-small-muted.ts @@ -0,0 +1,45 @@ +import type { Emphasis, Parent, Root, Text } from "mdast"; +import { SKIP, visit } from "unist-util-visit"; + +const delimiter = "??++"; + +export function remarkSmallMuted() { + return (tree: Root) => { + visit(tree, "text", (node: Text, index, parent: Parent | undefined) => { + if (index === undefined || !parent) return; + + const children: Parent["children"] = []; + let cursor = 0; + let opening = node.value.indexOf(delimiter); + + while (opening !== -1) { + const contentStart = opening + delimiter.length; + const closing = node.value.indexOf(delimiter, contentStart); + if (closing === -1) break; + + if (opening > cursor) { + children.push({ type: "text", value: node.value.slice(cursor, opening) }); + } + children.push({ + type: "emphasis", + children: [{ type: "text", value: node.value.slice(contentStart, closing) }], + data: { + hName: "span", + hProperties: { className: ["text-xs", "text-muted-foreground"] }, + }, + } satisfies Emphasis); + + cursor = closing + delimiter.length; + opening = node.value.indexOf(delimiter, cursor); + } + + if (children.length === 0) return; + if (cursor < node.value.length) { + children.push({ type: "text", value: node.value.slice(cursor) }); + } + + parent.children.splice(index, 1, ...children); + return [SKIP, index + children.length]; + }); + }; +}