nextjs+MDX渲染md文件并生成目录
nextjs+MDX渲染md文件并生成目录
一、效果展示
线上网站:点击体验
md文件
网页
二、需要使用的模块包
包名 | 作用 |
---|---|
@mdx-js/react | 用来渲染react组件 |
@next-mdx-remote | 将字符串转换成html标签 |
@remark-slug | 为html标签添加id(锚点跳转) |
@mapbox/rehype-prism | 添加代码高亮 |
@jsdevtools/rehype-toc | 生成目录 |
@remark-gfm | 渲染表格插件 |
三、使用方法
项目目录结构
1
1.在_app.js中导入mdx-js/react
import { MDXProvider } from '@mdx-js/react';
function MyApp({ Component, pageProps }) {// 定义 mdx 中语法的映射组件const components = {// img: props => <Image {...props}></Image>,h1: props => {return <h1><div id={props.id} className='relative -top-24 invisible' ></div><a href={'#' + props.id}>{props.children}</a></h1>},h2: props => {return <h2><div id={props.id} className='relative -top-24 invisible' ></div><a href={'#' + props.id}>{props.children}</a></h2>},h3: props => {return <h3><div id={props.id} className='relative -top-24 invisible' ></div><a href={'#' + props.id}>{props.children}</a></h3>},h4: props => {return <h4><div id={props.id} className='relative -top-24 invisible' ></div><a href={'#' + props.id}>{props.children}</a></h4>},wrapper: ({ children, ...props }) => {// console.log(children.map(child => child.props.mdxType))// console.log(React.Children.toArray(children), 999)// console.log(children)// console.log(props, 111)// if (props.layout) {// return <main {...props} />// }return <>{children}</>}}return <MDXProvider components={components}><Component {...pageProps}/></MDXProvider>
}export default MyApp
2.在blog/[name].js中
2.1通过getStaticProps在服务器使用fs模块运行读取content文件目录下的md文件内容
2.2配置MDX各种插件
2.3在通过MDXRemote将文件内容渲染出来
2.4通过插件获取到元数据和目录
2.5在组件prop中获取到内容
2.6通过自定义组件TableContents生成自己的目录
import { serialize } from 'next-mdx-remote/serialize'
import { MDXRemote } from 'next-mdx-remote'
import Layout from "../../components/Layout";
import slug from 'remark-slug'
import remarkGfm from 'remark-gfm'
import rehypePrism from '@mapbox/rehype-prism'
import TableContents from '../../components/TableContents';
import React from 'react';// import { useInView } from 'react-intersection-observer';
export default function BlogPage(props) {const [id, setId] = React.useState(array[0])return (<div className="wrapper"><Layout href='/blog' full={true} theme={props.theme} setTheme={props.setTheme}>{/* <div>{props.source.frontmatter.title}</div> */}<div className='grid grid-cols-4 gap-6 relative'><div className='markdown xl:col-span-3 col-span-5 p-5 rounded-lg dark:bg-[#222222] box-shadow bg-white'><MDXRemote {...props.source} /></div><div className='xl:block hidden'><div className='sticky top-24 p-5 rounded-lg dark:bg-[#222222] box-shadow bg-white'><h3 className="text-xl text-gray-900 dark:text-gray-100 dark:opacity-90 font-bold pb-4">目录</h3><TableContents idTable={id} {...props.tocElement}></TableContents></div></div></div></Layout></div>)
}export async function getStaticProps(context) {// MDX text - can be from a local file, database, anywhereconst fs = require('fs')const path = require('path')const toc = require("@jsdevtools/rehype-toc");let tocElementconst { name } = context.paramslet source = String(fs.readFileSync(path.join(process.cwd(), 'src', 'content', name + '.md')))const mdxSource = await serialize(source, {scope: {},mdxOptions: {remarkPlugins: [slug, remarkGfm],rehypePlugins: [rehypePrism, [toc, {headings: ['h1', 'h2', 'h3', 'h4'],customizeTOC: (tocAll) => {tocElement = tocAllreturn false}}]],format: 'mdx'},parseFrontmatter: true})return { props: { source: mdxSource, tocElement: tocElement } }
}
export async function getStaticPaths() {return {paths: [],fallback: 'blocking'}
}
TableContents组件
//拼接字符串工具
import clsx from 'clsx'
import React from 'react'export default function TableContents(props) {switch (props.tagName) {case 'nav': {return (<nav {...props.properties}>{props.children.map((item, index) => {return <TableContents {...item} key={index} idTable={props.idTable} />})}</nav>)};case 'ol': {return (<ol {...props.properties}>{props.children.map((item, index) => {return <TableContents {...item} key={index} idTable={props.idTable} />})}</ol>)};case 'li': {return (<li {...props.properties}>{props.children.map((item, index) => {return <TableContents {...item} key={index} idTable={props.idTable} />})}</li>)};case 'a': {return (<a {...props.properties} className={clsx('block py-1 text-sm font-medium hover:text-[#428dcc] focus:outline-none dark:hover:text-gray-200 focus-visible:text-gray-700 dark:opacity-90 dark:focus-visible:text-gray-200 text-gray-400', props.properties.href == '#' + props.idTable && 'text-[#428dcc] dark:text-gray-200')}>{props.children.map((item, index) => {return <TableContents {...item} key={index} />})}</a>)};default: return (<>{props.value}</>)}
}
3.引入CSS样式
在_app.js中
markdown样式可自行设计
prism官网代码高亮样式点击链接下载
import '../styles/prism.css'
import '../styles/markdown.css'
4.项目源码链接github
nextjs+MDX渲染md文件并生成目录相关推荐
- md文件自动生成目录[docsify]
1.下载该工具,配置文件路径,双击程序运行即可 下载地址 ----- Docsify:自动生成sidebar与子目录sidebar_Sidebar-互联网文档类资源-CSDN下载 2.运行结果 3. ...
- VuePress 开发技术文档网站,管理.md文件,生成静态网站
目录 最终效果 开发流程 1. 新建文件夹 mydocs 2. 初始化项目 3. 安装 VuePress 4. 添加项目脚本 5. 添加 .md文件 6. 添加项目配置 7. 运行项目 参考资料 最 ...
- 文件夹文件自动生成目录的方法-保存到txt
文件夹文件自动生成目录的方法-保存到txt 1.打开记事本: 2.复制以下内容: @echo off dir /b /on >list.txt 3.另存为bat,类型ANSI
- .md文件自动生成项目目录结构
自动生成项目目录结构 1)安装mddir (-g是全局安装,可以选择不全局安装,这里因为以后都要使用所以选择的全局安装) npm install mddir -g 2)cd 到你想生成目录的工程结构, ...
- md 文件使用html阅读,使用markdow-it渲染md文件为html页面
前言:最近在写一些新闻资讯详情的页面,header组件.footer组件.目录组件都是固定的,只有新闻的内容是变化的.为了不去写重复的代码(有句话怎么说来着:战略上偷懒,战术上勤奋,就是这个意思),准 ...
- html 渲染md文件,markdown的学习和.md文件使用
Markdown Table of Contents 标准 Markdown 标题 # H1 ## H2 ### H3 #### H4 ##### H5 ###### H6 另外, 对于 H1 和 H ...
- vue渲染.md文件
1. 在package.json文件安装以下依赖,npm install "dependencies": {"github-markdown-css": &qu ...
- pdf文件如何生成目录 wps_wps制作pdf文档的详细方法
一些用户在使用wps软件的时候,wps怎样制作pdf文档?你们知道怎么操作的吗?对此感兴趣的伙伴们可以去下文看看wps制作pdf文档的详细方法. wps制作pdf文档的详细方法 一.打开或生成原始文件 ...
- md文件语法及目录使用
标题的使用 # ==<h1> ## <h2> ................ 空格的使用 换行的使用 ①段落换行 回车 ②普通换行 space +space+回车 ...
最新文章
- Android 应用进行性能分析/APP/系统性能分析
- 关于 TApplication 详解 三 ---- TComponent
- 在leangoo里怎么复制列表,删除列表,插入列表?
- 【Xmind】,让你的大脑解放出来
- mac 黑窗口连接mysql_Mac系统Python、PyCharm安装及使用方法详解
- Redis Sentinel 配置文件
- linux设置python3为默认python_Ubuntu 18.04将Python3设置为Python默认版本
- Jest + React Testing Library 单测总结
- 后台系统可扩展性学习笔记(十四)异步机制与MQ
- 【温故而知新-Javascript】使用canvas元素(第一部分)
- 【Python】AttributeError: 'Series' object has no attribute 'order'
- 光伏并网发电及低电压穿越技术
- 2012浙江大学光华法学院毕业典礼教师发言
- 谢晶:webpower中国区正在向“多渠道智能化营销”全面转型
- 企业云盘的作用不仅只是存储
- 拼多多店铺营业执照相关问题
- 从删库到跑路再到权限管理
- java.lang.NoClassDefFoundError: org/jdom2/JDOMException
- 数仓工具—Hive源码之SQL解析Antlr入门(7)
- 详解Ubuntu的网络配置