markDown转html的采坑之路

2022-07-14 21:01:37 浏览数 (1)

场景是基于关系产生的。所有的互联网应用都是将生活中的各种关系进行了一次抽象

前情回顾

上篇文章分享了的一个开发脚手架需要了解的相关技术点问题,今天要聊一下markDown转Html的一个问题

聊这个问题的原因是因为之前自己在开发一个博客系统的时候,后台需要将markDown语法转为html,然后才能提交到数据库中。否则博客的界面显示的只是纯文本内容,没有对应的样式。

我的目的是让后台可以支持MarkDown语法编辑,同时可以支持自定义样式。

基于这个需求,开始了采坑之路。

基于Vue的一次尝试

因为后台是用Vue搭建的,所以查了npm中支持markDownhtml的包。一个是mavon-editor,另外一个是codemirror

  • mavon-editor的使用方法如下:
代码语言:javascript复制
// test.vue
<template>
  <mavon-editor style="z-index:0" v-model="content" :toolbarsFlag="false" @htmlcode="editChange"></mavon-editor>
</template>
<script>
  import {mavonEditor} from 'mavon-editor'
  export default {
    data(){
      return {
        content:'' 
      }
    },
    methods:{
      editChange(v){
      console.log('value---',v)
    },
    }
  }
</script>

但是这里编辑的内容发生变化时,打印出来的value是纯文本,不带任何的html标签,所以这个方案pass掉了。

  • codeMirror的使用方法codeMirror的功能比较强大,但是使用起来也比较繁琐
代码语言:javascript复制
// test.vue
<template>
  <textarea
    id="code"
    name="code"
    rows="5"
    defaultValue="2312"
  ></textarea> 
</template>
<script>
 import 'codemirror/lib/codemirror.css'
 import 'codemirror/theme/monokai.css'
 import 'codemirror/theme/eclipse.css'
 import 'codemirror/theme/idea.css'
 import 'codemirror/addon/hint/show-hint.css'
 import 'codemirror/addon/display/fullscreen.css'
 import CodeMirror from 'codemirror/lib/codemirror.js'
 import 'codemirror/mode/markdown/markdown.js'
 import 'codemirror/mode/clike/clike.js'
 import 'codemirror/addon/display/autorefresh.js'
 import 'codemirror/addon/edit/matchbrackets.js'
 import 'codemirror/addon/selection/active-line.js'
 import 'codemirror/addon/display/fullscreen.js'
 import 'codemirror/addon/hint/show-hint.js'
 import 'codemirror/addon/hint/sql-hint.js'
  export default {
    data(){
      return {
        content:'' 
      }
    },
    mounted(){
      this.editer = CodeMirror.fromTextArea(
      document.getElementById('code'),
        {
          lineNumbers: false,
          lineWarpping: true,
          styleActiveLine: true,
          matchBrackets: true,
          autoRefresh: true,
          theme: 'monokai',
          mode: 'text/markdown',
          lint: true,
          // hint: CodeMirror.hint,
          extraKeys: {
            Q: function(cm) {
              cm.setOption('fullScreen', !cm.getOption('fullScreen'))
              // console.log('sqlCodeMirror--',sqlCodeMirror)
            },
            Esc: function(cm) {
              if (cm.getOption('fullScreen')) cm.setOption('fullScreen', false)
            }
          },
          hintOptions: {
            tables: {
              t_test_login: ['col_a', 'col_b'],
              t_test_employee: ['other_columns1', 'other_columns2']
            }
          }
        }
      )
      his.editer.on('change', function(editor, change) {
      if (change.origin == ' input') {
        var textArray = change.text
        // console.log('textArray',textArray)
        //不提示
        // if(!ignoreInputCode(textArray)){
        //  setTimeout(function() { editor.execCommand("autocomplete"); }, 100);
        // }
      }
      let test = self.editer.getTextArea();
      console.log('test---',test)
      let val = self.editer.getValue()
      console.log('val---',val)
      console.log(self.editer.getDoc())
    })
    }
    methods:{
      editChange(v){
      console.log('value---',v)
    },
    }
  }
</script>

需要在mounted方法中进行初始化,然后监听change方法获取文本内容,同样只返回文本,不带任何html标签

react项目中尝试解析markdown

因为前端网站是基于react开发的,所以找到了ReactMarkDown找个包。使用方法如下:

代码语言:javascript复制
import React,{useState,useEffect} from 'react';
import api from '../../http/api/index'
import { withRouter } from "react-router-dom";
import  ReactMarkDown  from 'react-markdown';
import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter';
// 这里是一堆主题样式
import {dark,tomorrow,duotoneForest,duotoneSea,duotoneSpace,materialOceanic,
  funky, vs,synthwave84 ,solarizedlight,shadesOfPurple,pojoaque,okaidia,nord
  ,materialLight,materialDark,hopscotch,ghcolors,a11yDark,atomDark,
  base16AteliersulphurpoolLight,cb,darcula,prism,vscDarkPlus
} from 'react-syntax-highlighter/dist/esm/styles/prism'
import {vs2015,googlecode,solarizedDark,gml} from 'react-syntax-highlighter/dist/esm/styles/hljs'

const renderers = {
  code: ({language, value}) => {
    return <SyntaxHighlighter style={solarizedDark} language={language} children={value} />
  }
}

const ArticleDetail =  ({...props})=>{
  const {state}= props.location
  const {artileId}= state
  const [content,setContent] = useState('');
  
  useEffect(()=>{
    if(artileId){
      getArticle({id:artileId})
    }
    
  },[artileId]);
  
  const getArticle = (params)=>{
    api.getArticleDetail(params).then(({data})=>{
      if(data.code == 200){
        setContent(data.data)
      }
    })
  }

  return (
    <ReactMarkDown 
      source={content.content}
      // children={content.content} 
      renderers={renderers}
      escapeHtml={true}  //不进行HTML标签的转化
    />
  )
}

export default withRouter(ArticleDetail)

这个组件理论上可以直接在界面上渲染markDown语法,但是后台上传不带html标签样式的文本后,渲染出来的内容丑陋不堪,所以这个方案也pass掉了。

最终的方案

在尝试了以上的方案以后,找到了这么一个东西

代码语言:javascript复制
<script src="http://cdn.bootcss.com/pagedown/1.0/Markdown.Converter.js"></script>

它可以把markDown编辑的内容转化成带html标签的字符串。使用方法如下:

代码语言:javascript复制
// html界面
<textarea id="test" v-model="content"  style="width:500px;min-height:300px;background:pink;"></textarea>
代码语言:javascript复制
// js
  var target = document.getElementById("test")
  var c = new Markdown.Converter()
  var html = c.makeHtml(target.innerText)
  console.log(html)
// <h3>hello world</h3>

这样一来,我们可以自由的上传带html标签的内容到后台,甚至可以对转化的html内容进行二次加工,进行样式的定制。算是比较符合最初的需求。

总结

  • mavon-editor,codeMirror,ReactMarkDown的基本使用
  • Markdown.Converter.js的基本使用
  • 相对于前三个包来说,个人感觉Markdown.Converter.js的使用还是比较好,可以自由的去定制一些自己想要的东西。

javascript基础知识总结

0 人点赞