diff --git a/css/tailwind.css b/css/tailwind.css index b7d9ce9..64246d0 100644 --- a/css/tailwind.css +++ b/css/tailwind.css @@ -14,6 +14,19 @@ @apply hidden; } +.code-line { + @apply pl-4 -mx-4 border-l-4 border-gray-800; +} + +.highlight-line { + @apply -mx-4 bg-gray-700 bg-opacity-50 border-l-4 border-primary-500; +} + +.line-number::before { + @apply pr-4 -ml-2 text-gray-400; + content: attr(line); +} + html { scroll-behavior: smooth; } diff --git a/data/blog/new-features-in-v1.mdx b/data/blog/new-features-in-v1.mdx index fb48d70..2e43d0b 100644 --- a/data/blog/new-features-in-v1.mdx +++ b/data/blog/new-features-in-v1.mdx @@ -1,6 +1,6 @@ --- title: 'New features in v1' -date: '2021-06-02' +date: '2021-06-29' tags: ['next-js', 'tailwind', 'guide'] draft: false summary: 'An overview of the new features released in v1 - code block copy, multiple authors, frontmatter layout and more' @@ -12,15 +12,17 @@ layout: PostSimple A post on the new features introduced in v1.0. New features: - [Theme colors](#theme-colors) +- [Xdm MDX compiler](#xdm-mdx-compiler) - [Layouts](#layouts) - [Multiple authors](#multiple-authors) - [Copy button for code blocks](#copy-button-for-code-blocks) +- [Line highlighting and line numbers](#line-highlighting-and-line-numbers) ## Theme colors You can easily modify the theme color by changing the primary attribute in the tailwind config file: -```:tailwind.config.js +```js:tailwind.config.js theme: { colors: { primary: colors.teal, @@ -37,6 +39,18 @@ Tailwind includes great default color palettes that can be used for theming your Migrating from v1? You can revert to the previous theme by setting `primary` to `colors.sky` (Tailwind 2.2.2 and above, otherwise `colors.lightBlue`) and changing gray to `colors.coolGray`. +## Xdm MDX compiler + +We switch the MDX bundler from [next-mdx-remote](https://github.com/hashicorp/next-mdx-remote) to [mdx-bundler](https://github.com/kentcdodds/mdx-bundler). +This uses [xdm](https://github.com/wooorm/xdm) under the hood uses the latest micromark 3 and remark, rehype libraries. + +**Warning:** If you were using custom remark or rehype libraries, please upgrade to micromark 3 compatible ones. If you are upgrading, please delete `node_modules` and `package-lock.json` to avoid having past dependencies related issues. + +[xdm](https://github.com/wooorm/xdm) contains multiple improvements over [@mdx-js/mdx](https://github.com/mdx-js/mdx), the compiler used internally by next-mdx-remote, but there might be some breaking behaviour changes. +Please check your markdown output to verify. + +Some new possibilities include loading components directly in the mdx file using the import syntax and including js code which could be compiled at the build step. + ## Layouts You can map mdx blog content to layout components by configuring the frontmatter field. For example, this post is written with the new `PostSimple` layout! @@ -110,7 +124,7 @@ Information on authors is now split from `siteMetadata.json` and stored in its o Here's how an author markdown file might looks like: -```:default.md +```md:default.md --- name: Tails Azimuth avatar: /static/images/avatar.png @@ -153,3 +167,46 @@ A demo of a multiple author post is shown in the [Introducing Tailwind Nextjs St Hover over a code block and you will notice a Github inspired copy button! You can modify `./components/Pre.js` to further customise it. The component is passed to `MDXComponents` and modifies all `
` blocks. + +## Line highlighting and line numbers + +Line highlighting and line numbers is now supported out of the box thanks to the new [rehype-prism-plus plugin](https://github.com/timlrx/rehype-prism-plus) + +The following javascript code block: + +```` +```js {1, 3-4} showLineNumbers +var num1, num2, sum +num1 = prompt('Enter first number') +num2 = prompt('Enter second number') +sum = parseInt(num1) + parseInt(num2) // "+" means "add" +alert('Sum = ' + sum) // "+" means combine into a string +``` +```` + +will appear as: + +```js {1,3-4} showLineNumbers +var num1, num2, sum +num1 = prompt('Enter first number') +num2 = prompt('Enter second number') +sum = parseInt(num1) + parseInt(num2) // "+" means "add" +alert('Sum = ' + sum) // "+" means combine into a string +``` + +To modify the styles, change the following class selectors in the `tailwind.css` file: + +```css +.code-line { + @apply pl-4 -mx-4 border-l-4 border-gray-800; +} + +.highlight-line { + @apply -mx-4 bg-gray-700 bg-opacity-50 border-l-4 border-primary-500; +} + +.line-number::before { + @apply pr-4 -ml-2 text-gray-400; + content: attr(line); +} +``` diff --git a/lib/mdx.js b/lib/mdx.js index 3df137c..bf8f4dc 100644 --- a/lib/mdx.js +++ b/lib/mdx.js @@ -86,7 +86,7 @@ export async function getFileBySlug(type, slug) { options.rehypePlugins = [ ...(options.rehypePlugins ?? []), require('rehype-katex'), - require('@mapbox/rehype-prism'), + [require('rehype-prism-plus'), { ignoreMissing: true }], () => { return (tree) => { visit(tree, 'element', (node, index, parent) => { diff --git a/lib/remark-code-title.js b/lib/remark-code-title.js index ed7d785..0c7e9ef 100644 --- a/lib/remark-code-title.js +++ b/lib/remark-code-title.js @@ -4,8 +4,8 @@ module.exports = function (options) { return (tree) => visit(tree, 'code', (node, index) => { const nodeLang = node.lang || '' - let language = '', - title = '' + let language = '' + let title = '' if (nodeLang.includes(':')) { language = nodeLang.slice(0, nodeLang.search(':')) diff --git a/package-lock.json b/package-lock.json index 24d80e9..3d66991 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1545,16 +1545,6 @@ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==" }, - "@mapbox/rehype-prism": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@mapbox/rehype-prism/-/rehype-prism-0.6.0.tgz", - "integrity": "sha512-/0Ev/PB4fXdKPT6VDzVpnAPxGpWFIc4Yz3mf/DzLEMxlpIPZpZlCzaFk4V4NGFofQXPc41+GpEcZtWP3VuFWVA==", - "requires": { - "hast-util-to-string": "^1.0.4", - "refractor": "^3.3.1", - "unist-util-visit": "^2.0.3" - } - }, "@next/bundle-analyzer": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-11.0.1.tgz", @@ -1931,6 +1921,11 @@ "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" }, + "@types/prismjs": { + "version": "1.16.5", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.16.5.tgz", + "integrity": "sha512-nSU7U6FQDJJCraFNwaHmH5YDsd/VA9rTnJ7B7AGFdn+m+VSt3FjLWN7+AbqxZ67dbFazqtrDFUto3HK4ljrHIg==" + }, "@types/q": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", @@ -2791,17 +2786,6 @@ } } }, - "clipboard": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz", - "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==", - "optional": true, - "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" - } - }, "coa": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", @@ -3201,12 +3185,6 @@ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", - "optional": true - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -4495,15 +4473,6 @@ } } }, - "good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "optional": true, - "requires": { - "delegate": "^3.1.2" - } - }, "graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", @@ -6730,6 +6699,11 @@ "lines-and-columns": "^1.1.6" } }, + "parse-numeric-range": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.2.0.tgz", + "integrity": "sha512-1q2tXpAOplPxcl8vrIGPWz1dJxxfmdRkCFcpxxMBerDnGuuHalOWF/xj9L8Nn5XoTUoB/6F0CeQBp2fMgkOYFg==" + }, "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -6982,14 +6956,6 @@ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" }, - "prismjs": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz", - "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==", - "requires": { - "clipboard": "^2.0.0" - } - }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -7312,16 +7278,6 @@ } } }, - "refractor": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.3.1.tgz", - "integrity": "sha512-vaN6R56kLMuBszHSWlwTpcZ8KTMG6aUCok4GrxYDT20UIOXxOc5o6oDc8tNTzSlH3m2sI+Eu9Jo2kVdDcUTWYw==", - "requires": { - "hastscript": "^6.0.0", - "parse-entities": "^2.0.0", - "prismjs": "~1.23.0" - } - }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -7437,6 +7393,147 @@ "parse5": "^6.0.0" } }, + "rehype-prism-plus": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/rehype-prism-plus/-/rehype-prism-plus-0.0.1.tgz", + "integrity": "sha512-tq9PtqEVEATTNDIV22b/3foSqM0nGS5akAImavIwGKnswFrBoFjTHowOwIvermb1B4tx1hjDtD0i2HOHITUg3g==", + "requires": { + "hast-util-to-string": "^1.0.4", + "parse-numeric-range": "^1.2.0", + "refractor": "^4.0.0", + "unist-util-visit": "^3.1.0" + }, + "dependencies": { + "character-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.0.tgz", + "integrity": "sha512-oHqMj3eAuJ77/P5PaIRcqk+C3hdfNwyCD2DAUcD5gyXkegAuF2USC40CEqPscDk4I8FRGMTojGJQkXDsN5QlJA==" + }, + "character-entities-legacy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-2.0.0.tgz", + "integrity": "sha512-YwaEtEvWLpFa6Wh3uVLrvirA/ahr9fki/NUd/Bd4OR6EdJ8D22hovYQEOUCBfQfcqnC4IAMGMsHXY1eXgL4ZZA==" + }, + "character-reference-invalid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.0.tgz", + "integrity": "sha512-pE3Z15lLRxDzWJy7bBHBopRwfI20sbrMVLQTC7xsPglCHf4Wv1e167OgYAFP78co2XlhojDyAqA+IAJse27//g==" + }, + "comma-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", + "integrity": "sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==" + }, + "hast-util-parse-selector": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.0.tgz", + "integrity": "sha512-AyjlI2pTAZEOeu7GeBPZhROx0RHBnydkQIXlhnFzDi0qfXTmGUWoCYZtomHbrdrheV4VFUlPcfJ6LMF5T6sQzg==", + "requires": { + "@types/hast": "^2.0.0" + } + }, + "hastscript": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.0.1.tgz", + "integrity": "sha512-3Nww02NdnAoLZlI4mifLRYU9jZ1PrMD+eYnnW3RGVKlRD2bW+fNTvr1KLnET/DAf8c6CMlMblXVUhXJiGIKwDA==", + "requires": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + } + }, + "is-alphabetical": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.0.tgz", + "integrity": "sha512-5OV8Toyq3oh4eq6sbWTYzlGdnMT/DPI5I0zxUBxjiigQsZycpkKF3kskkao3JyYGuYDHvhgJF+DrjMQp9SX86w==" + }, + "is-alphanumerical": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.0.tgz", + "integrity": "sha512-t+2GlJ+hO9yagJ+jU3+HSh80VKvz/3cG2cxbGGm4S0hjKuhWQXgPVUVOZz3tqZzMjhmphZ+1TIJTlRZRoe6GCQ==", + "requires": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + } + }, + "is-decimal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.0.tgz", + "integrity": "sha512-QfrfjQV0LjoWQ1K1XSoEZkTAzSa14RKVMa5zg3SdAfzEmQzRM4+tbSFWb78creCeA9rNBzaZal92opi1TwPWZw==" + }, + "is-hexadecimal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.0.tgz", + "integrity": "sha512-vGOtYkiaxwIiR0+Ng/zNId+ZZehGfINwTzdrDqc6iubbnQWhnPuYymOzOKUDqa2cSl59yHnEh2h6MvRLQsyNug==" + }, + "parse-entities": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-3.0.0.tgz", + "integrity": "sha512-AJlcIFDNPEP33KyJLguv0xJc83BNvjxwpuUIcetyXUsLpVXAUCePJ5kIoYtEN2R1ac0cYaRu/vk9dVFkewHQhQ==", + "requires": { + "character-entities": "^2.0.0", + "character-entities-legacy": "^2.0.0", + "character-reference-invalid": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + } + }, + "prismjs": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.24.0.tgz", + "integrity": "sha512-SqV5GRsNqnzCL8k5dfAjCNhUrF3pR0A9lTDSCUZeh/LIshheXJEaP0hwLz2t4XHivd2J/v2HR+gRnigzeKe3cQ==" + }, + "property-information": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.0.1.tgz", + "integrity": "sha512-F4WUUAF7fMeF4/JUFHNBWDaKDXi2jbvqBW/y6o5wsf3j19wTZ7S60TmtB5HoBhtgw7NKQRMWuz5vk2PR0CygUg==" + }, + "refractor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-4.1.0.tgz", + "integrity": "sha512-qUcwf/qkP3sH7RrhgEPt5d4/5M7lK9nCH8UkYXNsmXMDUd7JqGg91IQVEUS9maJqqiF4Bo02P5ozWSXOQb7jow==", + "requires": { + "@types/hast": "^2.0.0", + "@types/prismjs": "^1.0.0", + "hastscript": "^7.0.0", + "parse-entities": "^3.0.0", + "prismjs": "~1.24.0" + } + }, + "space-separated-tokens": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz", + "integrity": "sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==" + }, + "unist-util-is": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.0.tgz", + "integrity": "sha512-pWspZ+AvTqYbC+xWeRmzGqbcY8Na08Eowlfs2xchWTYot8vBBAq+syrE/LWS0bw1D/JOu4lwzDbEb6Mz13tK+g==" + }, + "unist-util-visit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", + "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^4.0.0" + } + }, + "unist-util-visit-parents": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", + "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + } + } + }, "rehype-stringify": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-8.0.0.tgz", @@ -7679,12 +7776,6 @@ "kind-of": "^6.0.0" } }, - "select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", - "optional": true - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -8400,12 +8491,6 @@ "setimmediate": "^1.0.4" } }, - "tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "optional": true - }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", diff --git a/package.json b/package.json index 29135a9..f288adc 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "prepare": "husky install" }, "dependencies": { - "@mapbox/rehype-prism": "^0.6.0", "@tailwindcss/forms": "^0.3.2", "@tailwindcss/typography": "^0.4.0", "autoprefixer": "^10.2.5", @@ -27,6 +26,7 @@ "react-dom": "17.0.2", "reading-time": "1.3.0", "rehype-katex": "^5.0.0", + "rehype-prism-plus": "0.0.1", "remark-autolink-headings": "6.0.1", "remark-footnotes": "^3.0.0", "remark-gfm": "^1.0.0",