From 72ae661e9e6f7b32adf9e6a47cdc6352dfa2a27d Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Thu, 8 Apr 2021 15:17:00 -0400 Subject: [PATCH] Add support for syntax highlighting of code blocks (#65) * Add support for syntax highlighting of code blocks * Escape usage of backtick strings * Add workspace root for snowpack * Use prismjs/components as an external module --- astro-prism/index.mjs | 2 +- components/Prism.astro | 30 ++++++- examples/snowpack/package-lock.json | 124 +++++++-------------------- examples/snowpack/snowpack.config.js | 3 + package.json | 2 +- src/@types/optimizer.ts | 2 +- src/compiler/optimize/index.ts | 7 +- src/compiler/optimize/prism.ts | 85 ++++++++++++++++++ src/runtime.ts | 2 +- www/astro/pages/blog.md | 2 - 10 files changed, 154 insertions(+), 105 deletions(-) create mode 100644 examples/snowpack/snowpack.config.js create mode 100644 src/compiler/optimize/prism.ts diff --git a/astro-prism/index.mjs b/astro-prism/index.mjs index 1d0e1a98f..bb4fc53e4 100644 --- a/astro-prism/index.mjs +++ b/astro-prism/index.mjs @@ -9,7 +9,7 @@ export function addAstro(Prism) { scriptLang = 'typescript'; } else { scriptLang = 'javascript'; - console.warn('Prism TypeScript language not loading, Astro scripts will be treated as JavaScript.'); + console.warn('Prism TypeScript language not loaded, Astro scripts will be treated as JavaScript.'); } diff --git a/components/Prism.astro b/components/Prism.astro index 52995fab7..7f47becb2 100644 --- a/components/Prism.astro +++ b/components/Prism.astro @@ -1,12 +1,38 @@ --- import Prism from 'prismjs'; import { addAstro } from '../astro-prism/index.mjs'; - -addAstro(Prism); +import * as loadLanguages from 'prismjs/components/'; export let lang; export let code; +const languageMap = new Map([ + ['ts', 'typescript'] +]); + +if(lang == null) { + console.warn('Prism.astro: No language provided.'); +} + +const ensureLoaded = lang => { + if(!Prism.languages[lang]) { + loadLanguages([lang]); + } +}; + +if(languageMap.has(lang)) { + ensureLoaded(languageMap.get(lang)); +} else if(lang === 'astro') { + ensureLoaded('typescript'); + addAstro(Prism); +} else { + ensureLoaded(lang); +} + +if(!Prism.languages[lang]) { + console.warn(`Unable to load the language: ${lang}`); +} + const grammar = Prism.languages[lang]; let html = Prism.highlight(code, grammar, lang); diff --git a/examples/snowpack/package-lock.json b/examples/snowpack/package-lock.json index afa079c75..c822b6f07 100644 --- a/examples/snowpack/package-lock.json +++ b/examples/snowpack/package-lock.json @@ -980,8 +980,6 @@ "@babel/traverse": "^7.13.0", "@snowpack/plugin-sass": "^1.4.0", "@snowpack/plugin-svelte": "^3.6.0", - "@snowpack/plugin-vue": "^2.4.0", - "@vue/server-renderer": "^3.0.10", "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", "astring": "^1.7.0", @@ -1008,9 +1006,7 @@ "react-dom": "^17.0.1", "rollup": "^2.43.1", "sass": "^1.32.8", - "snowpack": "^3.2.2", "svelte": "^3.35.0", - "vue": "^3.0.10", "yargs-parser": "^20.2.7" }, "dependencies": { @@ -1121,8 +1117,7 @@ "@babel/parser": { "version": "7.13.10", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.10.tgz", - "integrity": "sha512-0s7Mlrw9uTWkYua7xWr99Wpk2bnGa0ANleKfksYAES8LpWH4gW1OUr42vqKNf0us5UQNfru2wPqMqRITzq/SIQ==", - "dev": true + "integrity": "sha512-0s7Mlrw9uTWkYua7xWr99Wpk2bnGa0ANleKfksYAES8LpWH4gW1OUr42vqKNf0us5UQNfru2wPqMqRITzq/SIQ==" }, "@babel/template": { "version": "7.12.13", @@ -1261,7 +1256,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@snowpack/plugin-vue/-/plugin-vue-2.3.0.tgz", "integrity": "sha512-W53I7nZrHaV85yNqo9PaD1M0FS0Ftw9+eiGf8mez7lyvSd//MGAhdIjXO7Xn2RhnBauM/BnbnUxu/L/2/P5FiA==", - "dev": true, "requires": { "@vue/compiler-sfc": "^3.0.0", "hash-sum": "^2.0.0" @@ -1472,7 +1466,6 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.0.7.tgz", "integrity": "sha512-JFohgBXoyUc3mdeI2WxlhjQZ5fakfemJkZHX8Gu/nFbEg3+lKVUZmNKWmmnp9aOzJQZKoj77LjmFxiP+P+7lMQ==", - "dev": true, "requires": { "@babel/parser": "^7.12.0", "@babel/types": "^7.12.0", @@ -1484,8 +1477,7 @@ "estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" } } }, @@ -1493,7 +1485,6 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.0.7.tgz", "integrity": "sha512-VnIH9EbWQm/Tkcp+8dCaNVsVvhm/vxCrIKWRkXY9215hTqOqQOvejT8IMjd2kc++nIsYMsdQk6H9qqBvoLe/Cw==", - "dev": true, "requires": { "@vue/compiler-core": "3.0.7", "@vue/shared": "3.0.7" @@ -1503,7 +1494,6 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.0.7.tgz", "integrity": "sha512-37/QILpGE+J3V+bP9Slg9e6xGqfk+MmS2Yj8ChR4fS0/qWUU/YoYHE0GPIzjmBdH0JVOOmJqunxowIXmqNiHng==", - "dev": true, "requires": { "@babel/parser": "^7.12.0", "@babel/types": "^7.12.0", @@ -1526,14 +1516,12 @@ "estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "requires": { "yallist": "^3.0.2" } @@ -1541,8 +1529,7 @@ "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } }, @@ -1550,7 +1537,6 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.0.7.tgz", "integrity": "sha512-nHRbHeSpfXwjypettjrA16TjgfDcPEwq3m/zHnGyLC1QqdLtklXmpSM43/CPwwTCRa/qdt0pldJf22MiCEuTSQ==", - "dev": true, "requires": { "@vue/compiler-dom": "3.0.7", "@vue/shared": "3.0.7" @@ -1560,7 +1546,6 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.0.7.tgz", "integrity": "sha512-FotWcNNaKhqpFZrdgsUOZ1enlJ5lhTt01CNTtLSyK7jYFgZBTuw8vKsEutZKDYZ1XKotOfoeO8N3pZQqmM6Etw==", - "dev": true, "requires": { "@vue/shared": "3.0.7" } @@ -1569,7 +1554,6 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.0.7.tgz", "integrity": "sha512-DBAZAwVvdmMXuyd6/9qqj/kYr/GaLTmn1L2/QLxLwP+UfhIboiTSBc/tUUb8MRk7Bb98GzNeAWkkT6AfooS3dQ==", - "dev": true, "requires": { "@vue/reactivity": "3.0.7", "@vue/shared": "3.0.7" @@ -1579,7 +1563,6 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.7.tgz", "integrity": "sha512-Oij4ruOtnpQpCj+/Q3JPzgpTJ1Q7+N67pA53A8KVITEtxfvKL46NN6dhAZ5NGqwX6RWZpYqWQNewITeF0pHr8g==", - "dev": true, "requires": { "@vue/runtime-core": "3.0.7", "@vue/shared": "3.0.7", @@ -1590,7 +1573,6 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.0.7.tgz", "integrity": "sha512-3idEbDTQ0GSPgGTiM9Ml4IwPOityotTRUyrDttAyFoSz6DI1RvE1QR0nSQR7TMgMDXwbO22gf+nMYVkj7c9VRg==", - "dev": true, "requires": { "@vue/compiler-ssr": "3.0.7", "@vue/shared": "3.0.7" @@ -1599,8 +1581,7 @@ "@vue/shared": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.0.7.tgz", - "integrity": "sha512-dn5FyfSc4ky424jH4FntiHno7Ss5yLkqKNmM/NXwANRnlkmqu74pnGetexDFVG5phMk9/FhwovUZCWGxsotVKg==", - "dev": true + "integrity": "sha512-dn5FyfSc4ky424jH4FntiHno7Ss5yLkqKNmM/NXwANRnlkmqu74pnGetexDFVG5phMk9/FhwovUZCWGxsotVKg==" }, "abbrev": { "version": "1.1.1", @@ -1731,14 +1712,12 @@ "big-integer": { "version": "1.6.48", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", - "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", - "dev": true + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==" }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, "binary-extensions": { "version": "2.2.0", @@ -1748,8 +1727,7 @@ "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "boolbase": { "version": "1.0.0", @@ -1775,7 +1753,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz", "integrity": "sha1-1g1dzCDLptx+HymbNdPh+V2vuuY=", - "dev": true, "requires": { "big-integer": "^1.6.7" } @@ -1951,8 +1928,7 @@ "cli-spinners": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz", - "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==", - "dev": true + "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==" }, "cliui": { "version": "7.0.4", @@ -2003,8 +1979,7 @@ "colorette": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" }, "concat-map": { "version": "0.0.1", @@ -2078,7 +2053,6 @@ "version": "0.16.0", "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz", "integrity": "sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==", - "dev": true, "requires": { "bluebird": "^3.7.2" } @@ -2147,14 +2121,12 @@ "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" }, "csstype": { "version": "2.6.16", "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz", - "integrity": "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q==", - "dev": true + "integrity": "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q==" }, "date-fns": { "version": "2.19.0", @@ -2197,7 +2169,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-2.0.0.tgz", "integrity": "sha1-AezONxpx6F8VoXF354YwR+c9vn0=", - "dev": true, "requires": { "bplist-parser": "^0.1.0", "pify": "^2.3.0", @@ -2208,7 +2179,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz", "integrity": "sha1-F+soB5h/dpUunASF/DEdBqgmouA=", - "dev": true, "requires": { "os-homedir": "^1.0.0" } @@ -2319,8 +2289,7 @@ "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" }, "end-of-stream": { "version": "1.4.4", @@ -2673,8 +2642,7 @@ "fdir": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-5.0.0.tgz", - "integrity": "sha512-cteqwWMA43lEmgwOg5HSdvhVFD39vHjQDhZkRMlKmeoNPtSSgUw1nUypydiY2upMdGiBFBZvNBDbnoBh0yCzaQ==", - "dev": true + "integrity": "sha512-cteqwWMA43lEmgwOg5HSdvhVFD39vHjQDhZkRMlKmeoNPtSSgUw1nUypydiY2upMdGiBFBZvNBDbnoBh0yCzaQ==" }, "file-entry-cache": { "version": "6.0.1", @@ -2747,7 +2715,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz", "integrity": "sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ==", - "dev": true, "requires": { "loader-utils": "^1.1.0" } @@ -2895,8 +2862,7 @@ "hash-sum": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", - "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", - "dev": true + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" }, "hosted-git-info": { "version": "2.8.8", @@ -2960,14 +2926,12 @@ "icss-replace-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", - "dev": true + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" }, "icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==" }, "ignore": { "version": "5.1.8", @@ -3001,8 +2965,7 @@ "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" }, "inflight": { "version": "1.0.6", @@ -3077,8 +3040,7 @@ "is-docker": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", - "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", - "dev": true + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==" }, "is-extendable": { "version": "0.1.1", @@ -3154,7 +3116,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, "requires": { "is-docker": "^2.0.0" } @@ -3218,7 +3179,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, "requires": { "minimist": "^1.2.0" } @@ -3268,7 +3228,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, "requires": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -3298,8 +3257,7 @@ "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "dev": true + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, "loose-envify": { "version": "1.4.0", @@ -3327,7 +3285,6 @@ "version": "0.25.7", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "dev": true, "requires": { "sourcemap-codec": "^1.4.4" } @@ -3357,7 +3314,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, "requires": { "source-map": "^0.6.1" } @@ -3496,8 +3452,7 @@ "nanoid": { "version": "3.1.22", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz", - "integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==", - "dev": true + "integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==" }, "natural-compare": { "version": "1.4.0", @@ -3631,7 +3586,6 @@ "version": "7.4.2", "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dev": true, "requires": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" @@ -3653,8 +3607,7 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "p-cancelable": { "version": "1.1.0", @@ -3777,14 +3730,12 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" }, "postcss": { "version": "8.2.8", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.8.tgz", "integrity": "sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw==", - "dev": true, "requires": { "colorette": "^1.2.2", "nanoid": "^3.1.20", @@ -3795,7 +3746,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules/-/postcss-modules-4.0.0.tgz", "integrity": "sha512-ghS/ovDzDqARm4Zj6L2ntadjyQMoyJmi0JkLlYtH2QFLrvNlxH5OAVRPWPeKilB0pY7SbuhO173KOWkPAxRJcw==", - "dev": true, "requires": { "generic-names": "^2.0.1", "icss-replace-symbols": "^1.1.0", @@ -3810,14 +3760,12 @@ "postcss-modules-extract-imports": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==" }, "postcss-modules-local-by-default": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", - "dev": true, "requires": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -3828,7 +3776,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "dev": true, "requires": { "postcss-selector-parser": "^6.0.4" } @@ -3837,7 +3784,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dev": true, "requires": { "icss-utils": "^5.0.0" } @@ -3846,7 +3792,6 @@ "version": "6.0.4", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz", "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==", - "dev": true, "requires": { "cssesc": "^3.0.0", "indexes-of": "^1.0.1", @@ -3857,8 +3802,7 @@ "postcss-value-parser": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", - "dev": true + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" }, "preact": { "version": "10.5.12", @@ -4088,7 +4032,6 @@ "version": "2.44.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.44.0.tgz", "integrity": "sha512-rGSF4pLwvuaH/x4nAS+zP6UNn5YUDWf/TeEU5IoXSZKBbKRNTCI3qMnYXKZgrC0D2KzS2baiOZt1OlqhMu5rnQ==", - "dev": true, "requires": { "fsevents": "~2.3.1" } @@ -4230,7 +4173,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/snowpack/-/snowpack-3.1.2.tgz", "integrity": "sha512-LsYlBNjB/t/p5QP434Pa1TqjyuX8VtXiYQaAWZkOn1d1TVKEt7nigMBr8Z+EDXYn6YlLXYKHXDvv/NhUS7Ri9A==", - "dev": true, "requires": { "cli-spinners": "^2.5.0", "default-browser-id": "^2.0.0", @@ -4246,22 +4188,19 @@ "esbuild": { "version": "0.9.7", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.9.7.tgz", - "integrity": "sha512-VtUf6aQ89VTmMLKrWHYG50uByMF4JQlVysb8dmg6cOgW8JnFCipmz7p+HNBl+RR3LLCuBxFGVauAe2wfnF9bLg==", - "dev": true + "integrity": "sha512-VtUf6aQ89VTmMLKrWHYG50uByMF4JQlVysb8dmg6cOgW8JnFCipmz7p+HNBl+RR3LLCuBxFGVauAe2wfnF9bLg==" } } }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" }, "spawn-command": { "version": "0.0.2-1", @@ -4304,8 +4243,7 @@ "string-hash": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", - "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=", - "dev": true + "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=" }, "string-width": { "version": "4.2.2", @@ -4586,8 +4524,7 @@ "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" }, "unique-string": { "version": "2.0.0", @@ -4673,7 +4610,6 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/vue/-/vue-3.0.7.tgz", "integrity": "sha512-8h4TikD+JabbMK9aRlBO4laG0AtNHRPHynxYgWZ9sq1YUPfzynd9Jeeb27XNyZytC7aCQRX9xe1+TQJuc181Tw==", - "dev": true, "requires": { "@vue/compiler-dom": "3.0.7", "@vue/runtime-dom": "3.0.7", diff --git a/examples/snowpack/snowpack.config.js b/examples/snowpack/snowpack.config.js new file mode 100644 index 000000000..5a800b10f --- /dev/null +++ b/examples/snowpack/snowpack.config.js @@ -0,0 +1,3 @@ +module.exports = { + workspaceRoot: '../../' +}; diff --git a/package.json b/package.json index 206a8c084..e221e8642 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "files": [ "components", "lib", - "prism-astro" + "astro-prism" ], "scripts": { "build": "tsc", diff --git a/src/@types/optimizer.ts b/src/@types/optimizer.ts index a076ae9b8..b6459ab51 100644 --- a/src/@types/optimizer.ts +++ b/src/@types/optimizer.ts @@ -1,7 +1,7 @@ import type { TemplateNode } from '../parser/interfaces'; import type { CompileOptions } from './compiler'; -export type VisitorFn = (node: TemplateNode, parent: TemplateNode, type: string, index: number) => void; +export type VisitorFn = (this: { skip: () => void; remove: () => void; replace: (node: T) => void }, node: T, parent: T, type: string, index: number) => void; export interface NodeVisitor { enter?: VisitorFn; diff --git a/src/compiler/optimize/index.ts b/src/compiler/optimize/index.ts index a7bf828e0..fcbd6e950 100644 --- a/src/compiler/optimize/index.ts +++ b/src/compiler/optimize/index.ts @@ -7,6 +7,7 @@ import { walk } from 'estree-walker'; import optimizeStyles from './styles.js'; import optimizeDoctype from './doctype.js'; import optimizeModuleScripts from './module-scripts.js'; +import optimizeCodeBlocks from './prism.js'; interface VisitorCollection { enter: Map; @@ -57,7 +58,7 @@ function walkAstWithVisitors(tmpl: TemplateNode, collection: VisitorCollection) if (collection.enter.has(node.type)) { const fns = collection.enter.get(node.type)!; for (let fn of fns) { - fn(node, parent, key, index); + fn.call(this, node, parent, key, index); } } }, @@ -65,7 +66,7 @@ function walkAstWithVisitors(tmpl: TemplateNode, collection: VisitorCollection) if (collection.leave.has(node.type)) { const fns = collection.leave.get(node.type)!; for (let fn of fns) { - fn(node, parent, key, index); + fn.call(this, node, parent, key, index); } } }, @@ -83,7 +84,7 @@ export async function optimize(ast: Ast, opts: OptimizeOptions) { const cssVisitors = createVisitorCollection(); const finalizers: Array<() => Promise> = []; - const optimizers = [optimizeStyles(opts), optimizeDoctype(opts), optimizeModuleScripts(opts)]; + const optimizers = [optimizeStyles(opts), optimizeDoctype(opts), optimizeModuleScripts(opts), optimizeCodeBlocks(ast.module)]; for (const optimizer of optimizers) { collectVisitors(optimizer, htmlVisitors, cssVisitors, finalizers); diff --git a/src/compiler/optimize/prism.ts b/src/compiler/optimize/prism.ts new file mode 100644 index 000000000..2a96ab73d --- /dev/null +++ b/src/compiler/optimize/prism.ts @@ -0,0 +1,85 @@ +import type { Optimizer } from '../../@types/optimizer'; +import type { Script } from '../../parser/interfaces'; +import { getAttrValue } from '../../ast.js'; + +const PRISM_IMPORT = `import Prism from 'astro/components/Prism.astro';\n`; +const prismImportExp = /import Prism from ['"]astro\/components\/Prism.astro['"]/; + +function escape(code: string) { + return code.replace(/[`$]/g, match => { + return '\\' + match; + }); +} + +export default function (module: Script): Optimizer { + let usesPrism = false; + + return { + visitors: { + html: { + Element: { + enter(node) { + if (node.name !== 'code') return; + const className = getAttrValue(node.attributes, 'class') || ''; + const classes = className.split(' '); + + let lang; + for (let cn of classes) { + const matches = /language-(.+)/.exec(cn); + if (matches) { + lang = matches[1]; + } + } + + if (!lang) return; + + let code; + if (node.children?.length) { + code = node.children[0].data; + } + + const repl = { + start: 0, + end: 0, + type: 'InlineComponent', + name: 'Prism', + attributes: [ + { + type: 'Attribute', + name: 'lang', + value: [ + { + type: 'Text', + raw: lang, + data: lang, + }, + ], + }, + { + type: 'Attribute', + name: 'code', + value: [ + { + type: 'MustacheTag', + content: '`' + escape(code) + '`', + }, + ], + }, + ], + children: [], + }; + + this.replace(repl); + usesPrism = true; + }, + }, + }, + }, + async finalize() { + // Add the Prism import if needed. + if (usesPrism && !prismImportExp.test(module.content)) { + module.content = PRISM_IMPORT + module.content; + } + }, + }; +} diff --git a/src/runtime.ts b/src/runtime.ts index 800c4d40a..f524a2bf5 100644 --- a/src/runtime.ts +++ b/src/runtime.ts @@ -164,7 +164,7 @@ async function createSnowpack(astroConfig: AstroConfig, env: Record }, packageOptions: { knownEntrypoints: ['preact-render-to-string'], - external: ['@vue/server-renderer', 'node-fetch'], + external: ['@vue/server-renderer', 'node-fetch', 'prismjs/components/'], }, }); diff --git a/www/astro/pages/blog.md b/www/astro/pages/blog.md index 3d6a3e23a..33502f29f 100644 --- a/www/astro/pages/blog.md +++ b/www/astro/pages/blog.md @@ -1,8 +1,6 @@ --- layout: ../layouts/index.astro title: Astro -import: - Prism: astro/components/Prism.astro --- ## Links