使用marked将markdown渲染成HTML的基本操作

文章目录


前言

最近想写一个博客网站,于是就想看看markdown 是如何转化成html的,本来我使用的是mvion-editor来编写我的markdown,但在实现只查看我上传的markdown是感觉有点笨重,于是就找到了marked 整个工具

安装

bash 复制代码
npm install marked

可以使用的其他工具

引入实例

默认情况下,Marked 将选项和扩展存储在全局范围内。这意味着更改一个脚本中的选项也会更改另一个脚本中的选项,因为它们共享同一个实例。

比如这种

javascript 复制代码
import {marked} from 'marked'
marked.renderer()

如果你不想改变全局范围,你可以创建一个新的 Marked 实例,以确保选项和扩展是本地范围的

javascript 复制代码
import { Marked } from 'marked';
const marked = new Marked([options, extension, ...]);

parse() 功能

javascript 复制代码
import { marked } from 'marked';
marked.parse(markdownString [,options])``

options 选项

还有一种使用option的方法

javascript 复制代码
// Create reference instance
import { marked } from 'marked';

// Set options
marked.use({
  async: true,
  pedantic: false,
  gfm: true,
});

// Compile
console.log(marked.parse(markdownString));

render 渲染器

渲染器定义给定标记的 HTML 输出。如果你在传递给 marked.use() 的选项对象中提供 renderer,则对象中的任何函数都将覆盖该标记类型的默认处理。

this.parser

将原始标记转换为 HTML

处理内联元素的嵌套结构

只能在渲染器的普通函数方法中访问(箭头函数不可用)

是 marked 内部 API 的一部分,用于构建完整的渲染链

块级渲染器方法

space(token: Tokens.Space): string

code(token: Tokens.Code): string

blockquote(token: Tokens.Blockquote): string

html(token: Tokens.HTML | Tokens.Tag): string

heading(token: Tokens.Heading): string

hr(token: Tokens.Hr): string

list(token: Tokens.List): string

listitem(token: Tokens.ListItem): string

checkbox(token: Tokens.Checkbox): string

paragraph(token: Tokens.Paragraph): string

table(token: Tokens.Table): string

tablerow(token: Tokens.TableRow): string

tablecell(token: Tokens.TableCell): string

内联级别渲染器方法

strong(token: Tokens.Strong): string

em(token: Tokens.Em): string

codespan(token: Tokens.Codespan): string

br(token: Tokens.Br): string

del(token: Tokens.Del): string

link(token: Tokens.Link): string

image(token: Tokens.Image): string

text(token: Tokens.Text | Tokens.Escape | Tokens.Tag): string

使用示例

javascript 复制代码
// Create reference instance
import { marked } from 'marked';

// Override function
const renderer = {
  heading({ tokens, depth }) {
    const text = this.parser.parseInline(tokens);
    const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');

    return `
            <h${depth}>
              <a name="${escapedText}" class="anchor" href="#${escapedText}">
                <span class="header-link"></span>
              </a>
              ${text}
            </h${depth}>`;
  }
};

marked.use({ renderer });
// Run marked
console.log(marked.parse('# heading+'));

上面的方法会创建一个新的renderer所有的渲染器只剩下你定义的heading 下面的是进行override

javascript 复制代码
import { marked } from 'marked';

// 获取默认渲染器
const renderer = new marked.Renderer();

// 覆盖默认渲染器的 heading 方法
renderer.heading = function({ tokens, depth }) {
  const text = this.parser.parseInline(tokens);
  const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');

  return `
          <h${depth}>
            <a name="${escapedText}" class="anchor" href="#${escapedText}">
              <span class="header-link"></span>
            </a>
            ${text}
          </h${depth}>`;
};

marked.setOptions({
  renderer: renderer
})

运行实例

在下面我重写了img 的渲染器,我感觉太大了,可以根据自己需要的大小,来进行替换,我的代码是根据,自己的项目来写的,想要运行的可以替换,下面的content.value的值,或者私信,我把markdown的部分,发出来,这里就不粘贴了

javascript 复制代码
<template>
  <div class="makedownMain" style="width:100vw;height:100vh">
    <div class="main">
    <div class="side"></div>
    <div class="main1">
  <el-scrollbar>
  <div class="title"><h1>{{ driftName }}</h1></div>
  <div class="content">
  <div v-html="htmlContent"></div>
  </div>
  </el-scrollbar>
  </div>
  </div>
  </div>
</template>

<script setup>
import { ref, onMounted} from 'vue'
import { marked } from 'marked'
import { userheaders } from '../../store/urlStore'
import { storeToRefs } from 'pinia'

const headers = userheaders()
const { content ,driftName} = storeToRefs(headers)
const htmlContent = ref('')



const renderer = new marked.Renderer()
renderer.image = function({ href, title, text }) {
  // href是图片URL,text是alt文本
  const altText = text || '图片'
  const escapedText = altText.toLowerCase().replace(/[^\w]+/g, '-')
  
  return `
    <img src="${href}" 
         alt="${escapedText}" 
         class="custom-markdown-image"
          ">
  `
}

marked.setOptions({
  renderer: renderer
})

onMounted(() => {
  if (content.value) {
    // 将markdown转换为HTML
    htmlContent.value = marked.parse(content.value)
    
  }})
</script>

<style>
  .title{
    margin-bottom: 5vh;
    
  }
.makedownMain{
  display:flex;
  
  overflow-y: auto;
  justify-content: center;
}
.main{
width:80vw;
box-shadow: var(--el-border-color-light) 0px 0px 10px;
display: flex;

}
.main1{
  width:65vw;
  height:100vh;
  background-color: aliceblue;
  box-shadow: var(--el-border-color-light) 0px 0px 10px;
  
}
img.custom-markdown-image {
  max-width: 50vw !important;
  height: auto !important;
  object-fit: contain !important;
  display: block !important;
  margin: 10px 0 !important;
  border-radius: 4px !important;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important;
}

.side{
  width:15vw;
  height:100vh;
  background-color:aliceblue;
}
.content{
  display: flex;
  height: inherit;
  width: inherit;
  justify-content: center;
}

</style

运行结果

可以看到我已经成功渲染出来了

相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
小羊没烦恼!1 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
俊昭喜喜里1 天前
java中的继承和多态的区别
java
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
譕痕1 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码1 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖1 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商