97 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
		
			
		
	
	
			97 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @fileoverview highlight 插件
							 | 
						||
| 
								 | 
							
								 * Include prismjs (https://prismjs.com)
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								const prism = require('./prism.min')
							 | 
						||
| 
								 | 
							
								const config = require('./config')
							 | 
						||
| 
								 | 
							
								const Parser = require('../parser')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function Highlight (vm) {
							 | 
						||
| 
								 | 
							
								  this.vm = vm
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Highlight.prototype.onParse = function (node, vm) {
							 | 
						||
| 
								 | 
							
								  if (node.name === 'pre') {
							 | 
						||
| 
								 | 
							
								    if (vm.options.editable) {
							 | 
						||
| 
								 | 
							
								      node.attrs.class = (node.attrs.class || '') + ' hl-pre'
							 | 
						||
| 
								 | 
							
								      return
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    let i
							 | 
						||
| 
								 | 
							
								    for (i = node.children.length; i--;) {
							 | 
						||
| 
								 | 
							
								      if (node.children[i].name === 'code') break
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (i === -1) return
							 | 
						||
| 
								 | 
							
								    const code = node.children[i]
							 | 
						||
| 
								 | 
							
								    let className = code.attrs.class + ' ' + node.attrs.class
							 | 
						||
| 
								 | 
							
								    i = className.indexOf('language-')
							 | 
						||
| 
								 | 
							
								    if (i === -1) {
							 | 
						||
| 
								 | 
							
								      i = className.indexOf('lang-')
							 | 
						||
| 
								 | 
							
								      if (i === -1) {
							 | 
						||
| 
								 | 
							
								        className = 'language-text'
							 | 
						||
| 
								 | 
							
								        i = 9
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        i += 5
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      i += 9
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    let j
							 | 
						||
| 
								 | 
							
								    for (j = i; j < className.length; j++) {
							 | 
						||
| 
								 | 
							
								      if (className[j] === ' ') break
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    const lang = className.substring(i, j)
							 | 
						||
| 
								 | 
							
								    if (code.children.length) {
							 | 
						||
| 
								 | 
							
								      const text = this.vm.getText(code.children).replace(/&/g, '&')
							 | 
						||
| 
								 | 
							
								      if (!text) return
							 | 
						||
| 
								 | 
							
								      if (node.c) {
							 | 
						||
| 
								 | 
							
								        node.c = undefined
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (prism.languages[lang]) {
							 | 
						||
| 
								 | 
							
								        code.children = (new Parser(this.vm).parse(
							 | 
						||
| 
								 | 
							
								          // 加一层 pre 保留空白符
							 | 
						||
| 
								 | 
							
								          '<pre>' + prism.highlight(text, prism.languages[lang], lang).replace(/token /g, 'hl-') + '</pre>'))[0].children
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      node.attrs.class = 'hl-pre'
							 | 
						||
| 
								 | 
							
								      code.attrs.class = 'hl-code'
							 | 
						||
| 
								 | 
							
								      if (config.showLanguageName) {
							 | 
						||
| 
								 | 
							
								        node.children.push({
							 | 
						||
| 
								 | 
							
								          name: 'div',
							 | 
						||
| 
								 | 
							
								          attrs: {
							 | 
						||
| 
								 | 
							
								            class: 'hl-language',
							 | 
						||
| 
								 | 
							
								            style: 'user-select:none'
							 | 
						||
| 
								 | 
							
								          },
							 | 
						||
| 
								 | 
							
								          children: [{
							 | 
						||
| 
								 | 
							
								            type: 'text',
							 | 
						||
| 
								 | 
							
								            text: lang
							 | 
						||
| 
								 | 
							
								          }]
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (config.copyByLongPress) {
							 | 
						||
| 
								 | 
							
								        node.attrs.style += (node.attrs.style || '') + ';user-select:none'
							 | 
						||
| 
								 | 
							
								        node.attrs['data-content'] = text
							 | 
						||
| 
								 | 
							
								        vm.expose()
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (config.showLineNumber) {
							 | 
						||
| 
								 | 
							
								        const line = text.split('\n').length; const children = []
							 | 
						||
| 
								 | 
							
								        for (let k = line; k--;) {
							 | 
						||
| 
								 | 
							
								          children.push({
							 | 
						||
| 
								 | 
							
								            name: 'span',
							 | 
						||
| 
								 | 
							
								            attrs: {
							 | 
						||
| 
								 | 
							
								              class: 'span'
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          })
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        node.children.push({
							 | 
						||
| 
								 | 
							
								          name: 'span',
							 | 
						||
| 
								 | 
							
								          attrs: {
							 | 
						||
| 
								 | 
							
								            class: 'line-numbers-rows'
							 | 
						||
| 
								 | 
							
								          },
							 | 
						||
| 
								 | 
							
								          children
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = Highlight
							 |