upstream #1
| @@ -1,4 +1,5 @@ | ||||
| import { MDXRemote } from 'next-mdx-remote' | ||||
| import { useMemo } from 'react' | ||||
| import { getMDXComponent } from 'mdx-bundler/client' | ||||
| import Image from './Image' | ||||
| import CustomLink from './Link' | ||||
| import Pre from './Pre' | ||||
| @@ -10,11 +11,12 @@ export const MDXComponents = { | ||||
| } | ||||
|  | ||||
| export const MDXLayoutRenderer = ({ layout, mdxSource, ...rest }) => { | ||||
|   const MDXComponent = useMemo(() => getMDXComponent(mdxSource), [mdxSource]) | ||||
|   const LayoutComponent = require(`../layouts/${layout}`).default | ||||
|  | ||||
|   return ( | ||||
|     <LayoutComponent {...rest}> | ||||
|       <MDXRemote {...mdxSource} components={MDXComponents} /> | ||||
|       <MDXComponent components={MDXComponents} /> | ||||
|     </LayoutComponent> | ||||
|   ) | ||||
| } | ||||
|   | ||||
| @@ -140,6 +140,7 @@ function fancyAlert(arg) { | ||||
|     $.facebox({ div: '#foo' }) | ||||
|   } | ||||
| } | ||||
| ``` | ||||
| ```` | ||||
|  | ||||
| And here's how it looks - nicely colored with styled code titles! | ||||
|   | ||||
| @@ -50,11 +50,11 @@ _Note_: If you try to save the image, it is in webp format, if your browser supp | ||||
|  | ||||
|  | ||||
| <p> | ||||
|   Photo by{' '} | ||||
|   Photo by | ||||
|   <a href="https://unsplash.com/@yucar?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"> | ||||
|     YUCAR FotoGrafik | ||||
|   </a>{' '} | ||||
|   on{' '} | ||||
|   </a> | ||||
|   on | ||||
|   <a href="https://unsplash.com/s/photos/sea?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"> | ||||
|     Unsplash | ||||
|   </a> | ||||
|   | ||||
| @@ -59,41 +59,41 @@ When MDX v2 is ready, one could potentially interleave markdown in jsx directly! | ||||
| ### Photo Credits | ||||
|  | ||||
| <div> | ||||
|   Maple photo by{' '} | ||||
|   Maple photo by | ||||
|   <a href="https://unsplash.com/@i_am_g?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"> | ||||
|     Guillaume Jaillet | ||||
|   </a>{' '} | ||||
|   on{' '} | ||||
|   </a> | ||||
|   on | ||||
|   <a href="https://unsplash.com/s/photos/canada?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"> | ||||
|     Unsplash | ||||
|   </a> | ||||
| </div> | ||||
| <div> | ||||
|   Mountains photo by{' '} | ||||
|   Mountains photo by | ||||
|   <a href="https://unsplash.com/@john_artifexfilms?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"> | ||||
|     John Lee | ||||
|   </a>{' '} | ||||
|   on{' '} | ||||
|   </a> | ||||
|   on | ||||
|   <a href="https://unsplash.com/s/photos/canada?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"> | ||||
|     Unsplash | ||||
|   </a> | ||||
| </div> | ||||
| <div> | ||||
|   Lake photo by{' '} | ||||
|   Lake photo by | ||||
|   <a href="https://unsplash.com/@tjholowaychuk?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"> | ||||
|     Tj Holowaychuk | ||||
|   </a>{' '} | ||||
|   on{' '} | ||||
|   </a> | ||||
|   on | ||||
|   <a href="https://unsplash.com/s/photos/canada?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"> | ||||
|     Unsplash | ||||
|   </a> | ||||
| </div> | ||||
| <div> | ||||
|   Toronto photo by{' '} | ||||
|   Toronto photo by | ||||
|   <a href="https://unsplash.com/@matthewhenry?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"> | ||||
|     Matthew Henry | ||||
|   </a>{' '} | ||||
|   on{' '} | ||||
|   </a> | ||||
|   on | ||||
|   <a href="https://unsplash.com/s/photos/canada?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText"> | ||||
|     Unsplash | ||||
|   </a> | ||||
|   | ||||
| @@ -15,13 +15,14 @@ module.exports = (options) => (tree) => { | ||||
|         const dimensions = sizeOf(`${process.cwd()}/public${imageNode.url}`) | ||||
|  | ||||
|         // Convert original node to next/image | ||||
|         imageNode.type = 'jsx' | ||||
|         imageNode.value = `<Image | ||||
|           alt={\`${imageNode.alt}\`}  | ||||
|           src={\`${imageNode.url}\`} | ||||
|           width={${dimensions.width}} | ||||
|           height={${dimensions.height}} | ||||
|       />` | ||||
|         ;(imageNode.type = 'mdxJsxFlowElement'), | ||||
|           (imageNode.name = 'Image'), | ||||
|           (imageNode.attributes = [ | ||||
|             { type: 'mdxJsxAttribute', name: 'alt', value: imageNode.alt }, | ||||
|             { type: 'mdxJsxAttribute', name: 'src', value: imageNode.url }, | ||||
|             { type: 'mdxJsxAttribute', name: 'width', value: dimensions.width }, | ||||
|             { type: 'mdxJsxAttribute', name: 'height', value: dimensions.height }, | ||||
|           ]) | ||||
|  | ||||
|         // Change node type from p to div to avoid nesting error | ||||
|         node.type = 'div' | ||||
|   | ||||
							
								
								
									
										46
									
								
								lib/mdx.js
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								lib/mdx.js
									
									
									
									
									
								
							| @@ -1,7 +1,6 @@ | ||||
| import { MDXComponents } from '@/components/MDXComponents' | ||||
| import { bundleMDX } from 'mdx-bundler' | ||||
| import fs from 'fs' | ||||
| import matter from 'gray-matter' | ||||
| import { serialize } from 'next-mdx-remote/serialize' | ||||
| import path from 'path' | ||||
| import readingTime from 'reading-time' | ||||
| import visit from 'unist-util-visit' | ||||
| @@ -49,18 +48,42 @@ export async function getFileBySlug(type, slug) { | ||||
|     : fs.readFileSync(mdPath, 'utf8') | ||||
|  | ||||
|   const { data, content } = matter(source) | ||||
|   const mdxSource = await serialize(content, { | ||||
|     components: MDXComponents, | ||||
|     mdxOptions: { | ||||
|       remarkPlugins: [ | ||||
|  | ||||
|   // https://github.com/kentcdodds/mdx-bundler#nextjs-esbuild-enoent | ||||
|   if (process.platform === 'win32') { | ||||
|     process.env.ESBUILD_BINARY_PATH = path.join( | ||||
|       process.cwd(), | ||||
|       'node_modules', | ||||
|       'esbuild', | ||||
|       'esbuild.exe' | ||||
|     ) | ||||
|   } else { | ||||
|     process.env.ESBUILD_BINARY_PATH = path.join( | ||||
|       process.cwd(), | ||||
|       'node_modules', | ||||
|       'esbuild', | ||||
|       'bin', | ||||
|       'esbuild' | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   const { code } = await bundleMDX(source, { | ||||
|     xdmOptions(options) { | ||||
|       // this is the recommended way to add custom remark/rehype plugins: | ||||
|       // The syntax might look weird, but it protects you in case we add/remove | ||||
|       // plugins in the future. | ||||
|       options.remarkPlugins = [ | ||||
|         ...(options.remarkPlugins ?? []), | ||||
|         require('remark-slug'), | ||||
|         require('remark-autolink-headings'), | ||||
|         require('remark-gfm'), | ||||
|         require('remark-code-titles'), | ||||
|         [require('remark-footnotes'), { inlineNotes: true }], | ||||
|         require('remark-math'), | ||||
|         imgToJsx, | ||||
|       ], | ||||
|       inlineNotes: true, | ||||
|       rehypePlugins: [ | ||||
|       ] | ||||
|       options.rehypePlugins = [ | ||||
|         ...(options.rehypePlugins ?? []), | ||||
|         require('rehype-katex'), | ||||
|         require('@mapbox/rehype-prism'), | ||||
|         () => { | ||||
| @@ -73,12 +96,13 @@ export async function getFileBySlug(type, slug) { | ||||
|             }) | ||||
|           } | ||||
|         }, | ||||
|       ], | ||||
|       ] | ||||
|       return options | ||||
|     }, | ||||
|   }) | ||||
|  | ||||
|   return { | ||||
|     mdxSource, | ||||
|     mdxSource: code, | ||||
|     frontMatter: { | ||||
|       readingTime: readingTime(content), | ||||
|       slug: slug || null, | ||||
|   | ||||
							
								
								
									
										32
									
								
								lib/remark-code-title.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								lib/remark-code-title.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| import visit from 'unist-util-visit' | ||||
|  | ||||
| module.exports = function (options) { | ||||
|   return (tree) => | ||||
|     visit(tree, 'code', (node, index) => { | ||||
|       const nodeLang = node.lang || '' | ||||
|       let language = '', | ||||
|         title = '' | ||||
|  | ||||
|       if (nodeLang.includes(':')) { | ||||
|         language = nodeLang.slice(0, nodeLang.search(':')) | ||||
|         title = nodeLang.slice(nodeLang.search(':') + 1, nodeLang.length) | ||||
|       } | ||||
|  | ||||
|       if (!title) { | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       const className = 'remark-code-title' | ||||
|  | ||||
|       const titleNode = { | ||||
|         type: 'mdxJsxFlowElement', | ||||
|         name: 'div', | ||||
|         attributes: [{ type: 'mdxJsxAttribute', name: 'className', value: className }], | ||||
|         children: [{ type: 'text', value: title }], | ||||
|         data: { _xdmExplicitJsx: true }, | ||||
|       } | ||||
|  | ||||
|       tree.children.splice(index, 0, titleNode) | ||||
|       node.lang = language | ||||
|     }) | ||||
| } | ||||
							
								
								
									
										1841
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1841
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -18,19 +18,20 @@ | ||||
|     "autoprefixer": "^10.2.5", | ||||
|     "gray-matter": "^4.0.2", | ||||
|     "image-size": "1.0.0", | ||||
|     "mdx-bundler": "^4.1.0", | ||||
|     "next": "11.0.1", | ||||
|     "next-mdx-remote": "^3.0.1", | ||||
|     "next-themes": "^0.0.14", | ||||
|     "postcss": "^8.3.5", | ||||
|     "preact": "^10.5.13", | ||||
|     "react": "17.0.2", | ||||
|     "react-dom": "17.0.2", | ||||
|     "reading-time": "1.3.0", | ||||
|     "rehype-katex": "^4.0.0", | ||||
|     "rehype-katex": "^5.0.0", | ||||
|     "remark-autolink-headings": "6.0.1", | ||||
|     "remark-code-titles": "0.1.2", | ||||
|     "remark-footnotes": "^3.0.0", | ||||
|     "remark-math": "^3.0.1", | ||||
|     "remark-gfm": "^1.0.0", | ||||
|     "remark-math": "^4.0.0", | ||||
|     "remark-slug": "6.0.0", | ||||
|     "tailwindcss": "^2.2.2" | ||||
|   }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user