diff --git a/src/renderer/components/Preview.vue b/src/renderer/components/Preview.vue
index b616f3cc..62ed26a7 100644
--- a/src/renderer/components/Preview.vue
+++ b/src/renderer/components/Preview.vue
@@ -47,7 +47,6 @@ import Markdown from 'markdown-it'
import katex from 'markdown-it-katex'
import MarkdownItAttrs from 'markdown-it-attrs'
import MultimdTable from 'markdown-it-multimd-table'
-import Highlight from 'highlight.js'
import file from '@fe/useful/file'
import { triggerHook } from '@fe/useful/plugin'
@@ -59,20 +58,7 @@ import 'github-markdown-css/github-markdown.css'
import 'highlight.js/styles/atom-one-dark.css'
import 'katex/dist/katex.min.css'
-const markdown = Markdown({
- linkify: true,
- breaks: true,
- html: true,
- highlight: (str: string, lang: string) => {
- if (lang && Highlight.getLanguage(lang)) {
- try {
- return Highlight.highlight(lang, str).value
- } catch (__) {}
- }
-
- return ''
- }
-})
+const markdown = Markdown({ linkify: true, breaks: true, html: true, })
.use(katex)
.use(MarkdownItAttrs)
.use(MultimdTable, { multiline: true })
diff --git a/src/renderer/plugins/code-line-number.ts b/src/renderer/plugins/code-line-number.ts
deleted file mode 100644
index e727c02e..00000000
--- a/src/renderer/plugins/code-line-number.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-/* eslint-disable */
-
-// https://github.com/wcoder/highlightjs-line-numbers.js
-
-import { Plugin } from '@fe/useful/plugin'
-
-const TABLE_NAME = 'hljs-ln'
-const LINE_NAME = 'hljs-ln-line'
-const CODE_BLOCK_NAME = 'hljs-ln-code'
-const NUMBERS_BLOCK_NAME = 'hljs-ln-numbers'
-const NUMBER_LINE_NAME = 'hljs-ln-n'
-const DATA_ATTR_NAME = 'data-line-number'
-const BREAK_LINE_REGEXP = /\r\n|\r|\n/g
-
-function addStyles () {
- var css = document.createElement('style')
- css.type = 'text/css'
- css.innerHTML = format(
- '.{0}{border-collapse:collapse}' +
- '.{0} td{padding:0}' +
- '.{1}:before{content:attr({2})}',
- [
- TABLE_NAME,
- NUMBER_LINE_NAME,
- DATA_ATTR_NAME
- ])
- document.getElementsByTagName('head')[0].appendChild(css)
-}
-
-function lineNumbersBlock (element: any, options?: any) {
- if (typeof element !== 'object') return
-
- async(function () {
- element.innerHTML = lineNumbersInternal(element, options)
- })
-}
-
-function lineNumbersInternal (element: any, options: any) {
- // define options or set default
- options = options || {
- singleLine: false
- }
-
- // convert options
- var firstLineIndex = options.singleLine ? 0 : 1
-
- duplicateMultilineNodes(element)
-
- return addLineNumbersBlockFor(element.innerHTML, firstLineIndex)
-}
-
-function addLineNumbersBlockFor (inputHtml: any, firstLineIndex: any) {
- var lines = getLines(inputHtml)
-
- // if last line contains only carriage return remove it
- if (lines[lines.length - 1].trim() === '') {
- lines.pop()
- }
-
- if (lines.length > firstLineIndex) {
- var html = ''
-
- for (var i = 0, l = lines.length; i < l; i++) {
- html += format(
- '
' +
- '| ' +
- '' +
- ' | ' +
- '' +
- ' {6} ' +
- ' | ' +
- '
',
- [
- NUMBERS_BLOCK_NAME,
- LINE_NAME,
- NUMBER_LINE_NAME,
- DATA_ATTR_NAME,
- CODE_BLOCK_NAME,
- i + 1,
- lines[i].length > 0 ? lines[i] : ' '
- ])
- }
-
- return format('', [ TABLE_NAME, html ])
- }
-
- return inputHtml
-}
-
-/**
- * Recursive method for fix multi-line elements implementation in highlight.js
- * Doing deep passage on child nodes.
- * @param {HTMLElement} element
- */
-function duplicateMultilineNodes (element: any) {
- var nodes = element.childNodes
- for (var node in nodes) {
- if (nodes.hasOwnProperty(node)) {
- var child = nodes[node]
- if (getLinesCount(child.textContent) > 0) {
- if (child.childNodes.length > 0) {
- duplicateMultilineNodes(child)
- } else {
- duplicateMultilineNode(child.parentNode)
- }
- }
- }
- }
-}
-
-/**
- * Method for fix multi-line elements implementation in highlight.js
- * @param {HTMLElement} element
- */
-function duplicateMultilineNode (element: any) {
- var className = element.className
-
- if (!/hljs-/.test(className)) return
-
- var lines = getLines(element.innerHTML)
-
- for (var i = 0, result = ''; i < lines.length; i++) {
- var lineText = lines[i].length > 0 ? lines[i] : ' '
- result += format('{1}\n', [ className, lineText ])
- }
-
- element.innerHTML = result.trim()
-}
-
-function getLines (text: string) {
- if (text.length === 0) return []
- return text.split(BREAK_LINE_REGEXP)
-}
-
-function getLinesCount (text: string) {
- return (text.trim().match(BREAK_LINE_REGEXP) || []).length
-}
-
-function async (func: Function) {
- setTimeout(func, 0)
-}
-
-/**
- * {@link https://wcoder.github.io/notes/string-format-for-string-formating-in-javascript}
- * @param {string} format
- * @param {array} args
- */
-function format (format: string, args: any) {
- return format.replace(/\{(\d+)\}/g, function (m, n) {
- return args[n] ? args[n] : m
- })
-}
-
-export default {
- name: 'markdown-toc',
- register: ctx => {
- ctx.registerHook('ON_STARTUP', addStyles)
- ctx.registerHook('ON_VIEW_RENDERED', ({ getViewDom }) => {
- const refView: HTMLElement = getViewDom()
- const nodes = refView.querySelectorAll('code[class^="language-"]')
- nodes.forEach(lineNumbersBlock)
- })
- }
-} as Plugin
diff --git a/src/renderer/plugins/markdown-code.ts b/src/renderer/plugins/markdown-code.ts
index b4944ea3..43f3b9f4 100644
--- a/src/renderer/plugins/markdown-code.ts
+++ b/src/renderer/plugins/markdown-code.ts
@@ -1,9 +1,167 @@
+import Highlight from 'highlight.js'
import { getKeyLabel } from '@fe/useful/shortcut'
import { Plugin, Ctx } from '@fe/useful/plugin'
+import { getLogger } from '../useful/utils'
+
+const logger = getLogger('markdown-code')
+
+/* eslint-disable */
+
+// https://github.com/wcoder/highlightjs-line-numbers.js
+
+const TABLE_NAME = 'hljs-ln'
+const LINE_NAME = 'hljs-ln-line'
+const CODE_BLOCK_NAME = 'hljs-ln-code'
+const NUMBERS_BLOCK_NAME = 'hljs-ln-numbers'
+const NUMBER_LINE_NAME = 'hljs-ln-n'
+const DATA_ATTR_NAME = 'data-line-number'
+const BREAK_LINE_REGEXP = /\r\n|\r|\n/g
+
+function addStyles () {
+ var css = document.createElement('style')
+ css.type = 'text/css'
+ css.innerHTML = format(
+ '.{0}{border-collapse:collapse}' +
+ '.{0} td{padding:0}' +
+ '.{1}:before{content:attr({2})}',
+ [
+ TABLE_NAME,
+ NUMBER_LINE_NAME,
+ DATA_ATTR_NAME
+ ])
+ document.getElementsByTagName('head')[0].appendChild(css)
+}
+
+function lineNumbersInternal (element: any, options?: any) {
+ // define options or set default
+ options = options || {
+ singleLine: false
+ }
+
+ // convert options
+ var firstLineIndex = options.singleLine ? 0 : 1
+
+ duplicateMultilineNodes(element)
+
+ return addLineNumbersBlockFor(element.innerHTML, firstLineIndex)
+}
+
+function addLineNumbersBlockFor (inputHtml: any, firstLineIndex: any) {
+ var lines = getLines(inputHtml)
+
+ // if last line contains only carriage return remove it
+ if (lines[lines.length - 1].trim() === '') {
+ lines.pop()
+ }
+
+ if (lines.length > firstLineIndex) {
+ var html = ''
+
+ for (var i = 0, l = lines.length; i < l; i++) {
+ html += format(
+ '' +
+ '| ' +
+ '' +
+ ' | ' +
+ '' +
+ ' {6} ' +
+ ' | ' +
+ '
',
+ [
+ NUMBERS_BLOCK_NAME,
+ LINE_NAME,
+ NUMBER_LINE_NAME,
+ DATA_ATTR_NAME,
+ CODE_BLOCK_NAME,
+ i + 1,
+ lines[i].length > 0 ? lines[i] : ' '
+ ])
+ }
+
+ return format('', [ TABLE_NAME, html ])
+ }
+
+ return inputHtml
+}
+
+/**
+ * Recursive method for fix multi-line elements implementation in highlight.js
+ * Doing deep passage on child nodes.
+ * @param {HTMLElement} element
+ */
+function duplicateMultilineNodes (element: any) {
+ var nodes = element.childNodes
+ for (var node in nodes) {
+ if (nodes.hasOwnProperty(node)) {
+ var child = nodes[node]
+ if (getLinesCount(child.textContent) > 0) {
+ if (child.childNodes.length > 0) {
+ duplicateMultilineNodes(child)
+ } else {
+ duplicateMultilineNode(child.parentNode)
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Method for fix multi-line elements implementation in highlight.js
+ * @param {HTMLElement} element
+ */
+function duplicateMultilineNode (element: any) {
+ var className = element.className
+
+ if (!/hljs-/.test(className)) return
+
+ var lines = getLines(element.innerHTML)
+
+ for (var i = 0, result = ''; i < lines.length; i++) {
+ var lineText = lines[i].length > 0 ? lines[i] : ' '
+ result += format('{1}\n', [ className, lineText ])
+ }
+
+ element.innerHTML = result.trim()
+}
+
+function getLines (text: string) {
+ if (text.length === 0) return []
+ return text.split(BREAK_LINE_REGEXP)
+}
+
+function getLinesCount (text: string) {
+ return (text.trim().match(BREAK_LINE_REGEXP) || []).length
+}
+
+/**
+ * {@link https://wcoder.github.io/notes/string-format-for-string-formating-in-javascript}
+ * @param {string} format
+ * @param {array} args
+ */
+function format (format: string, args: any) {
+ return format.replace(/\{(\d+)\}/g, function (m, n) {
+ return args[n] ? args[n] : m
+ })
+}
+
+function highlight (str: string, lang: string) {
+ if (lang && Highlight.getLanguage(lang)) {
+ try {
+ const element = document.createElement('code')
+ element.innerHTML = Highlight.highlight(lang, str).value
+ return lineNumbersInternal(element)
+ } catch (error) {
+ logger.error(error)
+ }
+ }
+
+ return ''
+}
export default {
name: 'markdown-code',
register: (ctx: Ctx) => {
+ ctx.registerHook('ON_STARTUP', addStyles)
ctx.markdown.registerPlugin(md => {
const Fun = (fn: Function) => (tokens: any, idx: any, options: any, env: any, slf: any) => {
if (tokens[idx].attrIndex('title') < 0) {
@@ -15,6 +173,7 @@ export default {
}
md.renderer.rules.code_inline = Fun(md.renderer.rules.code_inline!.bind(md.renderer.rules))
+ md.options.highlight = highlight as any
})
}
} as Plugin
diff --git a/src/renderer/plugins/markdown-render-vnode.ts b/src/renderer/plugins/markdown-render-vnode.ts
index b9cb9cf6..3a242662 100644
--- a/src/renderer/plugins/markdown-render-vnode.ts
+++ b/src/renderer/plugins/markdown-render-vnode.ts
@@ -46,7 +46,7 @@ defaultRules.fence = function (tokens: Token[], idx: number, options: any, _: an
const buildVNode = (arrts: any) => createVNode(
'pre',
{},
- [createVNode('code', { key: highlighted, ...arrts, innerHTML: highlighted }, [])]
+ [createVNode('code', { ...arrts, innerHTML: highlighted }, [])]
)
// If language exists, inject class gently, without modifying original token.
diff --git a/src/renderer/useful/plugin/build-in.ts b/src/renderer/useful/plugin/build-in.ts
index 8d1d2948..ac7ce02f 100644
--- a/src/renderer/useful/plugin/build-in.ts
+++ b/src/renderer/useful/plugin/build-in.ts
@@ -11,7 +11,6 @@ import markdownCode from '@fe/plugins/markdown-code'
import markdownLink from '@fe/plugins/markdown-link'
import markdownTaskList from '@fe/plugins/markdown-task-list'
import markdownFootnote from '@/renderer/plugins/markdown-footnote'
-import codeLineNumber from '@fe/plugins/code-line-number'
import transformImgOutLink from '@fe/plugins/transform-img-out-link'
import copyText from '@fe/plugins/copy-text'
import tableCellEdit from '@fe/plugins/table-cell-edit'
@@ -38,7 +37,6 @@ export default [
markdownLink,
markdownTaskList,
markdownFootnote,
- codeLineNumber,
transformImgOutLink,
copyText,
tableCellEdit,