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",