markdown转VNode

marked2vue

A markdown parser and compiler. Built for speed.Integrate Vue framework based on the Marked.

Marked2vue based on the Marked.You can use Marked2vue just like Marked.

  • ⚡ built for speed
  • ⬇️ low-level compiler for parsing markdown without caching or blocking for long periods of time
  • 🏚 Support for markdown to VNode
  • 👍 Seamless compatibility with Marked

Install

npm install marked2vue

Original functions of Marked

You can use Marked2vue just like Marked,Marked Doc:Marked Documentation

import { marked } from 'marked2vue';

marked.use({
  pedantic: false,
  gfm: true,
  breaks: false,
  sanitize: false,
  smartypants: false,
  xhtml: false
});

const html = marked.parse('# Marked in Node.js\n\nRendered by **marked**.');

Extended functionality

marked2vue Integrate Vue framework,You can parse the markdown string into a virtual node in Vue using the parseVNode function.

import { h, defineComponent, VNode } from 'vue';
import { VueParser, Lexer, marked} from 'marked2vue'
export default defineComponent({
  setup() {
    const lexer = new Lexer() as any
    const vueParser = new VueParser()
    const vnode = vueParser.parse(lexer.lex('# Marked in Node.js\n\nRendered by **marked**.'))

    return () => h('div', vnode)
  }
})

function

Markdown to HTML String
import { marked,Lexer,Parser } from 'marked2vue'
//use Original functions of Marked
let html = marked.parse('# example-0\n\nRendered by **marked**.');

//or
html = marked('# example-5\n\nRendered by **marked**.')

//or
const lexer = new Lexer()
const parser = new Parser()
const tokens = lexer.lex('# example-3\n\nRendered by **marked**.')
html = parser.parse(tokens)
Markdown to VNode of Vue
import { marked,Lexer,VueParser } from 'marked2vue'
//marked2vue extension function
let vnode = marked.parseVNode('# example-2\n\nRendered by **marked**.')

//or
vnode = marked('# example-5\n\nRendered by **marked**.',{isVNodeModel:true})

//or
const lexer = new Lexer()
const vueParser = new VueParser()
const tokens = lexer.lex('# example-3\n\nRendered by **marked**.')
vnode = vueParser.parse(tokens)
Asynchronous highlighting

The codeBlock use asynchronous highlighting in marked.

highlighting html

more info Using Advanced - Marked Documentation

marked.setOptions({
  highlight: function(code, lang, callback) {
    require('pygmentize-bundled') ({ lang: lang, format: 'html' }, code, function (err, result) {
      callback(err, result.toString());
    });
  }
});

marked.parse(markdownString, (err, html) => {
  console.log(html);
});
highlighting vnode
import { h, VNode, defineComponent } from 'vue';
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css'

export default defineComponent({
    setup() {
        //curr
        const instance = getCurrentInstance()
        let vnode:VNode = null
        //or use setOptions() add highlight function
        const highlightcode = marked.parseVNode(fenceMarkdownText,{
            highlight:function(code, lang, callback){  //custom highlight function
                const res = hljs.highlight(code, {language: lang,ignoreIllegals: true}).value
                callback(null, res); //callback result
            }
        },(err,res)=>{ //callback
            vnode = h('div',{class:'example-7'}, res)
            instance?.proxy?.$forceUpdate()  //update vnode render
        })
        
        return ()=>h('div',{class:'myexmple'},vnode)
    }
})

Extensibility

marked extension:Using Pro - Marked Documentation

add marked extension
// Create reference instance
import { marked } from 'marked2vue';

// Override function
const renderer = {
  heading(text, level) {
    const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');

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

marked.use({ renderer });

// Run marked
console.log(marked.parse('# heading+'));
add marked2vue extension

base on marked extension. add vueRenderer extension。

CustomComponent.vue
<script setup lang='ts'>
const props = defineProps<{ level: string | number, id?: string }>()
</script>

<template>
    <h1 class="myHeading" :id="id" v-if="level == '1'">
        <slot></slot>
    </h1>
    <h2 class="myHeading" :id="id" v-else-if="level == '2'">
        <slot></slot>
    </h2>
    <h3 class="myHeading" :id="id" v-else-if="level == '3'">
        <slot></slot>
    </h3>
    <h4 class="myHeading" :id="id" v-else-if="level == '4'">
        <slot></slot>
    </h4>
    <h5 class="myHeading" :id="id" v-else-if="level == '5'">
        <slot></slot>
    </h5>
    <h6 class="myHeading" :id="id" v-else>
        <slot></slot>
    </h6>
</template>

<style scoped>
.myHeading{}
</style>
App.vue
<script lang='ts'>
import { h, defineComponent, VNode } from 'vue';
import { VueParser, Lexer, marked,Slugger} from '../lib/marked2vue.esm'
import CustomComponent from './component/CustomComponent.vue'

export default defineComponent({
  setup() {
    //like renderer.heading, but "inlineVnode" instead of "text"
    const vueRenderer = {
      heading(inlineVnode:VNode[], level:string, raw:string,slugger:any) {
        return h(CustomComponent,{level},()=>inlineVnode);
      }
    }
    marked.use({ vueRenderer });

    const lexer = new Lexer() as any
    const vueParser = new VueParser()

    const vnode = vueParser.parse(lexer.lex('# Marked in Node.js\n\nRendered by **marked**.'))

    return () => h('div', vnode)
  }
})
</script>
result
<div>
  <h1 data-v-cc7286a7="" class="myHeading">Marked in Node.js</h1>
  <p data-v-2704c122="" class="marked-vue-paragraph">Rendered by
    <strong data-v-2704c122-s="" class="marked-vue-bold">marked</strong>.</p>
</div>

comparison

<script lang='ts'>
import { h, defineComponent, VNode } from 'vue';
import { VueParser, Lexer, marked,Slugger} from 'marked2vue'
import CustomComponent from './component/CustomComponent.vue'
import { fenceMarkdownText } from './markdownText'
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css'

export default defineComponent({
  setup() {
	//curr
    const instance = getCurrentInstance()
    
    //use Original functions of Marked
    const html = marked.parse('# example-0\n\nRendered by **marked**.');
    const example0 = h('div',{class:'example-0',innerHTML:html})

    // Override function(marked extension)
    const renderer = {
    heading(text, level) {
        const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
        return `
                <h${level}>
                <a name="${escapedText}" class="anchor" href="#${escapedText}">
                    <span class="header-link"></span>
                </a>
                ${text}
                </h${level}>`;
    }
    };
    marked.use({ renderer });
    const html2 = marked.parse('# example-1\n\nRendered by **marked**.');
    const example1 = h('div',{class:'example-1',innerHTML:html2})



    //use Extended functionality
    const vnode1 = marked.parseVNode('# example-2\n\nRendered by **marked**.')
    const example2 = h('div',{class:'example-2'}, vnode1)

    //use lexer and vueParser
    const lexer = new Lexer() as any
    const vueParser = new VueParser()
    const tokens = lexer.lex('# example-3\n\nRendered by **marked**.')
    const vnode2 = vueParser.parse(tokens)
    const example3 = h('div',{class:'example-3'}, vnode2)

    //marked2vue extension
    const vueRenderer = {
      heading(inlineVnode:VNode[], level:string, raw:string,slugger:any) {
        return h(CustomComponent,{level},()=>inlineVnode);
      }
    }
    marked.use({ vueRenderer });
    const vnode3 = marked.parseVNode('# example-4\n\nRendered by **marked**.')
    const example4 = h('div',{class:'example-4'}, vnode3)


    //Original marked 
    const originalHtml = marked('# example-5\n\nRendered by **marked**.')
    const example5 = h('div',{class:'example-5',innerHTML:originalHtml})

    const originalVNode = marked('# example-6\n\nRendered by **marked**.',{isVNodeModel:true})
    const example6 = h('div',{class:'example-6'}, originalVNode)

    //highlight code block
    let example7:any = null
    const highlightcode = marked.parseVNode(fenceMarkdownText,{
      highlight:function(code, lang, callback){  //custom highlight
        const res = hljs.highlight(code, {language: lang,ignoreIllegals: true}).value
        callback(null, res);
      }
    },(err,res)=>{ //callback
      example7 = h('div',{class:'example-7'}, res)
      console.log(example7);
      instance?.proxy?.$forceUpdate()  //update vnode render
    })


    return () => h('div',{class:'example'}, [example0,example1,example2,example3,example4,example5,example6,example7])
  }
})
</script>
Vue的canvas vnode是Vue框架中用于创建和管理canvas元素的虚拟节点。 虚拟节点(vnode)是Vue中抽象出来的一种数据结构,用于描述DOM元素。通过使用虚拟节点,Vue可以跟踪每个组件的状态变化,并在需要时更新DOM。在Vue中,每个canvas元素都会被表示为一个独立的vnode。 canvas vnode提供了一种将Vue和canvas元素相结合的灵活方式。通过创建canvas vnode,我们可以在Vue组件中使用canvas元素,并利用Vue的数据驱动特性来动态更新canvas的内容。 在使用canvas vnode时,我们可以通过Vue的模板语法或者render函数来创建vnode。然后,我们可以将这些vnode添加到Vue组件的模板中。一旦vnode被添加到模板中,Vue会将其换为真实的DOM元素,并将其插入到页面中。 一旦canvas vnode被渲染到页面中,我们可以使用canvas的API操作它。这些API包括绘制线条、绘制图形、绘制文本等功能。我们可以通过监听Vue组件的数据变化,来实现动态更新canvas的内容。当数据发生变化时,Vue会自动重新渲染vnode,并更新canvas的内容。 使用canvas vnode,我们可以利用Vue的响应式系统来管理canvas元素的状态。当事件发生或数据变化时,我们可以通过更新VNode的数据来实现动态的canvas绘制。同时,由于canvas vnode会被Vue管理,我们可以利用Vue的生命周期钩子函数来控制canvas的绘制时机,以提高应用的性能和用户体验。 总之,Vue的canvas vnode为我们提供了一种简单、灵活的方式来操作canvas元素,并将其和Vue的数据驱动特性相结合。通过使用canvas vnode,我们可以实现动态的、响应式的canvas绘制,提高应用的可维护性和交互性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值