index.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /**
  2. * @fileoverview highlight 插件
  3. * Include prismjs (https://prismjs.com)
  4. */
  5. const prism = require('./prism.min')
  6. const config = require('./config')
  7. const Parser = require('../parser')
  8. function Highlight (vm) {
  9. this.vm = vm
  10. }
  11. Highlight.prototype.onParse = function (node, vm) {
  12. if (node.name === 'pre') {
  13. let i
  14. for (i = node.children.length; i--;) {
  15. if (node.children[i].name === 'code') break
  16. }
  17. if (i === -1) return
  18. const code = node.children[i]
  19. let className = code.attrs.class || ''
  20. i = className.indexOf('language-')
  21. if (i === -1) {
  22. className = node.attrs.class || ''
  23. i = className.indexOf('language-')
  24. }
  25. if (i === -1) {
  26. className = 'language-text'
  27. i = className.indexOf('language-')
  28. }
  29. i += 9
  30. let j
  31. for (j = i; j < className.length; j++) {
  32. if (className[j] === ' ') break
  33. }
  34. const lang = className.substring(i, j)
  35. if (code.children.length && code.children[0].type === 'text') {
  36. const text = code.children[0].text.replace(/&amp;/g, '&')
  37. if (prism.languages[lang]) {
  38. code.children = (new Parser(this.vm).parse(
  39. // 加一层 pre 保留空白符
  40. '<pre>' + prism.highlight(text, prism.languages[lang], lang).replace(/token /g, 'hl-') + '</pre>'))[0].children
  41. }
  42. node.attrs.class = 'hl-pre'
  43. code.attrs.class = 'hl-code'
  44. if (config.showLanguageName) {
  45. node.children.push({
  46. name: 'div',
  47. attrs: {
  48. class: 'hl-language',
  49. style: 'user-select:none'
  50. },
  51. children: [{
  52. type: 'text',
  53. text: lang
  54. }]
  55. })
  56. }
  57. if (config.copyByLongPress) {
  58. node.attrs.style += (node.attrs.style || '') + ';user-select:none'
  59. node.attrs['data-content'] = text
  60. vm.expose()
  61. }
  62. if (config.showLineNumber) {
  63. const line = text.split('\n').length; const children = []
  64. for (let k = line; k--;) {
  65. children.push({
  66. name: 'span',
  67. attrs: {
  68. class: 'span'
  69. }
  70. })
  71. }
  72. node.children.push({
  73. name: 'span',
  74. attrs: {
  75. class: 'line-numbers-rows'
  76. },
  77. children
  78. })
  79. }
  80. }
  81. }
  82. }
  83. module.exports = Highlight