diff --git a/packages/carta-md/package-lock.json b/packages/carta-md/package-lock.json deleted file mode 100644 index 4a7cb36..0000000 --- a/packages/carta-md/package-lock.json +++ /dev/null @@ -1,656 +0,0 @@ -{ - "name": "carta-md", - "version": "3.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "carta-md", - "version": "3.0.0", - "license": "MIT", - "dependencies": { - "prismjs": "^1.29.0", - "rehype-stringify": "^10.0.0", - "remark-gfm": "^4.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.1.0", - "shiki": "^1.4.0", - "unified": "^11.0.4" - }, - "devDependencies": { - "@sveltejs/adapter-auto": "^3.1.1", - "@sveltejs/kit": "^2.5.4", - "@sveltejs/package": "^2.3.0", - "@sveltejs/vite-plugin-svelte": "^3.0.2", - "@types/prismjs": "^1.26.4", - "svelte-check": "^3.6.7", - "tslib": "^2.4.1", - "typescript": "^5.1.6", - "vite": "^5.1.6" - }, - "peerDependencies": { - "svelte": "^3.54.0 || ^4.0.0" - } - }, - "../../node_modules/.pnpm/@sveltejs+adapter-auto@3.1.1_@sveltejs+kit@2.5.4/node_modules/@sveltejs/adapter-auto": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "import-meta-resolve": "^4.0.0" - }, - "devDependencies": { - "@sveltejs/kit": "^2.4.1", - "@sveltejs/vite-plugin-svelte": "^3.0.1", - "@types/node": "^18.19.3", - "typescript": "^5.3.3" - }, - "peerDependencies": { - "@sveltejs/kit": "^2.0.0" - } - }, - "../../node_modules/.pnpm/@sveltejs+kit@2.5.4_@sveltejs+vite-plugin-svelte@3.0.2_svelte@4.2.2_vite@5.1.6/node_modules/@sveltejs/kit": { - "version": "2.5.4", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@types/cookie": "^0.6.0", - "cookie": "^0.6.0", - "devalue": "^4.3.2", - "esm-env": "^1.0.0", - "import-meta-resolve": "^4.0.0", - "kleur": "^4.1.5", - "magic-string": "^0.30.5", - "mrmime": "^2.0.0", - "sade": "^1.8.1", - "set-cookie-parser": "^2.6.0", - "sirv": "^2.0.4", - "tiny-glob": "^0.2.9" - }, - "bin": { - "svelte-kit": "svelte-kit.js" - }, - "devDependencies": { - "@playwright/test": "^1.41.0", - "@sveltejs/vite-plugin-svelte": "^3.0.1", - "@types/connect": "^3.4.38", - "@types/node": "^18.19.3", - "@types/sade": "^1.7.8", - "@types/set-cookie-parser": "^2.4.7", - "dts-buddy": "^0.4.3", - "rollup": "^4.9.5", - "svelte": "^4.2.10", - "svelte-preprocess": "^5.1.3", - "typescript": "^5.3.3", - "vite": "^5.1.0", - "vitest": "^1.2.0" - }, - "engines": { - "node": ">=18.13" - }, - "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3" - } - }, - "../../node_modules/.pnpm/@sveltejs+package@2.3.0_svelte@4.2.2_typescript@5.1.6/node_modules/@sveltejs/package": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chokidar": "^3.6.0", - "kleur": "^4.1.5", - "sade": "^1.8.1", - "semver": "^7.5.4", - "svelte2tsx": "~0.7.0" - }, - "bin": { - "svelte-package": "svelte-package.js" - }, - "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.1", - "@types/node": "^18.19.3", - "@types/semver": "^7.5.6", - "svelte": "^4.2.10", - "svelte-preprocess": "^5.1.3", - "typescript": "^5.3.3", - "uvu": "^0.5.6" - }, - "engines": { - "node": "^16.14 || >=18" - }, - "peerDependencies": { - "svelte": "^3.44.0 || ^4.0.0 || ^5.0.0-next.1" - } - }, - "../../node_modules/.pnpm/@sveltejs+vite-plugin-svelte@3.0.2_svelte@4.2.2_vite@5.1.6/node_modules/@sveltejs/vite-plugin-svelte": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^2.0.0", - "debug": "^4.3.4", - "deepmerge": "^4.3.1", - "kleur": "^4.1.5", - "magic-string": "^0.30.5", - "svelte-hmr": "^0.15.3", - "vitefu": "^0.2.5" - }, - "devDependencies": { - "@types/debug": "^4.1.12", - "esbuild": "^0.19.12", - "sass": "^1.70.0", - "svelte": "^4.2.9", - "vite": "^5.0.11" - }, - "engines": { - "node": "^18.0.0 || >=20" - }, - "peerDependencies": { - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" - } - }, - "../../node_modules/.pnpm/prismjs@1.29.0/node_modules/prismjs": { - "version": "1.29.0", - "license": "MIT", - "devDependencies": { - "@types/node-fetch": "^2.5.5", - "benchmark": "^2.1.4", - "chai": "^4.2.0", - "danger": "^10.5.0", - "del": "^4.1.1", - "docdash": "^1.2.0", - "eslint": "^7.22.0", - "eslint-plugin-jsdoc": "^32.3.0", - "eslint-plugin-regexp": "^1.6.0", - "gulp": "^4.0.2", - "gulp-clean-css": "^4.3.0", - "gulp-concat": "^2.3.4", - "gulp-header": "^2.0.7", - "gulp-jsdoc3": "^3.0.0", - "gulp-rename": "^1.2.0", - "gulp-replace": "^1.0.0", - "gulp-terser": "^2.1.0", - "gzip-size": "^5.1.1", - "htmlparser2": "^4.0.0", - "http-server": "^0.12.3", - "jsdom": "^16.7.0", - "mocha": "^9.2.2", - "node-fetch": "^3.1.1", - "npm-run-all": "^4.1.5", - "prettier": "^2.4.1", - "pump": "^3.0.0", - "refa": "^0.9.1", - "regexp-ast-analysis": "^0.2.4", - "regexpp": "^3.2.0", - "scslre": "^0.1.6", - "simple-git": "^3.3.0", - "webfont": "^9.0.0", - "yargs": "^13.2.2" - }, - "engines": { - "node": ">=6" - } - }, - "../../node_modules/.pnpm/rehype-stringify@10.0.0/node_modules/rehype-stringify": { - "version": "10.0.0", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-to-html": "^9.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "../../node_modules/.pnpm/remark-gfm@4.0.0/node_modules/remark-gfm": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "devDependencies": { - "@types/node": "^20.0.0", - "c8": "^8.0.0", - "is-hidden": "^2.0.0", - "prettier": "^3.0.0", - "remark": "^15.0.0", - "remark-cli": "^11.0.0", - "remark-preset-wooorm": "^9.0.0", - "string-width": "^6.0.0", - "to-vfile": "^8.0.0", - "type-coverage": "^2.0.0", - "typescript": "^5.0.0", - "xo": "^0.56.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "../../node_modules/.pnpm/remark-parse@11.0.0/node_modules/remark-parse": { - "version": "11.0.0", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "../../node_modules/.pnpm/remark-rehype@11.1.0/node_modules/remark-rehype": { - "version": "11.1.0", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "devDependencies": { - "@types/node": "^20.0.0", - "c8": "^9.0.0", - "prettier": "^3.0.0", - "rehype-stringify": "^10.0.0", - "remark-cli": "^11.0.0", - "remark-parse": "^11.0.0", - "remark-preset-wooorm": "^9.0.0", - "remark-stringify": "^11.0.0", - "type-coverage": "^2.0.0", - "typescript": "^5.0.0", - "xo": "^0.56.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "../../node_modules/.pnpm/shiki@1.4.0/node_modules/shiki": { - "version": "1.4.0", - "license": "MIT", - "dependencies": { - "@shikijs/core": "1.4.0" - }, - "devDependencies": { - "tm-grammars": "^1.7.2", - "tm-themes": "^1.4.1", - "vscode-oniguruma": "^1.7.0" - } - }, - "../../node_modules/.pnpm/svelte-check@3.6.7_postcss@8.4.31_svelte@4.2.2/node_modules/svelte-check": { - "version": "3.6.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", - "chokidar": "^3.4.1", - "fast-glob": "^3.2.7", - "import-fresh": "^3.2.1", - "picocolors": "^1.0.0", - "sade": "^1.7.4", - "svelte-preprocess": "^5.1.3", - "typescript": "^5.0.3" - }, - "bin": { - "svelte-check": "bin/svelte-check" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^24.0.0", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.0.0", - "@rollup/plugin-replace": "5.0.2", - "@rollup/plugin-typescript": "^10.0.0", - "@types/sade": "^1.7.2", - "builtin-modules": "^3.3.0", - "rollup": "3.7.5", - "rollup-plugin-cleanup": "^3.2.0", - "rollup-plugin-copy": "^3.4.0", - "svelte-language-server": "0.16.0", - "vscode-languageserver": "8.0.2", - "vscode-languageserver-protocol": "3.17.2", - "vscode-languageserver-types": "3.17.2", - "vscode-uri": "~3.0.0" - }, - "peerDependencies": { - "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" - } - }, - "../../node_modules/.pnpm/svelte@4.2.2/node_modules/svelte": { - "version": "4.2.2", - "license": "MIT", - "peer": true, - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "acorn": "^8.9.0", - "aria-query": "^5.3.0", - "axobject-query": "^3.2.1", - "code-red": "^1.0.3", - "css-tree": "^2.3.1", - "estree-walker": "^3.0.3", - "is-reference": "^3.0.1", - "locate-character": "^3.0.0", - "magic-string": "^0.30.4", - "periscopic": "^3.1.0" - }, - "devDependencies": { - "@playwright/test": "^1.35.1", - "@rollup/plugin-commonjs": "^24.1.0", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.1.0", - "@sveltejs/eslint-config": "^6.0.4", - "@types/aria-query": "^5.0.1", - "@types/estree": "^1.0.1", - "@types/node": "^14.18.51", - "agadoo": "^3.0.0", - "dts-buddy": "^0.1.7", - "esbuild": "^0.18.11", - "eslint-plugin-lube": "^0.1.7", - "happy-dom": "^9.20.3", - "jsdom": "22.0.0", - "kleur": "^4.1.5", - "rollup": "^3.26.2", - "source-map": "^0.7.4", - "tiny-glob": "^0.2.9", - "typescript": "^5.1.3", - "vitest": "^0.33.0" - }, - "engines": { - "node": ">=16" - } - }, - "../../node_modules/.pnpm/tslib@2.5.0/node_modules/tslib": { - "version": "2.5.0", - "dev": true, - "license": "0BSD" - }, - "../../node_modules/.pnpm/typescript@5.1.6/node_modules/typescript": { - "version": "5.1.6", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "devDependencies": { - "@esfx/canceltoken": "^1.0.0", - "@octokit/rest": "latest", - "@types/chai": "^4.3.4", - "@types/fs-extra": "^9.0.13", - "@types/glob": "^8.1.0", - "@types/microsoft__typescript-etw": "^0.1.1", - "@types/minimist": "^1.2.2", - "@types/mocha": "^10.0.1", - "@types/ms": "^0.7.31", - "@types/node": "latest", - "@types/source-map-support": "^0.5.6", - "@types/which": "^2.0.1", - "@typescript-eslint/eslint-plugin": "^5.33.1", - "@typescript-eslint/parser": "^5.33.1", - "@typescript-eslint/utils": "^5.33.1", - "azure-devops-node-api": "^12.0.0", - "chai": "^4.3.7", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "del": "^6.1.1", - "diff": "^5.1.0", - "esbuild": "^0.17.2", - "eslint": "^8.22.0", - "eslint-formatter-autolinkable-stylish": "^1.2.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-local": "^1.0.0", - "eslint-plugin-no-null": "^1.0.2", - "eslint-plugin-simple-import-sort": "^10.0.0", - "fast-xml-parser": "^4.0.11", - "fs-extra": "^9.1.0", - "glob": "^8.1.0", - "hereby": "^1.6.4", - "jsonc-parser": "^3.2.0", - "minimist": "^1.2.8", - "mocha": "^10.2.0", - "mocha-fivemat-progress-reporter": "^0.1.0", - "ms": "^2.1.3", - "node-fetch": "^3.2.10", - "source-map-support": "^0.5.21", - "tslib": "^2.5.0", - "typescript": "^5.0.2", - "which": "^2.0.2" - }, - "engines": { - "node": ">=14.17" - } - }, - "../../node_modules/.pnpm/unified@11.0.4/node_modules/unified": { - "version": "11.0.4", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "devDependencies": { - "@types/extend": "^3.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/node": "^20.0.0", - "c8": "^8.0.0", - "prettier": "^3.0.0", - "remark-cli": "^11.0.0", - "remark-preset-wooorm": "^9.0.0", - "tsd": "^0.29.0", - "type-coverage": "^2.0.0", - "typescript": "^5.0.0", - "xo": "^0.56.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "../../node_modules/.pnpm/vite@5.1.6_@types+node@18.16.3_sass@1.69.5/node_modules/vite": { - "version": "5.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.19.3", - "postcss": "^8.4.35", - "rollup": "^4.2.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "devDependencies": { - "@ampproject/remapping": "^2.3.0", - "@babel/parser": "^7.24.0", - "@jridgewell/trace-mapping": "^0.3.25", - "@rollup/plugin-alias": "^5.1.0", - "@rollup/plugin-commonjs": "^25.0.7", - "@rollup/plugin-dynamic-import-vars": "^2.1.2", - "@rollup/plugin-json": "^6.1.0", - "@rollup/plugin-node-resolve": "15.2.3", - "@rollup/plugin-typescript": "^11.1.6", - "@rollup/pluginutils": "^5.1.0", - "@types/escape-html": "^1.0.4", - "@types/pnpapi": "^0.0.5", - "acorn": "^8.11.3", - "acorn-walk": "^8.3.2", - "artichokie": "^0.2.0", - "cac": "^6.7.14", - "chokidar": "^3.6.0", - "connect": "^3.7.0", - "convert-source-map": "^2.0.0", - "cors": "^2.8.5", - "cross-spawn": "^7.0.3", - "debug": "^4.3.4", - "dep-types": "link:./src/types", - "dotenv": "^16.4.5", - "dotenv-expand": "^11.0.6", - "es-module-lexer": "^1.4.1", - "escape-html": "^1.0.3", - "estree-walker": "^3.0.3", - "etag": "^1.8.1", - "fast-glob": "^3.3.2", - "http-proxy": "^1.18.1", - "launch-editor-middleware": "^2.6.1", - "lightningcss": "^1.24.0", - "magic-string": "^0.30.8", - "micromatch": "^4.0.5", - "mlly": "^1.6.1", - "mrmime": "^2.0.0", - "open": "^8.4.2", - "parse5": "^7.1.2", - "pathe": "^1.1.2", - "periscopic": "^4.0.2", - "picocolors": "^1.0.0", - "picomatch": "^2.3.1", - "postcss-import": "^16.0.1", - "postcss-load-config": "^4.0.2", - "postcss-modules": "^6.0.0", - "resolve.exports": "^2.0.2", - "rollup-plugin-dts": "^6.1.0", - "rollup-plugin-esbuild": "^6.1.1", - "rollup-plugin-license": "^3.3.1", - "sirv": "^2.0.4", - "source-map-support": "^0.5.21", - "strip-ansi": "^7.1.0", - "strip-literal": "^2.0.0", - "tsconfck": "^3.0.3", - "tslib": "^2.6.2", - "types": "link:./types", - "ufo": "^1.4.0", - "ws": "^8.16.0" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/@sveltejs/adapter-auto": { - "resolved": "../../node_modules/.pnpm/@sveltejs+adapter-auto@3.1.1_@sveltejs+kit@2.5.4/node_modules/@sveltejs/adapter-auto", - "link": true - }, - "node_modules/@sveltejs/kit": { - "resolved": "../../node_modules/.pnpm/@sveltejs+kit@2.5.4_@sveltejs+vite-plugin-svelte@3.0.2_svelte@4.2.2_vite@5.1.6/node_modules/@sveltejs/kit", - "link": true - }, - "node_modules/@sveltejs/package": { - "resolved": "../../node_modules/.pnpm/@sveltejs+package@2.3.0_svelte@4.2.2_typescript@5.1.6/node_modules/@sveltejs/package", - "link": true - }, - "node_modules/@sveltejs/vite-plugin-svelte": { - "resolved": "../../node_modules/.pnpm/@sveltejs+vite-plugin-svelte@3.0.2_svelte@4.2.2_vite@5.1.6/node_modules/@sveltejs/vite-plugin-svelte", - "link": true - }, - "node_modules/@types/prismjs": { - "version": "1.26.4", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.4.tgz", - "integrity": "sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==", - "dev": true - }, - "node_modules/prismjs": { - "resolved": "../../node_modules/.pnpm/prismjs@1.29.0/node_modules/prismjs", - "link": true - }, - "node_modules/rehype-stringify": { - "resolved": "../../node_modules/.pnpm/rehype-stringify@10.0.0/node_modules/rehype-stringify", - "link": true - }, - "node_modules/remark-gfm": { - "resolved": "../../node_modules/.pnpm/remark-gfm@4.0.0/node_modules/remark-gfm", - "link": true - }, - "node_modules/remark-parse": { - "resolved": "../../node_modules/.pnpm/remark-parse@11.0.0/node_modules/remark-parse", - "link": true - }, - "node_modules/remark-rehype": { - "resolved": "../../node_modules/.pnpm/remark-rehype@11.1.0/node_modules/remark-rehype", - "link": true - }, - "node_modules/shiki": { - "resolved": "../../node_modules/.pnpm/shiki@1.4.0/node_modules/shiki", - "link": true - }, - "node_modules/svelte": { - "resolved": "../../node_modules/.pnpm/svelte@4.2.2/node_modules/svelte", - "link": true - }, - "node_modules/svelte-check": { - "resolved": "../../node_modules/.pnpm/svelte-check@3.6.7_postcss@8.4.31_svelte@4.2.2/node_modules/svelte-check", - "link": true - }, - "node_modules/tslib": { - "resolved": "../../node_modules/.pnpm/tslib@2.5.0/node_modules/tslib", - "link": true - }, - "node_modules/typescript": { - "resolved": "../../node_modules/.pnpm/typescript@5.1.6/node_modules/typescript", - "link": true - }, - "node_modules/unified": { - "resolved": "../../node_modules/.pnpm/unified@11.0.4/node_modules/unified", - "link": true - }, - "node_modules/vite": { - "resolved": "../../node_modules/.pnpm/vite@5.1.6_@types+node@18.16.3_sass@1.69.5/node_modules/vite", - "link": true - } - } -} diff --git a/packages/carta-md/package.json b/packages/carta-md/package.json index 80eedfc..bc074ef 100644 --- a/packages/carta-md/package.json +++ b/packages/carta-md/package.json @@ -16,7 +16,7 @@ }, "./default.css": "./dist/default.css" }, - "version": "1.0.0", + "version": "3.0.0", "scripts": { "dev": "vite dev", "build": "svelte-kit sync && svelte-package", @@ -28,7 +28,6 @@ "@sveltejs/kit": "^2.5.4", "@sveltejs/package": "^2.3.0", "@sveltejs/vite-plugin-svelte": "^3.0.2", - "@types/prismjs": "^1.26.4", "svelte-check": "^3.6.7", "tslib": "^2.4.1", "typescript": "^5.1.6", @@ -36,11 +35,11 @@ }, "type": "module", "dependencies": { - "prismjs": "^1.29.0", "rehype-stringify": "^10.0.0", "remark-gfm": "^4.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.0", + "shiki": "^1.4.0", "unified": "^11.0.4" }, "peerDependencies": { diff --git a/packages/carta-md/src/lib/Markdown.svelte b/packages/carta-md/src/lib/Markdown.svelte index 3124ffb..25d3971 100644 --- a/packages/carta-md/src/lib/Markdown.svelte +++ b/packages/carta-md/src/lib/Markdown.svelte @@ -1,22 +1,30 @@ -
+
{@html rendered} {#if mounted} diff --git a/packages/carta-md/src/lib/MarkdownEditor.svelte b/packages/carta-md/src/lib/MarkdownEditor.svelte index 4fc49bf..8e8cb33 100644 --- a/packages/carta-md/src/lib/MarkdownEditor.svelte +++ b/packages/carta-md/src/lib/MarkdownEditor.svelte @@ -15,7 +15,6 @@ export let scroll: 'sync' | 'async' = 'sync'; export let disableToolbar = false; export let placeholder = ''; - export let renderCls = 'prose'; export let textarea: TextAreaProps = {}; let userLabels: Partial = {}; @@ -125,7 +124,7 @@ {/if} {#if windowMode == 'split' || selectedTab == 'preview'} - + {#if mounted} {#each carta.components.filter(({ parent }) => [parent] diff --git a/packages/carta-md/src/lib/highlight.css b/packages/carta-md/src/lib/highlight.css deleted file mode 100644 index 635e145..0000000 --- a/packages/carta-md/src/lib/highlight.css +++ /dev/null @@ -1,88 +0,0 @@ -.carta-highlight { - color: #333333; - --hl-dark: #f8f8f2; -} - -.token.comment, -.token.prolog, -.token.doctype, -.token.cdata, -.token.punctuation { - color: #6a737d; -} - -.token.property, -.token.tag, -.token.boolean, -.token.number, -.token.constant, -.token.symbol, -.token.url { - color: #2396e3; - --hl-dark: #71d58a; -} - -.token.selector, -.token.attr-name, -.token.string, -.token.char, -.token.builtin, -.token.url > .token.content { - color: #5abd60; - --hl-dark: #4dacfa; -} - -.token.entity { - color: #6f42c1; - --hl-dark: #b392f0; -} - -.token.atrule, -.token.attr-value, -.token.keyword, -.token.class-name, -.token.function, -.token.italic, -.token.deleted, -.token.list { - color: #e16; - --hl-dark: #ff7cc6; -} - -.token.inserted { - color: #5abd60; - --hl-dark: #71d58a; -} - -.token.regex, -.token.variable, -.token.bold { - color: #f60; - --hl-dark: #b581fd; -} - -.token.important, -.token.bold { - font-weight: bold; -} -.token.italic { - font-style: italic; -} -.token.strike { - text-decoration: line-through; - color: #f44; - --hl-dark: #ff5261; -} -.token.title { - font-weight: bold; - color: #212121; - --hl-dark: #e8e8e8; -} -.token.blockquote { - color: #999; - --hl-dark: #7d828b -} -.token.code-snippet { - color: #2396e3; - --hl-dark: #4dacfa; -} diff --git a/packages/carta-md/src/lib/index.ts b/packages/carta-md/src/lib/index.ts index efdec2f..a188dad 100644 --- a/packages/carta-md/src/lib/index.ts +++ b/packages/carta-md/src/lib/index.ts @@ -5,6 +5,7 @@ export type { Icon } from '$lib/internal/icons'; export type { KeyboardShortcut } from '$lib/internal/shortcuts'; export type { Prefix } from '$lib/internal/prefixes'; export * from '$lib/internal/carta'; +export * from '$lib/internal/highlight'; export * from '$lib/internal/textarea-props'; export * from '$lib/internal/labels'; export * from './default.css?inline'; diff --git a/packages/carta-md/src/lib/internal/assets/markdown.ts b/packages/carta-md/src/lib/internal/assets/markdown.ts new file mode 100644 index 0000000..e058507 --- /dev/null +++ b/packages/carta-md/src/lib/internal/assets/markdown.ts @@ -0,0 +1,1779 @@ +import { type LanguageInput } from 'shiki'; + +const lang = { + displayName: 'CartaMarkdown', + name: 'cartamd' as const, + patterns: [{ include: '#frontMatter' }, { include: '#block' }], + repository: { + $self: {}, + $base: {}, + ampersand: { + // comment: + // 'Markdown will convert this for us. We match it so that the HTML grammar will not mark it up as invalid.', + match: '&(?!([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+);)', + name: 'meta.other.valid-ampersand.markdown' + }, + block: { + patterns: [ + { include: '#separator' }, + { include: '#heading' }, + { include: '#blockquote' }, + { include: '#lists' }, + { include: '#fenced_code_block' }, + { include: '#raw_block' }, + { include: '#link-def' }, + { include: '#html' }, + { include: '#table' }, + { include: '#paragraph' } + ] + }, + blockquote: { + begin: '(^|\\G)[ ]{0,3}(>) ?', + captures: { '2': { name: 'punctuation.definition.quote.begin.markdown' } }, + name: 'markup.quote.markdown', + patterns: [{ include: '#block' }], + while: '(^|\\G)\\s*(>) ?' + }, + bold: { + begin: + '(?x) (?(\\*\\*(?=\\w)|(?]*+>\n| (?`+)([^`]|(?!(?(?!`))`)*+\\k\n\n| \\\\[\\\\`*_{}\\[\\]()#.!+\\->]?+\n| \\[\n(\n(?\n[^\\[\\]\\\\]\n| \\\\.\n| \\[ \\g*+ \\]\n)*+\n\\]\n(\n(\n[ ]?\n\\[[^\\]]*+\\]\n)\n| (\n\\(\n[ \\t]*+\n?\n[ \\t]*+\n(\n(?[\'"])\n(.*?)\n\\k<title>\n)?\n\\)\n)\n)\n)\n| (?!(?<=\\S)\\k<open>).\n\n)++\n(?<=\\S)(?=__\\b|\\*\\*)\\k<open>\n)\n', + captures: { '1': { name: 'punctuation.definition.bold.markdown' } }, + end: '(?<=\\S)(\\1)', + name: 'markup.bold.markdown', + patterns: [ + { + applyEndPatternLast: true, + begin: '(?=<[^>]*?>)', + end: '(?<=>)', + patterns: [{ include: 'text.html.derivative' }] + }, + { include: '#escape' }, + { include: '#ampersand' }, + { include: '#bracket' }, + { include: '#raw' }, + { include: '#bold' }, + { include: '#italic' }, + { include: '#image-inline' }, + { include: '#link-inline' }, + { include: '#link-inet' }, + { include: '#link-email' }, + { include: '#image-ref' }, + { include: '#link-ref-literal' }, + { include: '#link-ref' }, + { include: '#link-ref-shortcut' }, + { include: '#strikethrough' } + ] + }, + bracket: { + // comment: + // 'Markdown will convert this for us. We match it so that the HTML grammar will not mark it up as invalid.', + match: '<(?![a-zA-Z/?\\$!])', + name: 'meta.other.valid-bracket.markdown' + }, + escape: { match: '\\\\[-`*_#+.!(){}\\[\\]\\\\>]', name: 'constant.character.escape.markdown' }, + fenced_code_block: { + patterns: [ + { include: '#fenced_code_block_css' }, + { include: '#fenced_code_block_basic' }, + { include: '#fenced_code_block_ini' }, + { include: '#fenced_code_block_java' }, + { include: '#fenced_code_block_lua' }, + { include: '#fenced_code_block_makefile' }, + { include: '#fenced_code_block_perl' }, + { include: '#fenced_code_block_r' }, + { include: '#fenced_code_block_ruby' }, + { include: '#fenced_code_block_php' }, + { include: '#fenced_code_block_sql' }, + { include: '#fenced_code_block_vs_net' }, + { include: '#fenced_code_block_xml' }, + { include: '#fenced_code_block_xsl' }, + { include: '#fenced_code_block_yaml' }, + { include: '#fenced_code_block_dosbatch' }, + { include: '#fenced_code_block_clojure' }, + { include: '#fenced_code_block_coffee' }, + { include: '#fenced_code_block_c' }, + { include: '#fenced_code_block_cpp' }, + { include: '#fenced_code_block_diff' }, + { include: '#fenced_code_block_dockerfile' }, + { include: '#fenced_code_block_git_commit' }, + { include: '#fenced_code_block_git_rebase' }, + { include: '#fenced_code_block_go' }, + { include: '#fenced_code_block_groovy' }, + { include: '#fenced_code_block_pug' }, + { include: '#fenced_code_block_js' }, + { include: '#fenced_code_block_js_regexp' }, + { include: '#fenced_code_block_json' }, + { include: '#fenced_code_block_jsonc' }, + { include: '#fenced_code_block_less' }, + { include: '#fenced_code_block_objc' }, + { include: '#fenced_code_block_swift' }, + { include: '#fenced_code_block_scss' }, + { include: '#fenced_code_block_perl6' }, + { include: '#fenced_code_block_powershell' }, + { include: '#fenced_code_block_python' }, + { include: '#fenced_code_block_julia' }, + { include: '#fenced_code_block_regexp_python' }, + { include: '#fenced_code_block_rust' }, + { include: '#fenced_code_block_scala' }, + { include: '#fenced_code_block_shell' }, + { include: '#fenced_code_block_ts' }, + { include: '#fenced_code_block_tsx' }, + { include: '#fenced_code_block_csharp' }, + { include: '#fenced_code_block_fsharp' }, + { include: '#fenced_code_block_dart' }, + { include: '#fenced_code_block_handlebars' }, + { include: '#fenced_code_block_markdown' }, + { include: '#fenced_code_block_log' }, + { include: '#fenced_code_block_erlang' }, + { include: '#fenced_code_block_elixir' }, + { include: '#fenced_code_block_latex' }, + { include: '#fenced_code_block_bibtex' }, + { include: '#fenced_code_block_twig' }, + { include: '#fenced_code_block_unknown' } + ] + }, + fenced_code_block_basic: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(html|htm|shtml|xhtml|inc|tmpl|tpl)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.html', + patterns: [{ include: 'text.html.basic' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_bibtex: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(bibtex)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.bibtex', + patterns: [{ include: 'text.bibtex' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_c: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(c|h)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.c', + patterns: [{ include: 'source.c' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_clojure: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(clj|cljs|clojure)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.clojure', + patterns: [{ include: 'source.clojure' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_coffee: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(coffee|Cakefile|coffee.erb)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.coffee', + patterns: [{ include: 'source.coffee' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_cpp: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(cpp|c\\+\\+|cxx)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.cpp source.cpp', + patterns: [{ include: 'source.cpp' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_csharp: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(cs|csharp|c#)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.csharp', + patterns: [{ include: 'source.cs' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_css: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(css|css.erb)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.css', + patterns: [{ include: 'source.css' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_dart: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(dart)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.dart', + patterns: [{ include: 'source.dart' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_diff: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(patch|diff|rej)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.diff', + patterns: [{ include: 'source.diff' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_dockerfile: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(dockerfile|Dockerfile)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.dockerfile', + patterns: [{ include: 'source.dockerfile' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_dosbatch: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(bat|batch)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.dosbatch', + patterns: [{ include: 'source.batchfile' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_elixir: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(elixir)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.elixir', + patterns: [{ include: 'source.elixir' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_erlang: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(erlang)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.erlang', + patterns: [{ include: 'source.erlang' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_fsharp: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(fs|fsharp|f#)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.fsharp', + patterns: [{ include: 'source.fsharp' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_git_commit: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(COMMIT_EDITMSG|MERGE_MSG)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.git_commit', + patterns: [{ include: 'text.git-commit' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_git_rebase: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(git-rebase-todo)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.git_rebase', + patterns: [{ include: 'text.git-rebase' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_go: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(go|golang)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.go', + patterns: [{ include: 'source.go' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_groovy: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(groovy|gvy)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.groovy', + patterns: [{ include: 'source.groovy' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_handlebars: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(handlebars|hbs)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.handlebars', + patterns: [{ include: 'text.html.handlebars' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_ini: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(ini|conf)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.ini', + patterns: [{ include: 'source.ini' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_java: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(java|bsh)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.java', + patterns: [{ include: 'source.java' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_js: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(js|jsx|javascript|es6|mjs|cjs|dataviewjs|\\{\\.js.+?\\})((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.javascript', + patterns: [{ include: 'source.js' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_js_regexp: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(regexp)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.js_regexp', + patterns: [{ include: 'source.js.regexp' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_json: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(json|json5|sublime-settings|sublime-menu|sublime-keymap|sublime-mousemap|sublime-theme|sublime-build|sublime-project|sublime-completions)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.json', + patterns: [{ include: 'source.json' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_jsonc: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(jsonc)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.jsonc', + patterns: [{ include: 'source.json.comments' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_julia: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(julia|\\{\\.julia.+?\\})((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.julia', + patterns: [{ include: 'source.julia' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_latex: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(latex|tex)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.latex', + patterns: [{ include: 'text.tex.latex' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_less: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(less)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.less', + patterns: [{ include: 'source.css.less' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_log: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(log)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.log', + patterns: [{ include: 'text.log' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_lua: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(lua)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.lua', + patterns: [{ include: 'source.lua' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_makefile: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(Makefile|makefile|GNUmakefile|OCamlMakefile)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.makefile', + patterns: [{ include: 'source.makefile' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_markdown: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(markdown|md)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.markdown', + patterns: [{ include: 'text.html.markdown' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_objc: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(objectivec|objective-c|mm|objc|obj-c|m|h)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.objc', + patterns: [{ include: 'source.objc' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_perl: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(perl|pl|pm|pod|t|PL|psgi|vcl)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.perl', + patterns: [{ include: 'source.perl' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_perl6: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(perl6|p6|pl6|pm6|nqp)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.perl6', + patterns: [{ include: 'source.perl.6' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_php: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(php|php3|php4|php5|phpt|phtml|aw|ctp)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.php', + patterns: [{ include: 'text.html.basic' }, { include: 'source.php' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_powershell: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(powershell|ps1|psm1|psd1|pwsh)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.powershell', + patterns: [{ include: 'source.powershell' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_pug: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(jade|pug)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.pug', + patterns: [{ include: 'text.pug' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_python: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(python|py|py3|rpy|pyw|cpy|SConstruct|Sconstruct|sconstruct|SConscript|gyp|gypi|\\{\\.python.+?\\})((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.python', + patterns: [{ include: 'source.python' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_r: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(R|r|s|S|Rprofile|\\{\\.r.+?\\})((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.r', + patterns: [{ include: 'source.r' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_regexp_python: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(re)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.regexp_python', + patterns: [{ include: 'source.regexp.python' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_ruby: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(ruby|rb|rbx|rjs|Rakefile|rake|cgi|fcgi|gemspec|irbrc|Capfile|ru|prawn|Cheffile|Gemfile|Guardfile|Hobofile|Vagrantfile|Appraisals|Rantfile|Berksfile|Berksfile.lock|Thorfile|Puppetfile)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.ruby', + patterns: [{ include: 'source.ruby' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_rust: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(rust|rs|\\{\\.rust.+?\\})((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.rust', + patterns: [{ include: 'source.rust' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_scala: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(scala|sbt)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.scala', + patterns: [{ include: 'source.scala' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_scss: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(scss)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.scss', + patterns: [{ include: 'source.css.scss' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_shell: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(shell|sh|bash|zsh|bashrc|bash_profile|bash_login|profile|bash_logout|.textmate_init|\\{\\.bash.+?\\})((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.shellscript', + patterns: [{ include: 'source.shell' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_sql: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(sql|ddl|dml)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.sql', + patterns: [{ include: 'source.sql' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_swift: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(swift)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.swift', + patterns: [{ include: 'source.swift' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_ts: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(typescript|ts)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.typescript', + patterns: [{ include: 'source.ts' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_tsx: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(tsx)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.typescriptreact', + patterns: [{ include: 'source.tsx' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_twig: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(twig)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.twig', + patterns: [{ include: 'source.twig' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_unknown: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?=([^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown' + }, + fenced_code_block_vs_net: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(vb)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.vs_net', + patterns: [{ include: 'source.asp.vb.net' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_xml: { + begin: + '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(xml|xsd|tld|jsp|pt|cpt|dtml|rss|opml)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.xml', + patterns: [{ include: 'text.xml' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_xsl: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(xsl|xslt)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.xsl', + patterns: [{ include: 'text.xml.xsl' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + fenced_code_block_yaml: { + begin: '(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(yaml|yml)((\\s+|:|,|\\{|\\?)[^`]*)?$)', + beginCaptures: { + '3': { name: 'punctuation.definition.markdown' }, + '4': { name: 'fenced_code.block.language.markdown' }, + '5': { name: 'fenced_code.block.language.attributes.markdown' } + }, + end: '(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$', + endCaptures: { '3': { name: 'punctuation.definition.markdown' } }, + name: 'markup.fenced_code.block.markdown', + patterns: [ + { + begin: '(^|\\G)(\\s*)(.*)', + contentName: 'meta.embedded.block.yaml', + patterns: [{ include: 'source.yaml' }], + while: '(^|\\G)(?!\\s*([`~]{3,})\\s*$)' + } + ] + }, + frontMatter: { + begin: '\\A-{3}\\s*$', + contentName: 'meta.embedded.block.frontmatter', + end: '(^|\\G)-{3}|\\.{3}\\s*$', + patterns: [{ include: 'source.yaml' }] + }, + heading: { + captures: { + '1': { + patterns: [ + { + captures: { + '1': { name: 'punctuation.definition.heading.markdown' }, + '2': { + name: 'entity.name.section.markdown', + patterns: [{ include: '#inline' }, { include: 'text.html.derivative' }] + }, + '3': { name: 'punctuation.definition.heading.markdown' } + }, + match: '(#{6})\\s+(.*?)(?:\\s+(#+))?\\s*$', + name: 'heading.6.markdown' + }, + { + captures: { + '1': { name: 'punctuation.definition.heading.markdown' }, + '2': { + name: 'entity.name.section.markdown', + patterns: [{ include: '#inline' }, { include: 'text.html.derivative' }] + }, + '3': { name: 'punctuation.definition.heading.markdown' } + }, + match: '(#{5})\\s+(.*?)(?:\\s+(#+))?\\s*$', + name: 'heading.5.markdown' + }, + { + captures: { + '1': { name: 'punctuation.definition.heading.markdown' }, + '2': { + name: 'entity.name.section.markdown', + patterns: [{ include: '#inline' }, { include: 'text.html.derivative' }] + }, + '3': { name: 'punctuation.definition.heading.markdown' } + }, + match: '(#{4})\\s+(.*?)(?:\\s+(#+))?\\s*$', + name: 'heading.4.markdown' + }, + { + captures: { + '1': { name: 'punctuation.definition.heading.markdown' }, + '2': { + name: 'entity.name.section.markdown', + patterns: [{ include: '#inline' }, { include: 'text.html.derivative' }] + }, + '3': { name: 'punctuation.definition.heading.markdown' } + }, + match: '(#{3})\\s+(.*?)(?:\\s+(#+))?\\s*$', + name: 'heading.3.markdown' + }, + { + captures: { + '1': { name: 'punctuation.definition.heading.markdown' }, + '2': { + name: 'entity.name.section.markdown', + patterns: [{ include: '#inline' }, { include: 'text.html.derivative' }] + }, + '3': { name: 'punctuation.definition.heading.markdown' } + }, + match: '(#{2})\\s+(.*?)(?:\\s+(#+))?\\s*$', + name: 'heading.2.markdown' + }, + { + captures: { + '1': { name: 'punctuation.definition.heading.markdown' }, + '2': { + name: 'entity.name.section.markdown', + patterns: [{ include: '#inline' }, { include: 'text.html.derivative' }] + }, + '3': { name: 'punctuation.definition.heading.markdown' } + }, + match: '(#{1})\\s+(.*?)(?:\\s+(#+))?\\s*$', + name: 'heading.1.markdown' + } + ] + } + }, + match: '(?:^|\\G)[ ]{0,3}(#{1,6}\\s+(.*?)(\\s+#{1,6})?\\s*)$', + name: 'markup.heading.markdown' + }, + 'heading-setext': { + patterns: [ + { match: '^(={3,})(?=[ \\t]*$\\n?)', name: 'markup.heading.setext.1.markdown' }, + { match: '^(-{3,})(?=[ \\t]*$\\n?)', name: 'markup.heading.setext.2.markdown' } + ] + }, + html: { + patterns: [ + { + begin: '(^|\\G)\\s*(<!--)', + captures: { + '1': { name: 'punctuation.definition.comment.html' }, + '2': { name: 'punctuation.definition.comment.html' } + }, + end: '(-->)', + name: 'comment.block.html' + }, + { + begin: '(?i)(^|\\G)\\s*(?=<(script|style|pre)(\\s|$|>)(?!.*?</(script|style|pre)>))', + end: '(?i)(.*)((</)(script|style|pre)(>))', + endCaptures: { + '1': { patterns: [{ include: 'text.html.derivative' }] }, + '2': { name: 'meta.tag.structure.$4.end.html' }, + '3': { name: 'punctuation.definition.tag.begin.html' }, + '4': { name: 'entity.name.tag.html' }, + '5': { name: 'punctuation.definition.tag.end.html' } + }, + patterns: [ + { + begin: '(\\s*|$)', + patterns: [{ include: 'text.html.derivative' }], + while: '(?i)^(?!.*</(script|style|pre)>)' + } + ] + }, + { + begin: '(?i)(^|\\G)\\s*(?=</?[a-zA-Z]+[^\\s/>]*(\\s|$|/?>))', + patterns: [{ include: 'text.html.derivative' }], + while: '^(?!\\s*$)' + }, + { + begin: '(^|\\G)\\s*(?=(<[a-zA-Z0-9\\-](/?>|\\s.*?>)|</[a-zA-Z0-9\\-]>)\\s*$)', + patterns: [{ include: 'text.html.derivative' }], + while: '^(?!\\s*$)' + } + ] + }, + 'image-inline': { + captures: { + '1': { name: 'punctuation.definition.link.description.begin.markdown' }, + '2': { name: 'string.other.link.description.markdown' }, + '4': { name: 'punctuation.definition.link.description.end.markdown' }, + '5': { name: 'punctuation.definition.metadata.markdown' }, + '7': { name: 'punctuation.definition.link.markdown' }, + '8': { name: 'markup.underline.link.image.markdown' }, + '9': { name: 'punctuation.definition.link.markdown' }, + '10': { name: 'markup.underline.link.image.markdown' }, + '12': { name: 'string.other.link.description.title.markdown' }, + '13': { name: 'punctuation.definition.string.begin.markdown' }, + '14': { name: 'punctuation.definition.string.end.markdown' }, + '15': { name: 'string.other.link.description.title.markdown' }, + '16': { name: 'punctuation.definition.string.begin.markdown' }, + '17': { name: 'punctuation.definition.string.end.markdown' }, + '18': { name: 'string.other.link.description.title.markdown' }, + '19': { name: 'punctuation.definition.string.begin.markdown' }, + '20': { name: 'punctuation.definition.string.end.markdown' }, + '21': { name: 'punctuation.definition.metadata.markdown' } + }, + match: `(?x) +(\\!\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\]) + +(\\() + +[ \\t]* +( +(<)((?:\\\\[<>]|[^<>\\n])*)(>) +| ((?<url>(?>[^\\s()]+)|\\(\\g<url>*\\))*) +) +[ \\t]* +(?: +((\\().+?(\\))) +| ((").+?(")) +| ((').+?(')) +)? +\\s* +(\\)) +`, + name: 'meta.image.inline.markdown' + }, + 'image-ref': { + captures: { + '1': { name: 'punctuation.definition.link.description.begin.markdown' }, + '2': { name: 'string.other.link.description.markdown' }, + '4': { name: 'punctuation.definition.link.description.end.markdown' }, + '5': { name: 'punctuation.definition.constant.markdown' }, + '6': { name: 'constant.other.reference.link.markdown' }, + '7': { name: 'punctuation.definition.constant.markdown' } + }, + match: + '(\\!\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])[ ]?(\\[)(.*?)(\\])', + name: 'meta.image.reference.markdown' + }, + inline: { + patterns: [ + { include: '#ampersand' }, + { include: '#bracket' }, + { include: '#bold' }, + { include: '#italic' }, + { include: '#raw' }, + { include: '#strikethrough' }, + { include: '#escape' }, + { include: '#image-inline' }, + { include: '#image-ref' }, + { include: '#link-email' }, + { include: '#link-inet' }, + { include: '#link-inline' }, + { include: '#link-ref' }, + { include: '#link-ref-literal' }, + { include: '#link-ref-shortcut' } + ] + }, + italic: { + begin: + '(?x) (?<open>(\\*(?=\\w)|(?<!\\w)\\*|(?<!\\w)\\b_))(?=\\S)\n(?=\n(\n<[^>]*+>\n| (?<raw>`+)([^`]|(?!(?<!`)\\k<raw>(?!`))`)*+\\k<raw>\n\n| \\\\[\\\\`*_{}\\[\\]()#.!+\\->]?+\n| \\[\n(\n(?<square>\n[^\\[\\]\\\\]\n| \\\\.\n| \\[ \\g<square>*+ \\]\n)*+\n\\]\n(\n(\n[ ]?\n\\[[^\\]]*+\\]\n)\n| (\n\\(\n[ \\t]*+\n<?(.*?)>?\n[ \\t]*+\n(\n(?<title>[\'"])\n(.*?)\n\\k<title>\n)?\n\\)\n)\n)\n)\n| \\k<open>\\k<open>\n| (?!(?<=\\S)\\k<open>).\n\n)++\n(?<=\\S)(?=_\\b|\\*)\\k<open>\n)\n', + captures: { '1': { name: 'punctuation.definition.italic.markdown' } }, + end: '(?<=\\S)(\\1)((?!\\1)|(?=\\1\\1))', + name: 'markup.italic.markdown', + patterns: [ + { + applyEndPatternLast: true, + begin: '(?=<[^>]*?>)', + end: '(?<=>)', + patterns: [{ include: 'text.html.derivative' }] + }, + { include: '#escape' }, + { include: '#ampersand' }, + { include: '#bracket' }, + { include: '#raw' }, + { include: '#bold' }, + { include: '#image-inline' }, + { include: '#link-inline' }, + { include: '#link-inet' }, + { include: '#link-email' }, + { include: '#image-ref' }, + { include: '#link-ref-literal' }, + { include: '#link-ref' }, + { include: '#link-ref-shortcut' }, + { include: '#strikethrough' } + ] + }, + 'link-def': { + captures: { + '1': { name: 'punctuation.definition.constant.markdown' }, + '2': { name: 'constant.other.reference.link.markdown' }, + '3': { name: 'punctuation.definition.constant.markdown' }, + '4': { name: 'punctuation.separator.key-value.markdown' }, + '5': { name: 'punctuation.definition.link.markdown' }, + '6': { name: 'markup.underline.link.markdown' }, + '7': { name: 'punctuation.definition.link.markdown' }, + '8': { name: 'markup.underline.link.markdown' }, + '9': { name: 'string.other.link.description.title.markdown' }, + '10': { name: 'punctuation.definition.string.begin.markdown' }, + '11': { name: 'punctuation.definition.string.end.markdown' }, + '12': { name: 'string.other.link.description.title.markdown' }, + '13': { name: 'punctuation.definition.string.begin.markdown' }, + '14': { name: 'punctuation.definition.string.end.markdown' }, + '15': { name: 'string.other.link.description.title.markdown' }, + '16': { name: 'punctuation.definition.string.begin.markdown' }, + '17': { name: 'punctuation.definition.string.end.markdown' } + }, + match: `(?x) +\\s* +(\\[)([^]]+?)(\\])(:) +[ \\t]* +(?:(<)((?:\\\\[<>]|[^<>\\n])*)(>)|(\\S+?)) +[ \\t]* +(?: +((\\().+?(\\))) +| ((").+?(")) +| ((').+?(')) +)? +\\s* +$ +`, + name: 'meta.link.reference.def.markdown' + }, + 'link-email': { + captures: { + '1': { name: 'punctuation.definition.link.markdown' }, + '2': { name: 'markup.underline.link.markdown' }, + '4': { name: 'punctuation.definition.link.markdown' } + }, + match: + "(<)((?:mailto:)?[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)(>)", + name: 'meta.link.email.lt-gt.markdown' + }, + 'link-inet': { + captures: { + '1': { name: 'punctuation.definition.link.markdown' }, + '2': { name: 'markup.underline.link.markdown' }, + '3': { name: 'punctuation.definition.link.markdown' } + }, + match: '(<)((?:https?|ftp)://.*?)(>)', + name: 'meta.link.inet.markdown' + }, + 'link-inline': { + captures: { + '1': { name: 'punctuation.definition.link.title.begin.markdown' }, + '2': { + name: 'string.other.link.title.markdown', + patterns: [ + { include: '#raw' }, + { include: '#bold' }, + { include: '#italic' }, + { include: '#strikethrough' }, + { include: '#image-inline' } + ] + }, + '4': { name: 'punctuation.definition.link.title.end.markdown' }, + '5': { name: 'punctuation.definition.metadata.markdown' }, + '7': { name: 'punctuation.definition.link.markdown' }, + '8': { name: 'markup.underline.link.markdown' }, + '9': { name: 'punctuation.definition.link.markdown' }, + '10': { name: 'markup.underline.link.markdown' }, + '12': { name: 'string.other.link.description.title.markdown' }, + '13': { name: 'punctuation.definition.string.begin.markdown' }, + '14': { name: 'punctuation.definition.string.end.markdown' }, + '15': { name: 'string.other.link.description.title.markdown' }, + '16': { name: 'punctuation.definition.string.begin.markdown' }, + '17': { name: 'punctuation.definition.string.end.markdown' }, + '18': { name: 'string.other.link.description.title.markdown' }, + '19': { name: 'punctuation.definition.string.begin.markdown' }, + '20': { name: 'punctuation.definition.string.end.markdown' }, + '21': { name: 'punctuation.definition.metadata.markdown' } + }, + match: `(?x) +(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\]) + +(\\() + +[ \\t]* +( +(<)((?:\\\\[<>]|[^<>\\n])*)(>) +| ((?<url>(?>[^\\s()]+)|\\(\\g<url>*\\))*) +) +[ \\t]* + +(?: +((\\()[^()]*(\\))) +| ((")[^"]*(")) +| ((')[^']*(')) +)? +\\s* +(\\)) +`, + name: 'meta.link.inline.markdown' + }, + 'link-ref': { + captures: { + '1': { name: 'punctuation.definition.link.title.begin.markdown' }, + '2': { + name: 'string.other.link.title.markdown', + patterns: [ + { include: '#raw' }, + { include: '#bold' }, + { include: '#italic' }, + { include: '#strikethrough' }, + { include: '#image-inline' } + ] + }, + '4': { name: 'punctuation.definition.link.title.end.markdown' }, + '5': { name: 'punctuation.definition.constant.begin.markdown' }, + '6': { name: 'constant.other.reference.link.markdown' }, + '7': { name: 'punctuation.definition.constant.end.markdown' } + }, + match: + '(?<![\\]\\\\])(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])(\\[)([^\\]]*+)(\\])', + name: 'meta.link.reference.markdown' + }, + 'link-ref-literal': { + captures: { + '1': { name: 'punctuation.definition.link.title.begin.markdown' }, + '2': { name: 'string.other.link.title.markdown' }, + '4': { name: 'punctuation.definition.link.title.end.markdown' }, + '5': { name: 'punctuation.definition.constant.begin.markdown' }, + '6': { name: 'punctuation.definition.constant.end.markdown' } + }, + match: + '(?<![\\]\\\\])(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])[ ]?(\\[)(\\])', + name: 'meta.link.reference.literal.markdown' + }, + 'link-ref-shortcut': { + captures: { + '1': { name: 'punctuation.definition.link.title.begin.markdown' }, + '2': { name: 'string.other.link.title.markdown' }, + '3': { name: 'punctuation.definition.link.title.end.markdown' } + }, + match: '(?<![\\]\\\\])(\\[)((?:[^\\s\\[\\]\\\\]|\\\\[\\[\\]])+?)((?<!\\\\)\\])', + name: 'meta.link.reference.markdown' + }, + list_paragraph: { + begin: '(^|\\G)(?=\\S)(?![*+->]\\s|[0-9]+\\.\\s)', + name: 'meta.paragraph.markdown', + patterns: [ + { include: '#inline' }, + { include: 'text.html.derivative' }, + { include: '#heading-setext' } + ], + while: + '(^|\\G)(?!\\s*$|#|[ ]{0,3}([-*_>][ ]{2,}){3,}[ \\t]*$\\n?|[ ]{0,3}[*+->]|[ ]{0,3}[0-9]+\\.)' + }, + lists: { + patterns: [ + { + begin: '(^|\\G)([ ]{0,3})([*+-])([ \\t])', + beginCaptures: { '3': { name: 'punctuation.definition.list.begin.markdown' } }, + name: 'markup.list.unnumbered.markdown', + patterns: [{ include: '#block' }, { include: '#list_paragraph' }], + while: '((^|\\G)([ ]{2,4}|\\t))|(^[ \\t]*$)' + }, + { + begin: '(^|\\G)([ ]{0,3})([0-9]+[\\.\\)])([ \\t])', + beginCaptures: { '3': { name: 'punctuation.definition.list.begin.markdown' } }, + name: 'markup.list.numbered.markdown', + patterns: [{ include: '#block' }, { include: '#list_paragraph' }], + while: '((^|\\G)([ ]{2,4}|\\t))|(^[ \\t]*$)' + } + ] + }, + paragraph: { + begin: '(^|\\G)[ ]{0,3}(?=[^ \\t\\n])', + name: 'meta.paragraph.markdown', + patterns: [ + { include: '#inline' }, + { include: 'text.html.derivative' }, + { include: '#heading-setext' } + ], + while: '(^|\\G)((?=\\s*[-=]{3,}\\s*$)|[ ]{4,}(?=[^ \\t\\n]))' + }, + raw: { + captures: { + '1': { name: 'punctuation.definition.raw.markdown' }, + '3': { name: 'punctuation.definition.raw.markdown' } + }, + match: '(`+)((?:[^`]|(?!(?<!`)\\1(?!`))`)*+)(\\1)', + name: 'markup.inline.raw.string.markdown' + }, + raw_block: { + begin: '(^|\\G)([ ]{4}|\\t)', + name: 'markup.raw.block.markdown', + while: '(^|\\G)([ ]{4}|\\t)' + }, + separator: { + match: '(^|\\G)[ ]{0,3}([\\*\\-\\_])([ ]{0,2}\\2){2,}[ \\t]*$\\n?', + name: 'meta.separator.markdown' + }, + strikethrough: { + captures: { + '1': { name: 'punctuation.definition.strikethrough.markdown' }, + '2': { + patterns: [ + { + applyEndPatternLast: true, + begin: '(?=<[^>]*?>)', + end: '(?<=>)', + patterns: [{ include: 'text.html.derivative' }] + }, + { include: '#escape' }, + { include: '#ampersand' }, + { include: '#bracket' }, + { include: '#raw' }, + { include: '#bold' }, + { include: '#italic' }, + { include: '#image-inline' }, + { include: '#link-inline' }, + { include: '#link-inet' }, + { include: '#link-email' }, + { include: '#image-ref' }, + { include: '#link-ref-literal' }, + { include: '#link-ref' }, + { include: '#link-ref-shortcut' } + ] + }, + '3': { name: 'punctuation.definition.strikethrough.markdown' } + }, + match: '(?<!\\\\)(~{2,})((?:[^~]|(?!(?<![~\\\\])\\1(?!~))~)*+)(\\1)', + name: 'markup.strikethrough.markdown' + }, + table: { + begin: '(^|\\G)(\\|)(?=[^|].+\\|\\s*$)', + beginCaptures: { '2': { name: 'punctuation.definition.table.markdown' } }, + name: 'markup.table.markdown', + patterns: [ + { match: '\\|', name: 'punctuation.definition.table.markdown' }, + { + captures: { '1': { name: 'punctuation.separator.table.markdown' } }, + match: '(?<=\\|)\\s*(:?-+:?)\\s*(?=\\|)' + }, + { + captures: { '1': { patterns: [{ include: '#inline' }] } }, + match: '(?<=\\|)\\s*(?=\\S)((\\\\\\||[^|])+)(?<=\\S)\\s*(?=\\|)' + } + ], + while: '(^|\\G)(?=\\|)' + } + }, + scopeName: 'text.html.cartamd', + embeddedLangs: [], + embeddedLangsLazy: [ + 'css', + 'html', + 'ini', + 'java', + 'lua', + 'make', + 'perl', + 'r', + 'ruby', + 'php', + 'sql', + 'vb', + 'xml', + 'xsl', + 'yaml', + 'bat', + 'clojure', + 'coffee', + 'c', + 'cpp', + 'diff', + 'docker', + 'git-commit', + 'git-rebase', + 'go', + 'groovy', + 'pug', + 'javascript', + 'json', + 'jsonc', + 'less', + 'objective-c', + 'swift', + 'scss', + 'raku', + 'powershell', + 'python', + 'julia', + 'rust', + 'scala', + 'shellscript', + 'typescript', + 'tsx', + 'csharp', + 'fsharp', + 'dart', + 'handlebars', + 'erlang', + 'elixir', + 'latex', + 'bibtex', + 'html-derivative' + ] +} satisfies LanguageInput; + +export default lang; diff --git a/packages/carta-md/src/lib/internal/assets/theme-dark.ts b/packages/carta-md/src/lib/internal/assets/theme-dark.ts new file mode 100644 index 0000000..795b8c3 --- /dev/null +++ b/packages/carta-md/src/lib/internal/assets/theme-dark.ts @@ -0,0 +1,330 @@ +import { type ThemeInput } from 'shiki'; + +const theme = { + displayName: 'Carta Dark' as const, + name: 'carta-dark' as const, + semanticHighlighting: true, + fg: '#f8f8f2', + bg: 'transparent', + tokenColors: [ + { + scope: ['comment', 'punctuation.definition.comment', 'string.comment'], + settings: { + foreground: '#6a737d' + } + }, + { + scope: ['variable.other.constant', 'variable.other.enummember', 'variable.language'], + settings: { + foreground: '#fff' + } + }, + { + scope: ['constant', 'entity.name.constant'], + settings: { + foreground: '#71d58a' + } + }, + { + scope: ['entity', 'entity.name'], + settings: { + foreground: '#b392f0' + } + }, + { + scope: 'variable.parameter.function', + settings: { + foreground: '#e1e4e8' + } + }, + { + scope: 'entity.name.tag', + settings: { + foreground: '#85e89d' + } + }, + { + scope: ['keyword', 'punctuation.definition.template-expression'], + settings: { + foreground: '#ff7cc6' + } + }, + { + scope: ['storage', 'storage.type'], + settings: { + foreground: '#ff7cc6' + } + }, + { + scope: ['storage.modifier.package', 'storage.modifier.import', 'storage.type.java'], + settings: { + foreground: '#e1e4e8' + } + }, + { + scope: [ + 'string', + 'punctuation.definition.string', + 'string punctuation.section.embedded source' + ], + settings: { + foreground: '#4dacfa' + } + }, + { + scope: 'support', + settings: { + foreground: '#71d58a' + } + }, + { + scope: 'meta.property-name', + settings: { + foreground: '#71d58a' + } + }, + { + scope: 'variable', + settings: { + foreground: '#b581fd' + } + }, + { + scope: 'variable.other', + settings: { + foreground: '#e1e4e8' + } + }, + { + scope: 'invalid.broken', + settings: { + fontStyle: 'italic', + foreground: '#fdaeb7' + } + }, + { + scope: 'invalid.deprecated', + settings: { + fontStyle: 'italic', + foreground: '#fdaeb7' + } + }, + { + scope: 'invalid.illegal', + settings: { + fontStyle: 'italic', + foreground: '#fdaeb7' + } + }, + { + scope: 'invalid.unimplemented', + settings: { + fontStyle: 'italic', + foreground: '#fdaeb7' + } + }, + { + scope: 'carriage-return', + settings: { + background: '#ff7cc6', + fontStyle: 'italic underline', + foreground: '#24292e' + } + }, + { + scope: 'message.error', + settings: { + foreground: '#fdaeb7' + } + }, + { + scope: 'string variable', + settings: { + foreground: '#71d58a' + } + }, + { + scope: ['source.regexp', 'string.regexp'], + settings: { + foreground: '#4dacfa' + } + }, + { + scope: [ + 'string.regexp.character-class', + 'string.regexp constant.character.escape', + 'string.regexp source.ruby.embedded', + 'string.regexp string.regexp.arbitrary-repitition' + ], + settings: { + foreground: '#4dacfa' + } + }, + { + scope: 'string.regexp constant.character.escape', + settings: { + fontStyle: 'bold', + foreground: '#85e89d' + } + }, + { + scope: 'support.constant', + settings: { + foreground: '#71d58a' + } + }, + { + scope: 'support.variable', + settings: { + foreground: '#71d58a' + } + }, + { + scope: 'meta.module-reference', + settings: { + foreground: '#71d58a' + } + }, + { + scope: 'punctuation.definition.list.begin.markdown', + settings: { + foreground: '#ff7cc6' + } + }, + { + scope: ['markup.heading', 'markup.heading entity.name'], + settings: { + fontStyle: 'bold', + foreground: '#e8e8e8' + } + }, + { + scope: 'markup.quote', + settings: { + foreground: '#7d828b' + } + }, + { + scope: 'markup.italic', + settings: { + fontStyle: 'italic', + foreground: '#ff7cc6' + } + }, + { + scope: 'markup.bold', + settings: { + foreground: '#b581fd' + } + }, + { + scope: ['markup.underline'], + settings: { + foreground: '#71d58a', + fontStyle: 'underline' + } + }, + { + scope: ['markup.strikethrough'], + settings: { + foreground: '#ff5261', + fontStyle: 'strikethrough' + } + }, + { + scope: 'markup.inline.raw', + settings: { + foreground: '#4dacfa' + } + }, + { + scope: ['markup.deleted', 'meta.diff.header.from-file', 'punctuation.definition.deleted'], + settings: { + background: '#86181d', + foreground: '#fdaeb7' + } + }, + { + scope: ['markup.inserted', 'meta.diff.header.to-file', 'punctuation.definition.inserted'], + settings: { + background: '#144620', + foreground: '#85e89d' + } + }, + { + scope: ['markup.changed', 'punctuation.definition.changed'], + settings: { + background: '#c24e00', + foreground: '#b581fd' + } + }, + { + scope: ['markup.ignored', 'markup.untracked'], + settings: { + background: '#71d58a', + foreground: '#2f363d' + } + }, + { + scope: 'meta.diff.range', + settings: { + fontStyle: 'bold', + foreground: '#b392f0' + } + }, + { + scope: 'meta.diff.header', + settings: { + foreground: '#71d58a' + } + }, + { + scope: 'meta.separator', + settings: { + fontStyle: 'bold', + foreground: '#71d58a' + } + }, + { + scope: 'meta.output', + settings: { + foreground: '#71d58a' + } + }, + { + scope: [ + 'brackethighlighter.tag', + 'brackethighlighter.curly', + 'brackethighlighter.round', + 'brackethighlighter.square', + 'brackethighlighter.angle', + 'brackethighlighter.quote' + ], + settings: { + foreground: '#d1d5da' + } + }, + { + scope: 'brackethighlighter.unmatched', + settings: { + foreground: '#fdaeb7' + } + }, + { + scope: ['constant.other.reference.link', 'string.other.link'], + settings: { + fontStyle: 'underline', + foreground: '#4dacfa' + } + }, + { + scope: ['punctuation.definition.markdown', 'fenced_code.block.language'], + settings: { + foreground: '#ff7cc6' + } + } + ], + type: 'light' +} satisfies ThemeInput; + +export default theme; diff --git a/packages/carta-md/src/lib/internal/assets/theme-light.ts b/packages/carta-md/src/lib/internal/assets/theme-light.ts new file mode 100644 index 0000000..6239c1b --- /dev/null +++ b/packages/carta-md/src/lib/internal/assets/theme-light.ts @@ -0,0 +1,329 @@ +import { type ThemeInput } from 'shiki'; + +const theme = { + displayName: 'Carta Light' as const, + name: 'carta-light' as const, + semanticHighlighting: true, + fg: '#333333', + bg: 'transparent', + tokenColors: [ + { + scope: ['comment', 'punctuation.definition.comment', 'string.comment'], + settings: { + foreground: '#6a737d' + } + }, + { + scope: ['variable.other.constant', 'variable.other.enummember', 'variable.language'], + settings: { + foreground: '#000' + } + }, + { + scope: ['constant', 'entity.name.constant'], + settings: { + foreground: '#3bf' + } + }, + { + scope: ['entity', 'entity.name'], + settings: { + foreground: '#6f42c1' + } + }, + { + scope: 'variable.parameter.function', + settings: { + foreground: '#24292e' + } + }, + { + scope: 'entity.name.tag', + settings: { + foreground: '#22863a' + } + }, + { + scope: ['keyword', 'punctuation.definition.template-expression'], + settings: { + foreground: '#e16' + } + }, + { + scope: ['storage', 'storage.type'], + settings: { + foreground: '#e16' + } + }, + { + scope: ['storage.modifier.package', 'storage.modifier.import', 'storage.type.java'], + settings: { + foreground: '#24292e' + } + }, + { + scope: [ + 'string', + 'punctuation.definition.string', + 'string punctuation.section.embedded source' + ], + settings: { + foreground: '#7d8' + } + }, + { + scope: 'support', + settings: { + foreground: '#3bf' + } + }, + { + scope: 'meta.property-name', + settings: { + foreground: '#3bf' + } + }, + { + scope: 'variable', + settings: { + foreground: '#f60' + } + }, + { + scope: 'variable.other', + settings: { + foreground: '#24292e' + } + }, + { + scope: 'invalid.broken', + settings: { + fontStyle: 'italic', + foreground: '#b31d28' + } + }, + { + scope: 'invalid.deprecated', + settings: { + fontStyle: 'italic', + foreground: '#b31d28' + } + }, + { + scope: 'invalid.illegal', + settings: { + fontStyle: 'italic', + foreground: '#b31d28' + } + }, + { + scope: 'invalid.unimplemented', + settings: { + fontStyle: 'italic', + foreground: '#b31d28' + } + }, + { + scope: 'carriage-return', + settings: { + background: '#e16', + fontStyle: 'italic underline', + foreground: '#fafbfc' + } + }, + { + scope: 'message.error', + settings: { + foreground: '#b31d28' + } + }, + { + scope: 'string variable', + settings: { + foreground: '#3bf' + } + }, + { + scope: ['source.regexp', 'string.regexp'], + settings: { + foreground: '#7d8' + } + }, + { + scope: [ + 'string.regexp.character-class', + 'string.regexp constant.character.escape', + 'string.regexp source.ruby.embedded', + 'string.regexp string.regexp.arbitrary-repitition' + ], + settings: { + foreground: '#7d8' + } + }, + { + scope: 'string.regexp constant.character.escape', + settings: { + fontStyle: 'bold', + foreground: '#22863a' + } + }, + { + scope: 'support.constant', + settings: { + foreground: '#3bf' + } + }, + { + scope: 'support.variable', + settings: { + foreground: '#3bf' + } + }, + { + scope: 'meta.module-reference', + settings: { + foreground: '#3bf' + } + }, + { + scope: 'punctuation.definition.list.begin.markdown', + settings: { + foreground: '#e16' + } + }, + { + scope: ['markup.heading', 'markup.heading entity.name'], + settings: { + fontStyle: 'bold', + foreground: '#212121' + } + }, + { + scope: 'markup.quote', + settings: { + foreground: '#999' + } + }, + { + scope: 'markup.italic', + settings: { + foreground: '#e16' + } + }, + { + scope: 'markup.bold', + settings: { + foreground: '#f60' + } + }, + { + scope: ['markup.underline'], + settings: { + foreground: '#84f', + fontStyle: 'underline' + } + }, + { + scope: ['markup.strikethrough'], + settings: { + foreground: '#f44', + fontStyle: 'strikethrough' + } + }, + { + scope: 'markup.inline.raw', + settings: { + foreground: '#5af' + } + }, + { + scope: ['markup.deleted', 'meta.diff.header.from-file', 'punctuation.definition.deleted'], + settings: { + background: '#ffeef0', + foreground: '#b31d28' + } + }, + { + scope: ['markup.inserted', 'meta.diff.header.to-file', 'punctuation.definition.inserted'], + settings: { + background: '#f0fff4', + foreground: '#22863a' + } + }, + { + scope: ['markup.changed', 'punctuation.definition.changed'], + settings: { + background: '#ffebda', + foreground: '#f60' + } + }, + { + scope: ['markup.ignored', 'markup.untracked'], + settings: { + background: '#3bf', + foreground: '#f6f8fa' + } + }, + { + scope: 'meta.diff.range', + settings: { + fontStyle: 'bold', + foreground: '#6f42c1' + } + }, + { + scope: 'meta.diff.header', + settings: { + foreground: '#3bf' + } + }, + { + scope: 'meta.separator', + settings: { + fontStyle: 'bold', + foreground: '#3bf' + } + }, + { + scope: 'meta.output', + settings: { + foreground: '#3bf' + } + }, + { + scope: [ + 'brackethighlighter.tag', + 'brackethighlighter.curly', + 'brackethighlighter.round', + 'brackethighlighter.square', + 'brackethighlighter.angle', + 'brackethighlighter.quote' + ], + settings: { + foreground: '#586069' + } + }, + { + scope: 'brackethighlighter.unmatched', + settings: { + foreground: '#b31d28' + } + }, + { + scope: ['constant.other.reference.link', 'string.other.link'], + settings: { + fontStyle: 'underline', + foreground: '#5af' + } + }, + { + scope: ['punctuation.definition.markdown', 'fenced_code.block.language'], + settings: { + foreground: '#e16' + } + } + ], + type: 'light' +} satisfies ThemeInput; + +export default theme; diff --git a/packages/carta-md/src/lib/internal/carta.ts b/packages/carta-md/src/lib/internal/carta.ts index 2661086..47ccc4c 100644 --- a/packages/carta-md/src/lib/internal/carta.ts +++ b/packages/carta-md/src/lib/internal/carta.ts @@ -15,6 +15,16 @@ import { defaultIcons, type Icon, type DefaultIconId } from './icons'; import { defaultPrefixes, type DefaultPrefixId, type Prefix } from './prefixes'; import { Renderer } from './renderer'; import { CustomEvent, type MaybeArray } from './utils'; +import { + loadHighlighter, + loadDefaultTheme, + type Highlighter, + type GrammarRule, + type ShikiOptions, + type DualTheme, + type Theme, + type HighlightingRule +} from './highlight'; /** * Carta-specific event with extra payload. @@ -101,12 +111,12 @@ export interface Options { /** * Highlighter options. */ - // shikiOptions?: ShikiOptions; + shikiOptions?: ShikiOptions; /** * ShikiJS theme * @default 'carta-light' for light mode and 'carta-dark' for dark mode. */ - // theme?: Theme | DualTheme; + theme?: Theme | DualTheme; } /** @@ -157,6 +167,14 @@ export interface Plugin { * elements absolutely. */ components?: ExtensionComponents; + /** + * Custom markdown grammar highlight rules for ShiKi. + */ + grammarRules?: GrammarRule[]; + /** + * Custom markdown highlighting rules for ShiKi. + */ + highlightingRules?: HighlightingRule[]; /** * Use this callback to execute code when one Carta instance loads the extension. * @param data General Carta related data. @@ -167,11 +185,14 @@ export interface Plugin { export class Carta { public readonly sanitizer?: (html: string) => string; public readonly historyOptions?: TextAreaHistoryOptions; - // public readonly theme?: Theme | DualTheme; + public readonly theme?: Theme | DualTheme; + public readonly shikiOptions?: ShikiOptions; public readonly rendererDebounce: number; public readonly keyboardShortcuts: KeyboardShortcut[]; public readonly icons: Icon[]; public readonly prefixes: Prefix[]; + public readonly grammarRules: GrammarRule[]; + public readonly highlightingRules: HighlightingRule[]; public readonly textareaListeners: Listeners; public readonly cartaListeners: Listeners; public readonly components: ExtensionComponents; @@ -182,6 +203,7 @@ export class Carta { private mElement: HTMLDivElement | undefined; private mInput: InputEnhancer | undefined; private mRenderer: Renderer | undefined; + private mHighlighter: Highlighter | Promise<Highlighter> | undefined; private mSyncTransformers: UnifiedTransformer<'sync'>[] = []; private mAsyncTransformers: UnifiedTransformer<'async'>[] = []; @@ -195,6 +217,22 @@ export class Carta { return this.mRenderer; } + public async highlighter(): Promise<Highlighter> { + if (!this.mHighlighter) { + const promise = async () => { + return loadHighlighter({ + theme: this.theme ?? (await loadDefaultTheme()), + grammarRules: this.grammarRules, + highlightingRules: this.highlightingRules, + shiki: this.shikiOptions + }); + }; + this.mHighlighter = promise(); + this.mHighlighter = await this.mHighlighter; + } + return this.mHighlighter; + } + private elementsToBind: { elem: HTMLElement; portal: HTMLElement; @@ -204,7 +242,8 @@ export class Carta { public constructor(options?: Options) { this.sanitizer = options?.sanitizer || undefined; this.historyOptions = options?.historyOptions; - // this.theme = options?.theme; + this.theme = options?.theme; + this.shikiOptions = options?.shikiOptions; this.rendererDebounce = options?.rendererDebounce ?? 300; // Load plugins @@ -214,6 +253,8 @@ export class Carta { this.textareaListeners = []; this.cartaListeners = []; this.components = []; + this.grammarRules = []; + this.highlightingRules = []; const listeners = []; for (const ext of options?.extensions ?? []) { @@ -221,6 +262,8 @@ export class Carta { this.icons.push(...(ext.icons ?? [])); this.prefixes.push(...(ext.prefixes ?? [])); this.components.push(...(ext.components ?? [])); + this.grammarRules.push(...(ext.grammarRules ?? [])); + this.highlightingRules.push(...(ext.highlightingRules ?? [])); listeners.push(...(ext.listeners ?? [])); } diff --git a/packages/carta-md/src/lib/internal/components/Input.svelte b/packages/carta-md/src/lib/internal/components/Input.svelte index aacef71..3874591 100644 --- a/packages/carta-md/src/lib/internal/components/Input.svelte +++ b/packages/carta-md/src/lib/internal/components/Input.svelte @@ -2,8 +2,8 @@ import { onMount } from 'svelte'; import type { Carta } from '../carta'; import type { TextAreaProps } from '../textarea-props'; - - import { Prism, MARKDOWN } from '../highlight'; + import { debounce } from '../utils'; + import { isSingleTheme, loadNestedLanguages } from '../highlight'; export let carta: Carta; export let value = ''; @@ -34,21 +34,43 @@ const setInput = () => { carta.$setInput(textarea, elem, () => { value = textarea.value; - highlightPrism(value); + highlight(value); }); }; - const highlightPrism = (text: string) => { - const html = Prism.highlight(text, MARKDOWN, 'md'); + const highlight = async (text: string) => { + const highlighter = await carta.highlighter(); + let html: string; + + if (isSingleTheme(highlighter.theme)) { + // Single theme + html = highlighter.codeToHtml(text, { + lang: highlighter.lang, + theme: highlighter.theme + }); + } else { + // Dual theme + html = highlighter.codeToHtml(text, { + lang: highlighter.lang, + themes: highlighter.theme + }); + } + if (carta.sanitizer) { highlighted = carta.sanitizer(html); } else { highlighted = html; } - resize(); }; - $: highlightPrism(value); + const highlightNestedLanguages = debounce(async (text: string) => { + const highlighter = await carta.highlighter(); + const { updated } = await loadNestedLanguages(highlighter, text); + if (updated) highlight(text); + }, 300); + + $: highlight(value).then(resize); + $: highlightNestedLanguages(value); onMount(() => { mounted = true; @@ -69,7 +91,7 @@ class="carta-input" bind:this={elem} > - <div class="carta-input-wrapper" class:mounted> + <div class="carta-input-wrapper"> <div class="carta-highlight carta-font-code" tabindex="-1" @@ -116,25 +138,22 @@ width: 100%; max-width: 100%; min-height: 100%; + + overflow-y: hidden; resize: none; padding: 0; margin: 0; border: 0; + color: transparent; + background: transparent; + + outline: none; tab-size: 4; } - .mounted > textarea { - overflow-y: hidden; - outline: none; - - color: transparent; - background: transparent; - } - .carta-highlight { - display: none; position: absolute; left: 0; right: 0; @@ -152,11 +171,7 @@ word-break: break-word; } - .mounted > .carta-highlight { - display: block; - } - - :global(.carta-highlight) { + :global(.carta-highlight .shiki) { margin: 0; tab-size: 4; background-color: transparent !important; diff --git a/packages/carta-md/src/lib/internal/components/Renderer.svelte b/packages/carta-md/src/lib/internal/components/Renderer.svelte index 2c375f4..1141749 100644 --- a/packages/carta-md/src/lib/internal/components/Renderer.svelte +++ b/packages/carta-md/src/lib/internal/components/Renderer.svelte @@ -6,7 +6,6 @@ export let carta: Carta; export let value: string; export let elem: HTMLDivElement; - export let renderCls = 'prose'; export let handleScroll: (e: UIEvent) => void; let mounted = false; @@ -26,7 +25,7 @@ onMount(() => (mounted = true)); </script> -<div bind:this={elem} on:scroll={handleScroll} class="carta-renderer {renderCls}"> +<div bind:this={elem} on:scroll={handleScroll} class="carta-renderer markdown-body"> <!-- eslint-disable-next-line svelte/no-at-html-tags --> {@html renderedHtml} {#if mounted} diff --git a/packages/carta-md/src/lib/internal/highlight.ts b/packages/carta-md/src/lib/internal/highlight.ts index c505326..16cfddf 100644 --- a/packages/carta-md/src/lib/internal/highlight.ts +++ b/packages/carta-md/src/lib/internal/highlight.ts @@ -1,15 +1,268 @@ -// @ts-expect-error no type definitions -import PrismImport from "prismjs/components/prism-core"; -import type PrismType from "prismjs"; +import { + getHighlighter, + type BundledTheme, + type ThemeInput, + type StringLiteralUnion, + type BundledLanguage, + type SpecialLanguage, + type LanguageInput, + type LanguageRegistration, + type HighlighterGeneric, + bundledLanguages, + bundledThemes, + type ThemeRegistration +} from 'shiki'; +import type { Intellisense } from './utils'; -const Prism: typeof PrismType = PrismImport; +/** + * Custom TextMate grammar rule for the highlighter. + */ +export type GrammarRule = { + name: string; + type: 'block' | 'inline'; + definition: LanguageRegistration['repository'][string]; +}; -globalThis.Prism = Prism; -import "prismjs/components/prism-markup"; -import prismMarkdown from "./prism-markdown"; -prismMarkdown(Prism); +/** + * Custom TextMate highlighting rule for the highlighter. + */ +export type HighlightingRule = { + light: NonNullable<ThemeRegistration['tokenColors']>[number]; + dark: NonNullable<ThemeRegistration['tokenColors']>[number]; +}; -const MARKDOWN = Prism.languages["md"]; +/** + * Shiki options for the highlighter. + */ +export type ShikiOptions = { + themes?: Array<ThemeInput | StringLiteralUnion<BundledTheme>>; + langs?: (LanguageInput | StringLiteralUnion<BundledLanguage> | SpecialLanguage)[]; +}; +type CustomMarkdownLangName = Awaited<(typeof import('./assets/markdown'))['default']['name']>; +type DefaultLightThemeName = Awaited<(typeof import('./assets/theme-light'))['default']['name']>; +type DefaultDarkThemeName = Awaited<(typeof import('./assets/theme-dark'))['default']['name']>; +export const customMarkdownLangName: CustomMarkdownLangName = 'cartamd'; +export const defaultLightThemeName: DefaultLightThemeName = 'carta-light'; +export const defaultDarkThemeName: DefaultDarkThemeName = 'carta-dark'; +export const loadDefaultTheme = async (): Promise<{ + light: ThemeRegistration; + dark: ThemeRegistration; +}> => ({ + light: structuredClone((await import('./assets/theme-light')).default), + dark: structuredClone((await import('./assets/theme-dark')).default) +}); -export {Prism, MARKDOWN}; +/** + * Language for the highlighter. + */ +export type Language = Intellisense<BundledLanguage | CustomMarkdownLangName>; +/** + * Theme name for the highlighter. + */ +export type ThemeName = Intellisense<BundledTheme | DefaultLightThemeName | DefaultDarkThemeName>; +/** + * Theme for the highlighter. + */ +export type Theme = ThemeName | ThemeRegistration; +/** + * Dual theme for light and dark mode. + */ +export type DualTheme = { + light: Theme; + dark: Theme; +}; + +/** + * Options for the highlighter. + */ +export type HighlighterOptions = { + grammarRules: GrammarRule[]; + highlightingRules: HighlightingRule[]; + theme: Theme | DualTheme; + shiki?: ShikiOptions; +}; + +/** + * Loads the highlighter instance, with custom rules and options. Uses Shiki under the hood. + * @param rules Custom rules for the highlighter, from plugins. + * @param options Custom options for the highlighter. + * @returns The highlighter instance. + */ +export async function loadHighlighter({ + grammarRules, + highlightingRules, + theme, + shiki +}: HighlighterOptions): Promise<Highlighter> { + // Inject rules into the custom markdown language + const injectGrammarRules = ( + lang: Awaited<(typeof import('./assets/markdown'))['default']>, + rules: GrammarRule[] + ) => { + lang.repository = { + ...langDefinition.repository, + ...Object.fromEntries(rules.map(({ name, definition }) => [name, definition])) + }; + for (const rule of rules) { + if (rule.type === 'block') { + lang.repository.block.patterns.unshift({ include: `#${rule.name}` }); + } else { + lang.repository.inline.patterns.unshift({ include: `#${rule.name}` }); + } + } + }; + + const injectHighlightRules = (theme: ThemeRegistration, rules: HighlightingRule[]) => { + if (theme.type === 'light') { + theme.tokenColors ||= []; + theme.tokenColors.unshift(...rules.map(({ light }) => light)); + } else { + theme.tokenColors ||= []; + theme.tokenColors.unshift(...rules.map(({ dark }) => dark)); + } + }; + + // Additional themes and languages provided by the user + const themes = shiki?.themes ?? []; + const langs = shiki?.langs ?? []; + + const highlighter: HighlighterGeneric<BundledLanguage, BundledTheme> = await getHighlighter({ + themes, + langs + }); + + // Custom markdown language + const langDefinition = (await import('./assets/markdown')).default; + injectGrammarRules(langDefinition, grammarRules); + await highlighter.loadLanguage(langDefinition); + + // Custom themes + if (isSingleTheme(theme)) { + let registration: ThemeRegistration; + if (isThemeRegistration(theme)) { + registration = theme; + } else { + registration = (await bundledThemes[theme as BundledTheme]()).default; + } + + injectHighlightRules(registration, highlightingRules); + + await highlighter.loadTheme(registration); + } else { + const { light, dark } = theme; + + let lightRegistration: ThemeRegistration; + let darkRegistration: ThemeRegistration; + + if (isThemeRegistration(light)) { + lightRegistration = light; + } else { + lightRegistration = (await bundledThemes[light as BundledTheme]()).default; + } + + if (isThemeRegistration(dark)) { + darkRegistration = dark; + } else { + darkRegistration = (await bundledThemes[dark as BundledTheme]()).default; + } + + injectHighlightRules(lightRegistration, highlightingRules); + injectHighlightRules(darkRegistration, highlightingRules); + + await highlighter.loadTheme(lightRegistration); + await highlighter.loadTheme(darkRegistration); + } + + return { + theme, + lang: customMarkdownLangName, + ...highlighter + }; +} +export interface Highlighter extends HighlighterGeneric<BundledLanguage, BundledTheme> { + /** + * The language specified for the highlighter. + */ + theme: Theme | DualTheme; + /** + * The theme specified for the highlighter. + */ + lang: Language; +} + +/** + * Checks if a language is a bundled language. + * @param lang The language to check. + * @returns Whether the language is a bundled language. + */ +export const isBundleLanguage = (lang: string): lang is BundledLanguage => + Object.keys(bundledLanguages).includes(lang); +/** + * Checks if a theme is a bundled theme. + * @param theme The theme to check. + * @returns Whether the theme is a bundled theme. + */ +export const isBundleTheme = (theme: string): theme is BundledTheme => + Object.keys(bundledThemes).includes(theme); +/** + * Checks if a theme is a dual theme. + * @param theme The theme to check. + * @returns Whether the theme is a dual theme. + */ +export const isDualTheme = (theme: Theme | DualTheme): theme is DualTheme => + typeof theme == 'object' && 'light' in theme && 'dark' in theme; +/** + * Checks if a theme is a single theme. + * @param theme The theme to check. + * @returns Whether the theme is a single theme. + */ +export const isSingleTheme = (theme: Theme | DualTheme): theme is Theme => !isDualTheme(theme); +/** + * Checks if a theme is a theme registration. + * @param theme The theme to check. + * @returns Whether the theme is a theme registration. + */ +export const isThemeRegistration = (theme: Theme): theme is ThemeRegistration => + typeof theme == 'object'; + +/** + * Find all nested languages in the markdown text and load them into the highlighter. + * @param text Markdown text to parse for nested languages. + * @returns The set of nested languages found in the text. + */ +const findNestedLanguages = (text: string) => { + const languages = new Set<string>(); + + const regex = /```([a-z]+)\n([\s\S]+?)\n```/g; + let match: RegExpExecArray | null; + while ((match = regex.exec(text))) { + languages.add(match[1]); + } + return languages; +}; + +/** + * Load all nested languages found in the markdown text into the highlighter. + * @param highlighter The highlighter instance. + * @param text The text to parse for nested languages. + * @returns Whether the highlighter was updated with new languages. + */ +export const loadNestedLanguages = async (highlighter: Highlighter, text: string) => { + text = text.replaceAll('\r\n', '\n'); // Normalize line endings + + const languages = findNestedLanguages(text); + const loadedLanguages = highlighter.getLoadedLanguages(); + let updated = false; + for (const lang of languages) { + if (isBundleLanguage(lang) && !loadedLanguages.includes(lang)) { + await highlighter.loadLanguage(lang); + loadedLanguages.push(lang); + updated = true; + } + } + + return { + updated + }; +}; diff --git a/packages/carta-md/src/lib/internal/prism-markdown.js b/packages/carta-md/src/lib/internal/prism-markdown.js deleted file mode 100644 index 7e16857..0000000 --- a/packages/carta-md/src/lib/internal/prism-markdown.js +++ /dev/null @@ -1,420 +0,0 @@ -// Original source: https://github.com/PrismJS/prism/blob/master/components/prism-markdown.js -export default function (Prism) { - - // Allow only one line break - const inner = /(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source; - - /** - * This function is intended for the creation of the bold or italic pattern. - * - * This also adds a lookbehind group to the given pattern to ensure that the pattern is not backslash-escaped. - * - * _Note:_ Keep in mind that this adds a capturing group. - * - * @param {string} pattern - * @returns {RegExp} - */ - function createInline(pattern) { - pattern = pattern.replace(/<inner>/g, function () { return inner; }); - return RegExp(/((?:^|[^\\])(?:\\{2})*)/.source + '(?:' + pattern + ')'); - } - - - const tableCell = /(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source; - const tableRow = /\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g, function () { return tableCell; }); - const tableLine = /\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source; - - - Prism.languages.markdown = Prism.languages.extend('markup', {}); - Prism.languages.insertBefore('markdown', 'prolog', { - 'front-matter-block': { - pattern: /(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/, - lookbehind: true, - greedy: true, - inside: { - 'punctuation': /^---|---$/, - 'front-matter': { - pattern: /\S+(?:\s+\S+)*/, - alias: ['yaml', 'language-yaml'], - inside: Prism.languages.yaml - } - } - }, - 'blockquote': { - // > ... - pattern: /^>(?:[\t ]*>)*/m, - alias: 'punctuation' - }, - 'table': { - pattern: RegExp('^' + tableRow + tableLine + '(?:' + tableRow + ')*', 'm'), - inside: { - 'table-data-rows': { - pattern: RegExp('^(' + tableRow + tableLine + ')(?:' + tableRow + ')*$'), - lookbehind: true, - inside: { - 'table-data': { - pattern: RegExp(tableCell), - inside: Prism.languages.markdown - }, - 'punctuation': /\|/ - } - }, - 'table-line': { - pattern: RegExp('^(' + tableRow + ')' + tableLine + '$'), - lookbehind: true, - inside: { - 'punctuation': /\||:?-{3,}:?/ - } - }, - 'table-header-row': { - pattern: RegExp('^' + tableRow + '$'), - inside: { - 'table-header': { - pattern: RegExp(tableCell), - alias: 'important', - inside: Prism.languages.markdown - }, - 'punctuation': /\|/ - } - } - } - }, - 'code': [ - { - // Prefixed by 4 spaces or 1 tab and preceded by an empty line - pattern: /((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/, - lookbehind: true, - alias: 'keyword' - }, - { - // ```optional language - // code block - // ``` - pattern: /^```[\s\S]*?^```$/m, - greedy: true, - inside: { - 'code-block': { - pattern: /^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m, - lookbehind: true - }, - 'code-language': { - pattern: /^(```).+/, - lookbehind: true - }, - 'punctuation': /```/ - } - } - ], - 'title': [ - { - // title 1 - // ======= - - // title 2 - // ------- - pattern: /\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m, - alias: 'important', - inside: { - punctuation: /==+$|--+$/ - } - }, - { - // # title 1 - // ###### title 6 - pattern: /(^\s*)#.+/m, - lookbehind: true, - alias: 'important', - inside: { - punctuation: /^#+|#+$/ - } - } - ], - 'hr': { - // *** - // --- - // * * * - // ----------- - pattern: /(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m, - lookbehind: true, - alias: 'punctuation' - }, - 'list': { - // * item - // + item - // - item - // 1. item - pattern: /(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m, - lookbehind: true, - alias: 'punctuation' - }, - 'url-reference': { - // [id]: http://example.com "Optional title" - // [id]: http://example.com 'Optional title' - // [id]: http://example.com (Optional title) - // [id]: <http://example.com> "Optional title" - pattern: /!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/, - inside: { - 'variable': { - pattern: /^(!?\[)[^\]]+/, - lookbehind: true - }, - 'string': /(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/, - 'punctuation': /^[\[\]!:]|[<>]/ - }, - alias: 'url' - }, - 'bold': { - // **strong** - // __strong__ - - // allow one nested instance of italic text using the same delimiter - pattern: createInline(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source), - lookbehind: true, - greedy: true, - inside: { - 'content': { - pattern: /(^..)[\s\S]+(?=..$)/, - lookbehind: true, - inside: {} // see below - }, - 'punctuation': /\*\*|__/ - } - }, - 'italic': { - // *em* - // _em_ - - // allow one nested instance of bold text using the same delimiter - pattern: createInline(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source), - lookbehind: true, - greedy: true, - inside: { - 'content': { - pattern: /(^.)[\s\S]+(?=.$)/, - lookbehind: true, - inside: {} // see below - }, - 'punctuation': /[*_]/ - } - }, - 'strike': { - // ~~strike through~~ - // ~strike~ - pattern: createInline(/(~~?)(?:(?!~)<inner>)+\2/.source), - lookbehind: true, - greedy: true, - inside: { - 'content': { - pattern: /(^~~?)[\s\S]+(?=\1$)/, - lookbehind: true, - inside: {} // see below - }, - 'punctuation': /~~?/ - } - }, - 'code-snippet': { - // `code` - // ``code`` - pattern: /(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/, - lookbehind: true, - greedy: true, - alias: ['code', 'keyword'] - }, - 'url': { - // [example](http://example.com "Optional title") - // [example][id] - // [example] [id] - pattern: createInline(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source), - lookbehind: true, - greedy: true, - inside: { - 'operator': /^!/, - 'content': { - pattern: /(^\[)[^\]]+(?=\])/, - lookbehind: true, - inside: {} // see below - }, - 'variable': { - pattern: /(^\][ \t]?\[)[^\]]+(?=\]$)/, - lookbehind: true - }, - 'url': { - pattern: /(^\]\()[^\s)]+/, - lookbehind: true - }, - 'string': { - pattern: /(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/, - lookbehind: true - } - } - }, - 'url-autolink': { - pattern: /https?:\/\/(?:[^\\\n\r >])+/, - lookbehind: true, - greedy: true, - alias: 'url', - } - }); - - ['url', 'bold', 'italic', 'strike'].forEach(function (token) { - ['url', 'bold', 'italic', 'strike', 'code-snippet'].forEach(function (inside) { - if (token !== inside) { - Prism.languages.markdown[token].inside.content.inside[inside] = Prism.languages.markdown[inside]; - } - }); - }); - - Prism.hooks.add('after-tokenize', function (env) { - if (env.language !== 'markdown' && env.language !== 'md') { - return; - } - - function walkTokens(tokens) { - if (!tokens || typeof tokens === 'string') { - return; - } - - for (let i = 0, l = tokens.length; i < l; i++) { - const token = tokens[i]; - - if (token.type !== 'code') { - walkTokens(token.content); - continue; - } - - /* - * Add the correct `language-xxxx` class to this code block. Keep in mind that the `code-language` token - * is optional. But the grammar is defined so that there is only one case we have to handle: - * - * token.content = [ - * <span class="punctuation">```</span>, - * <span class="code-language">xxxx</span>, - * '\n', // exactly one new lines (\r or \n or \r\n) - * <span class="code-block">...</span>, - * '\n', // exactly one new lines again - * <span class="punctuation">```</span> - * ]; - */ - - const codeLang = token.content[1]; - const codeBlock = token.content[3]; - - if (codeLang && codeBlock && - codeLang.type === 'code-language' && codeBlock.type === 'code-block' && - typeof codeLang.content === 'string') { - - // this might be a language that Prism does not support - - // do some replacements to support C++, C#, and F# - let lang = codeLang.content.replace(/\b#/g, 'sharp').replace(/\b\+\+/g, 'pp'); - // only use the first word - lang = (/[a-z][\w-]*/i.exec(lang) || [''])[0].toLowerCase(); - const alias = 'language-' + lang; - - // add alias - if (!codeBlock.alias) { - codeBlock.alias = [alias]; - } else if (typeof codeBlock.alias === 'string') { - codeBlock.alias = [codeBlock.alias, alias]; - } else { - codeBlock.alias.push(alias); - } - } - } - } - - walkTokens(env.tokens); - }); - - Prism.hooks.add('wrap', function (env) { - if (env.type !== 'code-block') { - return; - } - - let codeLang = ''; - for (let i = 0, l = env.classes.length; i < l; i++) { - const cls = env.classes[i]; - const match = /language-(.+)/.exec(cls); - if (match) { - codeLang = match[1]; - break; - } - } - - const grammar = Prism.languages[codeLang]; - - if (!grammar) { - if (codeLang && codeLang !== 'none' && Prism.plugins.autoloader) { - const id = 'md-' + new Date().valueOf() + '-' + Math.floor(Math.random() * 1e16); - env.attributes['id'] = id; - - Prism.plugins.autoloader.loadLanguages(codeLang, function () { - const ele = document.getElementById(id); - if (ele) { - ele.innerHTML = Prism.highlight(ele.textContent, Prism.languages[codeLang], codeLang); - } - }); - } - } else { - env.content = Prism.highlight(textContent(env.content), grammar, codeLang); - } - }); - - const tagPattern = RegExp(Prism.languages.markup.tag.pattern.source, 'gi'); - - /** - * A list of known entity names. - * - * This will always be incomplete to save space. The current list is the one used by lowdash's unescape function. - * - * @see {@link https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/unescape.js#L2} - */ - const KNOWN_ENTITY_NAMES = { - 'amp': '&', - 'lt': '<', - 'gt': '>', - 'quot': '"', - }; - - // IE 11 doesn't support `String.fromCodePoint` - const fromCodePoint = String.fromCodePoint || String.fromCharCode; - - /** - * Returns the text content of a given HTML source code string. - * - * @param {string} html - * @returns {string} - */ - function textContent(html) { - // remove all tags - let text = html.replace(tagPattern, ''); - - // decode known entities - text = text.replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi, function (m, code) { - code = code.toLowerCase(); - - if (code[0] === '#') { - let value; - if (code[1] === 'x') { - value = parseInt(code.slice(2), 16); - } else { - value = Number(code.slice(1)); - } - - return fromCodePoint(value); - } else { - const known = KNOWN_ENTITY_NAMES[code]; - if (known) { - return known; - } - - // unable to decode - return m; - } - }); - - return text; - } - - Prism.languages.md = Prism.languages.markdown; -} diff --git a/packages/carta-md/src/routes/+page.svelte b/packages/carta-md/src/routes/+page.svelte index 7799cde..a8ff175 100644 --- a/packages/carta-md/src/routes/+page.svelte +++ b/packages/carta-md/src/routes/+page.svelte @@ -4,7 +4,6 @@ import ToggleTheme from './ToggleTheme.svelte'; import sampleText from './sample.md?raw'; import '$lib/default.css'; - import '$lib/highlight.css'; const carta = new Carta(); </script> diff --git a/packages/carta-md/src/routes/ToggleTheme.svelte b/packages/carta-md/src/routes/ToggleTheme.svelte index 2598e49..8f369a4 100644 --- a/packages/carta-md/src/routes/ToggleTheme.svelte +++ b/packages/carta-md/src/routes/ToggleTheme.svelte @@ -50,7 +50,7 @@ background: #1b1b1f; } - :global(html.dark .prose) { + :global(html.dark .markdown-body) { color: #fff; } @@ -67,8 +67,8 @@ /* Code dark mode */ - :global(html.dark .carta-highlight), - :global(html.dark .carta-highlight span) { - color: var(--hl-dark) !important; + :global(html.dark .shiki), + :global(html.dark .shiki span) { + color: var(--shiki-dark) !important; } </style> diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7cae135..1968455 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -159,9 +159,6 @@ importers: packages/carta-md: dependencies: - prismjs: - specifier: ^1.29.0 - version: 1.29.0 rehype-stringify: specifier: ^10.0.0 version: 10.0.0 @@ -174,6 +171,9 @@ importers: remark-rehype: specifier: ^11.1.0 version: 11.1.0 + shiki: + specifier: ^1.4.0 + version: 1.4.0 svelte: specifier: ^3.54.0 || ^4.0.0 version: 4.2.2 @@ -193,9 +193,6 @@ importers: '@sveltejs/vite-plugin-svelte': specifier: ^3.0.2 version: 3.0.2(svelte@4.2.2)(vite@5.1.6) - '@types/prismjs': - specifier: ^1.26.4 - version: 1.26.4 svelte-check: specifier: ^3.6.7 version: 3.6.7(postcss@8.4.31)(svelte@4.2.2) @@ -1738,10 +1735,6 @@ packages: resolution: {integrity: sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==} dev: true - /@types/prismjs@1.26.4: - resolution: {integrity: sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==} - dev: true - /@types/pug@2.0.6: resolution: {integrity: sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==} dev: true @@ -5881,6 +5874,7 @@ packages: /prismjs@1.29.0: resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} engines: {node: '>=6'} + dev: true /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}