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
 |