稀土掘金 稀土掘金

Markdown的前端渲染

这里是终于还有一个页面就要写完项目的丹星,这篇也是讲述掘金网页项目中用到的比较重要的一个技术——markdown的前端渲染。

提起markdown很多人会想到Typora,这也是我常用的markdown编辑器,下面是Typora的界面。 其实Typora是将markdown语法编译成为了HTML,然后展现了出来,比如单个#号编译为了H1标签。

掘金和CSDN这类网页也提供了markdown写作的功能。那么前端如何做一个markdown的富文本编辑器并且呈现实时预览呢?

一套简单的技术栈是:marked.js实现markdown文本转HTML,highlight.js对代码进行高亮。

但是如果你是一名React选手,那么你可以使用:

  • 富文本编辑以及预览:md-editor-rt
  • markdown文本解析:react-markdown
  • 使markdown支持HTML语法:rehype-raw
  • 划线、表、任务列表和直接url等的语法扩展:remark-gfm
  • 代码高亮:react-syntax-highlighter
  • 目录提取与跳转:markdown-navbar

没错,我就是组件小子

下面来体验一下React的强大生态。

md-editor-rt富文本编辑器

下载

yarn add md-editor-rt

在React Hooks中,只需要非常简单的引入,使用useState配合Editor的两个API,就可以实现输入markdown并且实时渲染。

import React, { useState } from 'react';
// 导入组件
import Editor from 'md-editor-rt';
// 引入样式
import 'md-editor-rt/lib/style.css';  

export default function Md() {
  const [text, setText] = useState('hello md-editor-rt!');
  return <Editor modelValue={text} onChange={setText} />;
}

并且md-editor-rt自带了Toolbar,也就是编辑框上方的辅助栏,可以帮助用户更好的编辑。

React-markdown的渲染

上面说的是markdown编辑器以及渲染,如果后端传来了一个markdown文本,我们需要把它渲染到网页上,就像我们点进CSDN和掘金看文章,这时候需要对markdown做一个渲染,就可以用到react-markdown。 下载

yarn add react-markdown

只需要把markdown的文本放到ReactMarkdown双标签的组件就可以啦

import ReactMarkdown from "react-markdown";
<ReactMarkdown># Hello, *World*!</ReactMarkdown>

上方的Hello World!被解析为了一个h1标签。如果是单标签的话,我们可以把markdown的文本传入children参数中。

import ReactMarkdown from "react-markdown";
<ReactMarkdown children={markdownText} />

引入插件支持

react-markdown并不支持所有的Markdown语法,但是我们可以使用插件来添加对这些语法的支持。

  • remake-plugin增加了对脚注、划线、表、任务列表、自动链接文字或直接url的支持
  • rehype-raw增加了对HTML原生语法的支持
import gfm from "remark-gfm";
import rehypeRaw from 'rehype-raw'; 
import gfm from 'remark-gfm';
<ReactMarkdown
  children={text}
  rehypePlugins={[rehypeRaw]}
  remarkPlugins={[gfm]}
/>

react-syntax-highlighter

markdown中代码会转为code标签,但是HTML中对code其实没有很好的样式支持,所以我们需要额外的组件进行代码高亮。

我们可以定义一个组件(component),加入到react-markdown中。

import gfm from "remark-gfm";
import rehypeRaw from 'rehype-raw'; 
import gfm from 'remark-gfm';
<ReactMarkdown
  children={text}
  rehypePlugins={[rehypeRaw]}
  remarkPlugins={[gfm]}
  components={CodeBlock}
/>

其中CodeBlock是我们定义的插件。

首先,我们导入react-syntax-highlighter和一个代码主题,这里是atomDark,你也可以选择别的主题。

import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { atomDark } from 'react-syntax-highlighter/dist/esm/styles/prism';

const CodeBlock = {
  code({ node, inline, className, children, ...props }) {
    const match = /language-(\w+)/.exec(className || '');
    return !inline && match ? (
      <SyntaxHighlighter
        children={String(children).replace(/\n$/, '')}
        style={atomDark} // theme
        language={match[1].toLowerCase()}
        PreTag="section" // parent tag
        {...props}
      />
    ) : (
      <code className={className} {...props}>
        {children}
      </code>
    );
  },
};

下面的这一串code({ node, inline, className, children, ...props }) 可以看成是模板(因为我也不太能看得懂),但是后面的代码其实比较容易理解。

这里的match其实是抽取了代码块的代码语言,match[1]的位置其实就是指定的语言,这里一个踩坑的点:最好把字符串小写化。因为用户可能输入的是Java,但是SyntaxHighlighter其实只能识别java,所以会出现代码没有高亮的情况。

返回三元字符串的意思是如果语言支持,则使用SyntaxHighlighter高亮,如果不支持则直接返回code标签包裹。

markdown-navbar目录提取

仍然是一个无脑的组件,你只需要将markdown文本传入source参数,就可以自动提取标题,并且点击标题可以实现跳转和目录高亮。

import MarkNav from 'markdown-navbar';
<MarkNav source={text} />

网页案例

好了,你现在以及会markdown的渲染操作了,去写一个博客网页的案例吧,只需要再加一点点细节。

代做工资流水公司济宁代做对公账户流水湘潭对公账户流水代做天津代开离职证明厦门工资代付流水价格扬州房贷银行流水 代开咸阳对公账户流水开具西安代做工资证明江门查询工资银行流水盐城消费贷流水价格岳阳薪资流水单多少钱孝感薪资流水报价西安在职证明代办包头打流水单邯郸打印银行流水PS廊坊代办签证流水柳州企业贷流水样本盐城查询薪资银行流水三亚代做入职工资流水肇庆办理银行流水单荆州工资流水房贷流水报价莆田打企业贷流水上海日常消费流水打印银川流水单打印厦门转账流水公司淄博银行流水修改代开杭州企业流水打印价格海口代开工作收入证明泉州银行流水代办常州办贷款流水香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

代做工资流水公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化