From 59c39fcc6e5ebcb259628ab192fcf0f67593fd03 Mon Sep 17 00:00:00 2001 From: "Mr.Hope" Date: Tue, 9 May 2023 16:40:51 +0800 Subject: [PATCH 1/2] feat: add presets --- docs/package.json | 2 +- package.json | 2 + packages/client-presets/package.json | 84 ++++ packages/client-presets/rollup.config.ts | 379 ++++++++++++++++++ .../src/captcha/recaptcha-v3.ts | 14 + .../client-presets/src/captcha/turnstile.ts | 44 ++ .../client-presets/src/highlighter/prismjs.ts | 28 ++ .../client-presets/src/highlighter/shiki.ts | 12 + .../client-presets/src/markdown/emoji-tex.ts | 18 + packages/client-presets/src/markdown/emoji.ts | 17 + .../src/markdown/markdown-it/emoji.ts | 8 + .../src/markdown/markdown-it/highlighter.ts | 6 + .../src/markdown/markdown-it/markdown-it.ts | 23 ++ .../src/markdown/markdown-it/tex.ts | 7 + .../src/markdown/marked/emoji.ts | 8 + .../src/markdown/marked/highlighter.ts | 8 + .../src/markdown/marked/marked.ts | 24 ++ .../client-presets/src/markdown/marked/tex.ts | 67 ++++ packages/client-presets/src/markdown/slim.ts | 3 + packages/client-presets/src/markdown/tex.ts | 4 + .../src/shims-marked-extension.d.ts | 28 ++ .../client-presets/src/shims-modules.d.ts | 21 + packages/client-presets/src/tex/katex.ts | 9 + packages/client-presets/src/tex/mathjax.ts | 35 ++ packages/client-presets/src/typings.ts | 9 + packages/client-presets/tsconfig.json | 12 + packages/client/package.json | 2 - pnpm-lock.yaml | 230 ++++++++++- 28 files changed, 1080 insertions(+), 24 deletions(-) create mode 100644 packages/client-presets/package.json create mode 100644 packages/client-presets/rollup.config.ts create mode 100644 packages/client-presets/src/captcha/recaptcha-v3.ts create mode 100644 packages/client-presets/src/captcha/turnstile.ts create mode 100644 packages/client-presets/src/highlighter/prismjs.ts create mode 100644 packages/client-presets/src/highlighter/shiki.ts create mode 100644 packages/client-presets/src/markdown/emoji-tex.ts create mode 100644 packages/client-presets/src/markdown/emoji.ts create mode 100644 packages/client-presets/src/markdown/markdown-it/emoji.ts create mode 100644 packages/client-presets/src/markdown/markdown-it/highlighter.ts create mode 100644 packages/client-presets/src/markdown/markdown-it/markdown-it.ts create mode 100644 packages/client-presets/src/markdown/markdown-it/tex.ts create mode 100644 packages/client-presets/src/markdown/marked/emoji.ts create mode 100644 packages/client-presets/src/markdown/marked/highlighter.ts create mode 100644 packages/client-presets/src/markdown/marked/marked.ts create mode 100644 packages/client-presets/src/markdown/marked/tex.ts create mode 100644 packages/client-presets/src/markdown/slim.ts create mode 100644 packages/client-presets/src/markdown/tex.ts create mode 100644 packages/client-presets/src/shims-marked-extension.d.ts create mode 100644 packages/client-presets/src/shims-modules.d.ts create mode 100644 packages/client-presets/src/tex/katex.ts create mode 100644 packages/client-presets/src/tex/mathjax.ts create mode 100644 packages/client-presets/src/typings.ts create mode 100644 packages/client-presets/tsconfig.json diff --git a/docs/package.json b/docs/package.json index bd6472f3b88..f7e28cd0fcc 100644 --- a/docs/package.json +++ b/docs/package.json @@ -12,7 +12,7 @@ "@vuepress/client": "2.0.0-beta.61", "@vuepress/plugin-docsearch": "2.0.0-beta.61", "@vuepress/utils": "2.0.0-beta.61", - "marked": "4.3.0", + "marked": "5.0.1", "vue": "3.2.47", "vuepress": "2.0.0-beta.61", "vuepress-plugin-redirect": "2.0.0-beta.208", diff --git a/package.json b/package.json index 02de7d8a18f..07570219a83 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,9 @@ "@babel/runtime": "7.21.5", "@commitlint/cli": "17.6.3", "@commitlint/config-conventional": "17.6.3", + "@rollup/plugin-alias": "5.0.0", "@rollup/plugin-commonjs": "24.1.0", + "@rollup/plugin-json": "6.0.0", "@rollup/plugin-node-resolve": "15.0.2", "@rollup/plugin-replace": "5.0.2", "@types/node": "20.1.1", diff --git a/packages/client-presets/package.json b/packages/client-presets/package.json new file mode 100644 index 00000000000..2a5941287b6 --- /dev/null +++ b/packages/client-presets/package.json @@ -0,0 +1,84 @@ +{ + "name": "@waline/client-presets", + "version": "0.1.0-alpha.0", + "description": "Presets for official Waline client", + "private": true, + "keywords": [ + "waline", + "presets" + ], + "repository": { + "url": "https://github.com/walinejs/waline", + "directory": "packages/client-presets" + }, + "license": "MIT", + "author": { + "name": "Mr.Hope", + "email": "mister-hope@outlook.com", + "url": "https://mrhope.site" + }, + "exports": { + "./recaptcha-v3": { + "types": "./dist/recaptcha-v3.d.mts", + "import": "./dist/recaptcha-v3.mjs", + "require": "./dist/recaptcha-v3.cjs" + }, + "./turnstile": { + "types": "./dist/turnstile.d.mts", + "import": "./dist/turnstile.mjs", + "require": "./dist/turnstile.cjs" + }, + "./package.json": "./package.json" + }, + "files": [ + "dist" + ], + "scripts": { + "build": "rollup -c rollup.config.ts --configPlugin esbuild='{target:\"esnext\"}'", + "clean": "rimraf ./dist", + "dev": "vite", + "prepublishOnly": "pnpm clean && pnpm build" + }, + "browserslist": { + "production": [ + ">0.5%", + "maintained node versions", + "not dead", + "not ie 11", + "not op_mini all", + "last 2 years" + ], + "development": [ + "last 2 chrome version", + "last 2 firefox version", + "last 2 safari version" + ] + }, + "engines": { + "node": ">=16" + }, + "dependencies": { + "@types/markdown-it-emoji": "^2.0.2", + "@types/katex": "0.16.0", + "@mdit/plugin-tex": "^0.4.5", + "@types/marked": "^4.3.0", + "@types/markdown-it": "^12.2.3", + "@types/prismjs": "^1.26.0", + "katex": "^0.16.7", + "mathjax-full": "^3.2.2", + "marked": "^5.0.1", + "marked-highlight": "^1.0.1", + "marked-emoji": "^1.0.1", + "markdown-it": "^13.0.1", + "markdown-it-emoji": "^2.0.2", + "prismjs": "^1.29.0", + "shiki": "^0.14.2" + }, + "devDependencies": { + "@types/node": "18.15.11", + "@vitejs/plugin-vue": "4.1.0", + "recaptcha-v3": "1.10.0", + "user-agent-data-types": "0.3.1", + "vite": "4.2.1" + } +} diff --git a/packages/client-presets/rollup.config.ts b/packages/client-presets/rollup.config.ts new file mode 100644 index 00000000000..647ed899d0d --- /dev/null +++ b/packages/client-presets/rollup.config.ts @@ -0,0 +1,379 @@ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import aliasPlugin from '@rollup/plugin-alias'; +import commonjs from '@rollup/plugin-commonjs'; +import jsonPlugin from '@rollup/plugin-json'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import { type RollupOptions } from 'rollup'; +import dts from 'rollup-plugin-dts'; +import esbuild from 'rollup-plugin-esbuild'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const markdownItMainPath = path.resolve( + __dirname, + './src/markdown/markdown-it/markdown-it.ts' +); +const markdownItEmojiPath = path.resolve( + __dirname, + './src/markdown/markdown-it/emoji.ts' +); +const markdownItTexPath = path.resolve( + __dirname, + './src/markdown/markdown-it/tex.ts' +); + +const markedMainPath = path.resolve( + __dirname, + './src/markdown/marked/marked.ts' +); +const markedEmojiPath = path.resolve( + __dirname, + './src/markdown/marked/emoji.ts' +); +const markedTexPath = path.resolve(__dirname, './src/markdown/marked/tex.ts'); + +const katexPath = path.resolve(__dirname, './src/tex/katex.ts'); +const mathjaxPath = path.resolve(__dirname, './src/tex/mathjax.ts'); + +interface JSOptions { + input: string; + output: string; + alias?: Record | null; + json?: boolean; +} + +export const getJs = ({ + input, + output, + alias = null, + json = false, +}: JSOptions): RollupOptions => ({ + input: `./src/${input}`, + output: [ + { + file: `./dist/${output}.cjs`, + format: 'cjs', + sourcemap: true, + }, + { + file: `./dist/${output}.mjs`, + format: 'esm', + sourcemap: true, + }, + ], + plugins: [ + alias ? aliasPlugin({ entries: alias }) : null, + json ? jsonPlugin() : null, + esbuild({ + charset: 'utf8', + target: ['chrome79', 'firefox79', 'edge79', 'safari13', 'node16'], + minify: true, + }), + nodeResolve({ preferBuiltins: true }), + commonjs(), + ], +}); + +interface DtsOptions { + input: string; + output: string; + alias?: Record | null; +} + +export const getDts = ({ + input, + output, + alias = null, +}: DtsOptions): RollupOptions => ({ + input: `./src/${input}`, + output: [ + { file: `./dist/${output}.d.cts`, format: 'esm' }, + { file: `./dist/${output}.d.mts`, format: 'esm' }, + ], + plugins: [ + alias ? aliasPlugin({ entries: alias }) : null, + dts({ compilerOptions: { preserveSymlinks: false } }), + ], +}); + +const captcha = [ + getJs({ + input: 'captcha/recaptcha-v3.ts', + output: 'recaptcha-v3', + }), + + getDts({ + input: 'captcha/recaptcha-v3.ts', + output: 'turnstile', + }), + + getJs({ + input: 'captcha/turnstile.ts', + output: 'recaptcha-v3', + }), + + getDts({ + input: 'captcha/turnstile.ts', + output: 'turnstile', + }), +]; + +const markdownSlim = [ + getJs({ + input: 'markdown/slim.ts', + output: 'markdown-it-slim', + alias: { + '@markdown/main': markdownItMainPath, + }, + json: true, + }), + + getDts({ + input: 'markdown/slim.ts', + output: 'markdown-it-slim', + alias: { + '@markdown/main': markdownItMainPath, + }, + }), + + getJs({ + input: 'markdown/slim.ts', + output: 'marked-slim', + alias: { + '@markdown/main': markedMainPath, + }, + }), + + getDts({ + input: 'markdown/slim.ts', + output: 'marked-slim', + alias: { + '@markdown/main': markedMainPath, + }, + }), +]; + +const markdownEmoji = [ + getJs({ + input: 'markdown/emoji.ts', + output: 'markdown-it-emoji', + alias: { + '@markdown/main': markdownItMainPath, + '@markdown/emoji': markdownItEmojiPath, + }, + json: true, + }), + + getDts({ + input: 'markdown/emoji.ts', + output: 'markdown-it-emoji', + alias: { + '@markdown/main': markdownItMainPath, + '@markdown/emoji': markdownItEmojiPath, + }, + }), + + getJs({ + input: 'markdown/emoji.ts', + output: 'marked-emoji', + alias: { + '@markdown/main': markedMainPath, + '@markdown/emoji': markedEmojiPath, + }, + }), + + getDts({ + input: 'markdown/emoji.ts', + output: 'marked-emoji', + alias: { + '@markdown/main': markedMainPath, + '@markdown/emoji': markedEmojiPath, + }, + }), +]; + +const markdownTex = [ + getJs({ + input: 'markdown/tex.ts', + output: 'markdown-it-katex', + alias: { + '@markdown/main': markdownItMainPath, + '@markdown/tex': markdownItTexPath, + '@tex': katexPath, + }, + json: true, + }), + + getDts({ + input: 'markdown/tex.ts', + output: 'markdown-it-slim', + alias: { + '@markdown/main': markdownItMainPath, + '@markdown/tex': markdownItTexPath, + '@tex': katexPath, + }, + }), + + getJs({ + input: 'markdown/tex.ts', + output: 'marked-katex', + alias: { + '@markdown/main': markedMainPath, + '@markdown/tex': markedTexPath, + '@tex': katexPath, + }, + }), + + getDts({ + input: 'markdown/tex.ts', + output: 'marked-katex', + alias: { + '@markdown/main': markedMainPath, + '@markdown/tex': markedTexPath, + '@tex': katexPath, + }, + }), + + getJs({ + input: 'markdown/tex.ts', + output: 'markdown-it-mathjax', + alias: { + '@markdown/main': markdownItMainPath, + '@markdown/tex': markdownItTexPath, + '@tex': mathjaxPath, + }, + json: true, + }), + + getDts({ + input: 'markdown/tex.ts', + output: 'markdown-it-mathjax', + alias: { + '@markdown/main': markdownItMainPath, + '@markdown/tex': markdownItTexPath, + '@tex': mathjaxPath, + }, + }), + + getJs({ + input: 'markdown/tex.ts', + output: 'marked-mathjax', + alias: { + '@markdown/main': markedMainPath, + '@markdown/tex': markedTexPath, + '@tex': mathjaxPath, + }, + }), + + getDts({ + input: 'markdown/tex.ts', + output: 'marked-mathjax', + alias: { + '@markdown/main': markedMainPath, + '@markdown/tex': markedTexPath, + '@tex': mathjaxPath, + }, + }), +]; + +const markdownEmojiTex = [ + getJs({ + input: 'markdown/emoji-tex.ts', + output: 'markdown-it-emoji-katex', + alias: { + '@markdown/main': markdownItMainPath, + '@markdown/emoji': markdownItEmojiPath, + '@markdown/tex': markdownItTexPath, + '@tex': katexPath, + }, + json: true, + }), + + getDts({ + input: 'markdown/emoji-tex.ts', + output: 'markdown-it-emoji-katex', + alias: { + '@markdown/main': markdownItMainPath, + '@markdown/emoji': markdownItEmojiPath, + '@markdown/tex': markdownItTexPath, + '@tex': katexPath, + }, + }), + + getJs({ + input: 'markdown/emoji-tex.ts', + output: 'marked-emoji-katex', + alias: { + '@markdown/main': markedMainPath, + '@markdown/emoji': markedEmojiPath, + '@markdown/tex': markedTexPath, + '@tex': katexPath, + }, + }), + + getDts({ + input: 'markdown/emoji-tex.ts', + output: 'marked-emoji-katex', + alias: { + '@markdown/main': markedMainPath, + '@markdown/emoji': markedEmojiPath, + '@markdown/tex': markedTexPath, + '@tex': katexPath, + }, + }), + + getJs({ + input: 'markdown/emoji-tex.ts', + output: 'markdown-it-emoji-mathjax', + alias: { + '@markdown/main': markdownItMainPath, + '@markdown/emoji': markdownItEmojiPath, + '@markdown/tex': markdownItTexPath, + '@tex': mathjaxPath, + }, + json: true, + }), + + getDts({ + input: 'markdown/emoji-tex.ts', + output: 'markdown-it-emoji-mathjax', + alias: { + '@markdown/main': markdownItMainPath, + '@markdown/emoji': markdownItEmojiPath, + '@markdown/tex': markdownItTexPath, + '@tex': mathjaxPath, + }, + }), + + getJs({ + input: 'markdown/emoji-tex.ts', + output: 'marked-emoji-mathjax', + alias: { + '@markdown/main': markedMainPath, + '@markdown/emoji': markedEmojiPath, + '@markdown/tex': markedTexPath, + '@tex': mathjaxPath, + }, + }), + + getDts({ + input: 'markdown/emoji-tex.ts', + output: 'marked-emoji-mathjax', + alias: { + '@markdown/main': markedMainPath, + '@markdown/emoji': markedEmojiPath, + '@markdown/tex': markedTexPath, + '@tex': mathjaxPath, + }, + }), +]; + +export default [ + ...captcha, + ...markdownSlim, + ...markdownEmoji, + ...markdownTex, + ...markdownEmojiTex, +]; diff --git a/packages/client-presets/src/captcha/recaptcha-v3.ts b/packages/client-presets/src/captcha/recaptcha-v3.ts new file mode 100644 index 00000000000..44f81501bc2 --- /dev/null +++ b/packages/client-presets/src/captcha/recaptcha-v3.ts @@ -0,0 +1,14 @@ +import { type ReCaptchaInstance, load } from 'recaptcha-v3'; + +import { CaptchaValidator } from '../typings.js'; + +const recaptchaStore: Record> = {}; + +export const getReCaptcha = (key: string): CaptchaValidator => { + const init = (recaptchaStore[key] ??= load(key, { + useRecaptchaNet: true, + autoHideBadge: true, + })); + + return (action) => init.then((instance) => instance.execute(action)); +}; diff --git a/packages/client-presets/src/captcha/turnstile.ts b/packages/client-presets/src/captcha/turnstile.ts new file mode 100644 index 00000000000..37b228888dc --- /dev/null +++ b/packages/client-presets/src/captcha/turnstile.ts @@ -0,0 +1,44 @@ +import { CaptchaValidator } from '../typings.js'; + +export interface TurnstileOptions { + sitekey: string; + action?: string; + size?: 'normal' | 'compact'; + callback?: (token: string) => void; +} +export interface TurnstileInstance { + ready: (fn: () => void) => void; + render: (className: string, options?: TurnstileOptions) => void; +} + +declare global { + interface Window { + turnstile?: TurnstileInstance; + } +} + +export const initTurnstile = + (key: string): CaptchaValidator => + (action) => + new Promise((resolve) => { + const script = document.createElement('script'); + + script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js'; + + script.onload = (): void => { + const turnstile = window?.turnstile; + + const options: TurnstileOptions = { + sitekey: key, + action, + size: 'compact', + callback(token: string): void { + resolve(token); + }, + }; + + turnstile?.ready(() => + turnstile?.render('.wl-captcha-container', options) + ); + }; + }); diff --git a/packages/client-presets/src/highlighter/prismjs.ts b/packages/client-presets/src/highlighter/prismjs.ts new file mode 100644 index 00000000000..a84c555eb8b --- /dev/null +++ b/packages/client-presets/src/highlighter/prismjs.ts @@ -0,0 +1,28 @@ +import prismjs from 'prismjs'; +import rawLoadLanguages from 'prismjs/components/index'; + +import { type Highlighter } from '../typings.js'; + +// prevent warning messages +rawLoadLanguages.silent = true; + +const loadLanguages = (languages: string[] = []): void => { + const langsToLoad = languages.filter((item) => !prismjs.languages[item]); + + if (langsToLoad.length) { + rawLoadLanguages(langsToLoad); + } +}; + +/** + * Resolve syntax highlighter for corresponding language + */ +export const highlighter: Highlighter = (code: string, language: string) => { + // try to load languages + loadLanguages([language]); + + return prismjs.languages[language] + ? prismjs.highlight(code, prismjs.languages[language], language) + : // do not highlight if current language could not be loaded + code; +}; diff --git a/packages/client-presets/src/highlighter/shiki.ts b/packages/client-presets/src/highlighter/shiki.ts new file mode 100644 index 00000000000..bf13565ed7e --- /dev/null +++ b/packages/client-presets/src/highlighter/shiki.ts @@ -0,0 +1,12 @@ +import { type Highlighter as ShikiHighlighter, getHighlighter } from 'shiki'; + +import { type Highlighter } from '../typings.js'; + +let shikiHighlighter: ShikiHighlighter; + +export const initHighlighter = async (): Promise => { + shikiHighlighter = await getHighlighter({}); +}; + +export const highlighter: Highlighter = (code, lang) => + shikiHighlighter.codeToHtml(code, { lang }); diff --git a/packages/client-presets/src/markdown/emoji-tex.ts b/packages/client-presets/src/markdown/emoji-tex.ts new file mode 100644 index 00000000000..e62a3cd9995 --- /dev/null +++ b/packages/client-presets/src/markdown/emoji-tex.ts @@ -0,0 +1,18 @@ +import { setEmojiParser } from '@markdown/emoji'; +import { getRenderer as _getRenderer } from '@markdown/main'; +import '@markdown/tex'; + +import { type EmojiMap, type MarkdownRenderer } from '../typings.js'; + +export interface RendererOptions { + emojiMap: EmojiMap; +} + +export const getRenderer = ({ + emojiMap, +}: RendererOptions): Promise => { + setEmojiParser(emojiMap); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return _getRenderer(); +}; diff --git a/packages/client-presets/src/markdown/emoji.ts b/packages/client-presets/src/markdown/emoji.ts new file mode 100644 index 00000000000..d30bedd28fe --- /dev/null +++ b/packages/client-presets/src/markdown/emoji.ts @@ -0,0 +1,17 @@ +import { setEmojiParser } from '@markdown/emoji'; +import { getRenderer as _getRenderer } from '@markdown/main'; + +import { type EmojiMap, type MarkdownRenderer } from '../typings.js'; + +export interface RendererOptions { + emojiMap: EmojiMap; +} + +export const getRenderer = ({ + emojiMap, +}: RendererOptions): Promise => { + setEmojiParser(emojiMap); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return _getRenderer(); +}; diff --git a/packages/client-presets/src/markdown/markdown-it/emoji.ts b/packages/client-presets/src/markdown/markdown-it/emoji.ts new file mode 100644 index 00000000000..337d8d3b09b --- /dev/null +++ b/packages/client-presets/src/markdown/markdown-it/emoji.ts @@ -0,0 +1,8 @@ +import emoji from 'markdown-it-emoji'; + +import { markdownIt } from './markdown-it.js'; +import { type EmojiMap } from '../../typings.js'; + +export const setEmojiParser = (emojiMap: EmojiMap): void => { + markdownIt.use(emoji, { defs: emojiMap, shortcuts: {} }); +}; diff --git a/packages/client-presets/src/markdown/markdown-it/highlighter.ts b/packages/client-presets/src/markdown/markdown-it/highlighter.ts new file mode 100644 index 00000000000..dff5f613d8f --- /dev/null +++ b/packages/client-presets/src/markdown/markdown-it/highlighter.ts @@ -0,0 +1,6 @@ +import { markdownIt } from './markdown-it.js'; +import { type Highlighter } from '../../typings.js'; + +export const setHighlighter = (highlighter: Highlighter): void => { + markdownIt.options.highlight = highlighter; +}; diff --git a/packages/client-presets/src/markdown/markdown-it/markdown-it.ts b/packages/client-presets/src/markdown/markdown-it/markdown-it.ts new file mode 100644 index 00000000000..abb0c876e69 --- /dev/null +++ b/packages/client-presets/src/markdown/markdown-it/markdown-it.ts @@ -0,0 +1,23 @@ +import MarkdownIt from 'markdown-it'; + +import { type MarkdownRenderer } from '../../typings.js'; + +// markdown-it instance +export const markdownIt = MarkdownIt({ + breaks: true, + // Auto convert URL-like text to links + linkify: true, + // Enable some language-neutral replacement + quotes beautification + typographer: true, + // should always enable html option due to parsed emoji + html: true, +}); + +export const preparation: Promise[] = []; + +export const getRenderer = (): Promise => + Promise.all(preparation).then( + () => + (content: string): string => + markdownIt.render(content) + ); diff --git a/packages/client-presets/src/markdown/markdown-it/tex.ts b/packages/client-presets/src/markdown/markdown-it/tex.ts new file mode 100644 index 00000000000..b1cdf0ecbac --- /dev/null +++ b/packages/client-presets/src/markdown/markdown-it/tex.ts @@ -0,0 +1,7 @@ +import { tex } from '@mdit/plugin-tex'; +import { texRenderer } from '@tex'; + +import { markdownIt } from './markdown-it.js'; + +// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment +markdownIt.use(tex, { render: texRenderer }); diff --git a/packages/client-presets/src/markdown/marked/emoji.ts b/packages/client-presets/src/markdown/marked/emoji.ts new file mode 100644 index 00000000000..2b7d9913bd2 --- /dev/null +++ b/packages/client-presets/src/markdown/marked/emoji.ts @@ -0,0 +1,8 @@ +import { markedEmoji } from 'marked-emoji'; + +import { marked } from './marked.js'; +import { type EmojiMap } from '../../typings.js'; + +export const setEmojiParser = (emojiMap: EmojiMap): void => { + marked.use(markedEmoji({ emojis: emojiMap })); +}; diff --git a/packages/client-presets/src/markdown/marked/highlighter.ts b/packages/client-presets/src/markdown/marked/highlighter.ts new file mode 100644 index 00000000000..57ee65f2f59 --- /dev/null +++ b/packages/client-presets/src/markdown/marked/highlighter.ts @@ -0,0 +1,8 @@ +import { markedHighlight } from 'marked-highlight'; + +import { marked } from './marked.js'; +import { type Highlighter } from '../../typings.js'; + +export const setHighlighter = (highlighter: Highlighter): void => { + marked.use(markedHighlight({ highlight: highlighter })); +}; diff --git a/packages/client-presets/src/markdown/marked/marked.ts b/packages/client-presets/src/markdown/marked/marked.ts new file mode 100644 index 00000000000..ea0e1830e6a --- /dev/null +++ b/packages/client-presets/src/markdown/marked/marked.ts @@ -0,0 +1,24 @@ +import { marked } from 'marked'; + +import { type MarkdownRenderer } from '../../typings.js'; + +marked.setOptions({ + breaks: true, + smartLists: true, + smartypants: true, +}); + +export { marked }; + +export const preparation: Promise[] = []; + +export const parseMarkdown = (content: string): string => { + return marked.parse(content); +}; + +export const getRenderer = (): Promise => + Promise.all(preparation).then( + () => + (content: string): string => + marked.parse(content) + ); diff --git a/packages/client-presets/src/markdown/marked/tex.ts b/packages/client-presets/src/markdown/marked/tex.ts new file mode 100644 index 00000000000..6bfbd6df25d --- /dev/null +++ b/packages/client-presets/src/markdown/marked/tex.ts @@ -0,0 +1,67 @@ +import { texRenderer } from '@tex'; +import { type marked as Marked } from 'marked'; + +import { marked } from './marked.js'; +import { type TexRenderer } from '../../typings.js'; + +const INLINE_TEX_START = /\$.*?\$/; +const INLINE_TEX_REG = /^\$(.*?)\$/; +const BLOCK_TEX_REG = /^(?:\s{0,3})\$\$((?:[^\n]|\n[^\n])+?)\n{0,1}\$\$/; + +interface TexToken extends Marked.Tokens.Generic { + type: 'block-tex' | 'inline-tex'; + text: string; + raw: string; +} + +export const markedTex = (texRenderer: TexRenderer): Marked.MarkedExtension => { + const blockMathExtension: Marked.TokenizerAndRendererExtension = { + name: 'block-tex', + level: 'block', + start: (src) => src.indexOf('\n$$'), + tokenizer: (src) => { + const match = BLOCK_TEX_REG.exec(src); + + if (match) { + return { + type: 'block-tex', + raw: match[0], + text: match[1], + }; + } + + return; + }, + // eslint-disable-next-line + renderer: (token) => texRenderer((token).text, true), + }; + + const inlineMathExtension: Marked.TokenizerAndRendererExtension = { + name: 'inline-tex', + level: 'inline', + start: (src) => { + const index = src.search(INLINE_TEX_START); + + return index !== -1 ? index : src.length; + }, + tokenizer(src) { + const match = INLINE_TEX_REG.exec(src); + + if (match) { + return { + type: 'inline-tex', + raw: match[0], + text: match[1], + }; + } + + return; + }, + // eslint-disable-next-line + renderer: (token) => texRenderer((token).text, false), + }; + + return { extensions: [blockMathExtension, inlineMathExtension] }; +}; + +marked.use(markedTex(texRenderer)); diff --git a/packages/client-presets/src/markdown/slim.ts b/packages/client-presets/src/markdown/slim.ts new file mode 100644 index 00000000000..46e7b884aeb --- /dev/null +++ b/packages/client-presets/src/markdown/slim.ts @@ -0,0 +1,3 @@ +import { getRenderer } from '@markdown/main'; + +export { getRenderer }; diff --git a/packages/client-presets/src/markdown/tex.ts b/packages/client-presets/src/markdown/tex.ts new file mode 100644 index 00000000000..a5f4011ecaa --- /dev/null +++ b/packages/client-presets/src/markdown/tex.ts @@ -0,0 +1,4 @@ +import { getRenderer } from '@markdown/main'; +import '@markdown/tex'; + +export { getRenderer }; diff --git a/packages/client-presets/src/shims-marked-extension.d.ts b/packages/client-presets/src/shims-marked-extension.d.ts new file mode 100644 index 00000000000..82855fd8923 --- /dev/null +++ b/packages/client-presets/src/shims-marked-extension.d.ts @@ -0,0 +1,28 @@ +declare module 'marked-emoji' { + import { type marked } from 'marked'; + + export interface MarkedEmojiOptions { + emojis: Record; + /** + * @default false + */ + unicode?: boolean; + } + + export const markedEmoji: ( + options: MarkedEmojiOptions + ) => marked.MarkedExtension; +} + +declare module 'marked-highlight' { + import { type marked } from 'marked'; + + export interface MarkedHighlightOptions { + langPrefix?: string; + highlight?: (code: string, lang: string) => string; + } + + export const markedHighlight: ( + options: MarkedHighlightOptions + ) => marked.MarkedExtension; +} diff --git a/packages/client-presets/src/shims-modules.d.ts b/packages/client-presets/src/shims-modules.d.ts new file mode 100644 index 00000000000..db8bea3808b --- /dev/null +++ b/packages/client-presets/src/shims-modules.d.ts @@ -0,0 +1,21 @@ +declare module '@markdown/main' { + import { type MarkdownRenderer } from './typings.js'; + + export const getRenderer: () => Promise; +} + +declare module '@markdown/emoji' { + import { type EmojiMap } from './typings.js'; + + export const setEmojiParser: (emojiMap: EmojiMap) => void; +} + +declare module '@markdown/tex' { + export {}; +} + +declare module '@tex' { + import { type TexRenderer } from './typings.js'; + + export const texRenderer: TexRenderer; +} diff --git a/packages/client-presets/src/tex/katex.ts b/packages/client-presets/src/tex/katex.ts new file mode 100644 index 00000000000..8d233c7043a --- /dev/null +++ b/packages/client-presets/src/tex/katex.ts @@ -0,0 +1,9 @@ +import katex from 'katex'; + +import { type TexRenderer } from '../typings.js'; + +export const texRenderer: TexRenderer = (tex, displayMode) => + katex.renderToString(tex, { + displayMode, + throwOnError: false, + }); diff --git a/packages/client-presets/src/tex/mathjax.ts b/packages/client-presets/src/tex/mathjax.ts new file mode 100644 index 00000000000..24be29a70fc --- /dev/null +++ b/packages/client-presets/src/tex/mathjax.ts @@ -0,0 +1,35 @@ +/** + * Forked from https://github.com/tani/markdown-it-mathjax3/blob/master/index.ts + */ + +import { type LiteElement } from 'mathjax-full/js/adaptors/lite/Element.js'; +import { liteAdaptor } from 'mathjax-full/js/adaptors/liteAdaptor.js'; +import { AllPackages } from 'mathjax-full/js/input/tex/AllPackages.js'; +import { TeX } from 'mathjax-full/js/input/tex.js'; +import { mathjax as MathJax } from 'mathjax-full/js/mathjax.js'; +import { SVG } from 'mathjax-full/js/output/svg.js'; + +import { type TexRenderer } from '../typings.js'; + +const adaptor = liteAdaptor(); + +const InputJax = new TeX({ + packages: AllPackages, +}); + +const OutputJax = new SVG({ + fontCache: 'none', +}); + +export const texRenderer: TexRenderer = (tex, displayMode) => { + InputJax.reset(); + + /* eslint-disable */ + const mathDocument = MathJax.document(tex, { InputJax, OutputJax }).convert( + tex, + { display: displayMode } + ); + const html = adaptor.outerHTML(mathDocument); + + return html; +}; diff --git a/packages/client-presets/src/typings.ts b/packages/client-presets/src/typings.ts new file mode 100644 index 00000000000..a78c43c8ee5 --- /dev/null +++ b/packages/client-presets/src/typings.ts @@ -0,0 +1,9 @@ +export type CaptchaValidator = (token: string) => Promise; + +export type EmojiMap = Record; + +export type Highlighter = (code: string, lang: string) => string; + +export type MarkdownRenderer = (markdown: string) => string; + +export type TexRenderer = (tex: string, displayMode: boolean) => string; diff --git a/packages/client-presets/tsconfig.json b/packages/client-presets/tsconfig.json new file mode 100644 index 00000000000..ef9a6836409 --- /dev/null +++ b/packages/client-presets/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noImplicitAny": false, + "noUnusedParameters": false, + "jsx": "preserve", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "rootDir": "./src" + }, + "include": ["./src"] +} diff --git a/packages/client/package.json b/packages/client/package.json index 78c83ea15dd..fb52a5a0990 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -93,8 +93,6 @@ "@vueuse/core": "^10.1.2", "@waline/api": "workspace:*", "autosize": "^6.0.1", - "marked": "^4.3.0", - "recaptcha-v3": "1.10.0", "vue": "^3.2.47" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3099b97b279..aa0f641673a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,9 +28,15 @@ importers: '@commitlint/config-conventional': specifier: 17.6.3 version: 17.6.3 + '@rollup/plugin-alias': + specifier: 5.0.0 + version: 5.0.0(rollup@3.21.5) '@rollup/plugin-commonjs': specifier: 24.1.0 version: 24.1.0(rollup@3.21.5) + '@rollup/plugin-json': + specifier: 6.0.0 + version: 6.0.0(rollup@3.21.5) '@rollup/plugin-node-resolve': specifier: 15.0.2 version: 15.0.2(rollup@3.21.5) @@ -170,8 +176,8 @@ importers: specifier: 2.0.0-beta.61 version: 2.0.0-beta.61 marked: - specifier: 4.3.0 - version: 4.3.0 + specifier: 5.0.1 + version: 5.0.1 vue: specifier: 3.2.47 version: 3.2.47 @@ -252,12 +258,6 @@ importers: autosize: specifier: ^6.0.1 version: 6.0.1 - marked: - specifier: ^4.3.0 - version: 4.3.0 - recaptcha-v3: - specifier: 1.10.0 - version: 1.10.0 vue: specifier: ^3.2.47 version: 3.2.47 @@ -284,6 +284,70 @@ importers: specifier: 4.3.5 version: 4.3.5(@types/node@20.1.1)(sass@1.62.1) + packages/client-presets: + dependencies: + '@mdit/plugin-tex': + specifier: ^0.4.5 + version: 0.4.5 + '@types/katex': + specifier: 0.16.0 + version: 0.16.0 + '@types/markdown-it': + specifier: ^12.2.3 + version: 12.2.3 + '@types/markdown-it-emoji': + specifier: ^2.0.2 + version: 2.0.2 + '@types/marked': + specifier: ^4.3.0 + version: 4.3.0 + '@types/prismjs': + specifier: ^1.26.0 + version: 1.26.0 + katex: + specifier: ^0.16.7 + version: 0.16.7 + markdown-it: + specifier: ^13.0.1 + version: 13.0.1 + markdown-it-emoji: + specifier: ^2.0.2 + version: 2.0.2 + marked: + specifier: ^5.0.1 + version: 5.0.1 + marked-emoji: + specifier: ^1.0.1 + version: 1.0.1(marked@5.0.1) + marked-highlight: + specifier: ^1.0.1 + version: 1.0.1(marked@5.0.1) + mathjax-full: + specifier: ^3.2.2 + version: 3.2.2 + prismjs: + specifier: ^1.29.0 + version: 1.29.0 + shiki: + specifier: ^0.14.2 + version: 0.14.2 + devDependencies: + '@types/node': + specifier: 18.15.11 + version: 18.15.11 + '@vitejs/plugin-vue': + specifier: 4.1.0 + version: 4.1.0(vite@4.2.1)(vue@3.2.47) + recaptcha-v3: + specifier: 1.10.0 + version: 1.10.0 + user-agent-data-types: + specifier: 0.3.1 + version: 0.3.1 + vite: + specifier: 4.2.1 + version: 4.2.1(@types/node@18.15.11)(sass@1.62.1) + packages/cloudbase: dependencies: '@waline/vercel': @@ -3270,6 +3334,13 @@ packages: markdown-it: 13.0.1 dev: true + /@mdit/plugin-tex@0.4.5: + resolution: {integrity: sha512-L7ekZLMdzBNqsHzFS00ULyV+6ADtNAw5n7wN48qkE63K7QRWpXKEdXkNQ3LyaUwPCfSm1GgUv/QzI7SYiiL6jg==} + engines: {node: '>= 14'} + dependencies: + '@types/markdown-it': 12.2.3 + markdown-it: 13.0.1 + /@mdit/plugin-uml@0.4.4: resolution: {integrity: sha512-ArTrLQLa0pCxSrKHLSjNr3bPrxP6jhHDXYU35M2zayU5rTSPLWg9wrTRTD0TOvj6HVI331CGziO8hsy9QQSqlA==} engines: {node: '>= 14'} @@ -3310,7 +3381,7 @@ packages: resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} dependencies: '@gar/promisify': 1.1.3 - semver: 7.3.8 + semver: 7.5.0 /@npmcli/move-file@1.1.2: resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} @@ -3364,6 +3435,19 @@ packages: source-map: 0.7.4 dev: true + /@rollup/plugin-alias@5.0.0(rollup@3.21.5): + resolution: {integrity: sha512-l9hY5chSCjuFRPsnRm16twWBiSApl2uYFLsepQYwtBuAxNMQ/1dJqADld40P0Jkqm65GRTLy/AC6hnpVebtLsA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + rollup: 3.21.5 + slash: 4.0.0 + dev: true + /@rollup/plugin-babel@5.3.1(@babel/core@7.21.8)(rollup@2.79.1): resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} @@ -3399,6 +3483,19 @@ packages: rollup: 3.21.5 dev: true + /@rollup/plugin-json@6.0.0(rollup@3.21.5): + resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.0.2(rollup@3.21.5) + rollup: 3.21.5 + dev: true + /@rollup/plugin-node-resolve@11.2.1(rollup@2.79.1): resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==} engines: {node: '>= 10.0.0'} @@ -3695,7 +3792,6 @@ packages: /@types/katex@0.16.0: resolution: {integrity: sha512-hz+S3nV6Mym5xPbT9fnO8dDhBFQguMYpY0Ipxv06JMi1ORgnEM4M1ymWDUhUNer3ElLmT583opRo4RzxKmh9jw==} - dev: true /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} @@ -3705,24 +3801,20 @@ packages: /@types/linkify-it@3.0.2: resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==} - dev: true /@types/markdown-it-emoji@2.0.2: resolution: {integrity: sha512-2ln8Wjbcj/0oRi/6VnuMeWEHHuK8uapFttvcLmDIe1GKCsFBLOLBX+D+xhDa9oWOQV0IpvxwrSfKKssAqqroog==} dependencies: '@types/markdown-it': 12.2.3 - dev: true /@types/markdown-it@12.2.3: resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} dependencies: '@types/linkify-it': 3.0.2 '@types/mdurl': 1.0.2 - dev: true /@types/marked@4.3.0: resolution: {integrity: sha512-zK4gSFMjgslsv5Lyvr3O1yCjgmnE4pr8jbG8qVn4QglMwtpvPCf4YT2Wma7Nk95OxUUJI8Z+kzdXohbM7mVpGw==} - dev: true /@types/mdast@3.0.11: resolution: {integrity: sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==} @@ -3732,7 +3824,6 @@ packages: /@types/mdurl@1.0.2: resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} - dev: true /@types/minimatch@5.1.2: resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} @@ -3765,6 +3856,10 @@ packages: resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} dev: true + /@types/node@18.15.11: + resolution: {integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==} + dev: true + /@types/node@20.1.1: resolution: {integrity: sha512-uKBEevTNb+l6/aCQaKVnUModfEMjAl98lw2Si9P5y4hLu9tm6AlX2ZIoXZX6Wh9lJueYPrGPKk5WMCNHg/u6/A==} @@ -3772,6 +3867,10 @@ packages: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true + /@types/prismjs@1.26.0: + resolution: {integrity: sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==} + dev: false + /@types/prop-types@15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} dev: true @@ -3807,7 +3906,7 @@ packages: /@types/sax@1.2.4: resolution: {integrity: sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==} dependencies: - '@types/node': 17.0.45 + '@types/node': 20.1.1 dev: true /@types/scheduler@0.16.3: @@ -4228,7 +4327,7 @@ packages: recast: 0.21.5 remark-frontmatter: 4.0.1 remark-mdx-frontmatter: 1.1.1 - semver: 7.3.8 + semver: 7.5.0 sort-package-json: 1.57.0 tar-fs: 2.1.1 tsconfig-paths: 4.2.0 @@ -4297,6 +4396,17 @@ packages: - supports-color dev: true + /@vitejs/plugin-vue@4.1.0(vite@4.2.1)(vue@3.2.47): + resolution: {integrity: sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.0.0 + vue: ^3.2.25 + dependencies: + vite: 4.2.1(@types/node@18.15.11)(sass@1.62.1) + vue: 3.2.47 + dev: true + /@vitejs/plugin-vue@4.2.1(vite@4.1.4)(vue@3.2.47): resolution: {integrity: sha512-ZTZjzo7bmxTRTkb8GSTwkPOYDIP7pwuyV+RV53c9PYUouwcbkIZIvWvNWlX2b1dYZqtOv7D6iUAnJLVNGcLrSw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -5134,6 +5244,10 @@ packages: engines: {node: '>=12'} dev: true + /ansi-sequence-parser@1.1.0: + resolution: {integrity: sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==} + dev: false + /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -9079,7 +9193,7 @@ packages: '@types/glob': 7.2.0 array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.2.11 + fast-glob: 3.2.12 glob: 7.2.3 ignore: 5.2.4 merge2: 1.4.1 @@ -10270,7 +10384,6 @@ packages: /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - dev: true /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -11041,10 +11154,32 @@ packages: markdownlint-micromark: 0.1.2 dev: true + /marked-emoji@1.0.1(marked@5.0.1): + resolution: {integrity: sha512-1qSdZ078ySSIYSupZZ37YT4iV8mc1Na6oay6vx610lW6ZgU00kVjLcwGqS0NMBh5Rn8CmGHAwFtgUj1Vp+lnTg==} + peerDependencies: + marked: ^4.2.4 + dependencies: + marked: 5.0.1 + dev: false + + /marked-highlight@1.0.1(marked@5.0.1): + resolution: {integrity: sha512-dL9nk6dDRJ0BiSfhEilY0SWGgAgJTea9BY80rVHSEeZCECIqR3ytkvQEhlDYV7eOJ03GUUlqYcCtJKkymVMj8A==} + peerDependencies: + marked: ^4 || ^5 + dependencies: + marked: 5.0.1 + dev: false + /marked@4.3.0: resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} engines: {node: '>= 12'} hasBin: true + dev: true + + /marked@5.0.1: + resolution: {integrity: sha512-Nn9peC4lvIZdcfp8Uze6xk4ZYowkcj/K6+e/6rLHadhtjqeip/bYRxMgt3124IGGJ3RPs2uX5YVmAGbUutY18g==} + engines: {node: '>= 18'} + hasBin: true /mathjax-full@3.2.2: resolution: {integrity: sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==} @@ -13355,7 +13490,7 @@ packages: /recaptcha-v3@1.10.0: resolution: {integrity: sha512-aGTxYSk3FFNKnXeKDbLpgRDRyIHRZNBF5HyaXXAN1Aj4TSyyZvmoAn9CylvpqLV3pYpIQavwc+2rzhNFn5SsLQ==} - dev: false + dev: true /recast@0.21.5: resolution: {integrity: sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg==} @@ -13886,6 +14021,7 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 + dev: true /semver@7.5.0: resolution: {integrity: sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==} @@ -13974,6 +14110,15 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + /shiki@0.14.2: + resolution: {integrity: sha512-ltSZlSLOuSY0M0Y75KA+ieRaZ0Trf5Wl3gutE7jzLuIcWxLp5i/uEnLoQWNvgKXQ5OMpGkJnVMRLAuzjc0LJ2A==} + dependencies: + ansi-sequence-parser: 1.1.0 + jsonc-parser: 3.2.0 + vscode-oniguruma: 1.7.0 + vscode-textmate: 8.0.0 + dev: false + /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: @@ -16010,6 +16155,41 @@ packages: fsevents: 2.3.2 dev: true + /vite@4.2.1(@types/node@18.15.11)(sass@1.62.1): + resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.15.11 + esbuild: 0.17.18 + postcss: 8.4.23 + resolve: 1.22.2 + rollup: 3.21.5 + sass: 1.62.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /vite@4.3.5(@types/node@20.1.1)(sass@1.62.1): resolution: {integrity: sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -16123,6 +16303,14 @@ packages: engines: {node: '>=0.10.0'} dev: true + /vscode-oniguruma@1.7.0: + resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} + dev: false + + /vscode-textmate@8.0.0: + resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} + dev: false + /vue-demi@0.14.0(vue@3.2.47): resolution: {integrity: sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==} engines: {node: '>=12'} @@ -16434,7 +16622,7 @@ packages: '@mdit/plugin-sup': 0.4.4 '@mdit/plugin-tab': 0.4.4 '@mdit/plugin-tasklist': 0.4.4 - '@mdit/plugin-tex': 0.4.4 + '@mdit/plugin-tex': 0.4.5 '@mdit/plugin-uml': 0.4.4 '@types/js-yaml': 4.0.5 '@types/markdown-it': 12.2.3 From 01a4b1035e342d7bfeb028300389e43b8779a266 Mon Sep 17 00:00:00 2001 From: "Mr.Hope" Date: Wed, 10 May 2023 12:55:57 +0800 Subject: [PATCH 2/2] chore: tweaks --- .../src/markdown/markdown-it/highlighter.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/client-presets/src/markdown/markdown-it/highlighter.ts b/packages/client-presets/src/markdown/markdown-it/highlighter.ts index dff5f613d8f..8e1ab530374 100644 --- a/packages/client-presets/src/markdown/markdown-it/highlighter.ts +++ b/packages/client-presets/src/markdown/markdown-it/highlighter.ts @@ -1,6 +1,15 @@ +import { type PluginWithOptions } from 'markdown-it'; + import { markdownIt } from './markdown-it.js'; import { type Highlighter } from '../../typings.js'; -export const setHighlighter = (highlighter: Highlighter): void => { +export const highlight: PluginWithOptions = ( + markdownIt, + highlighter +) => { markdownIt.options.highlight = highlighter; }; + +export const setHighlighter = (highlighter: Highlighter): void => { + markdownIt.use(highlight, highlighter); +};