Optimize markdown renderer
This commit is contained in:
parent
907ba7e270
commit
2f19481147
|
@ -7,8 +7,13 @@ const sanitizeHtml = require('sanitize-html')
|
||||||
const markdownItEmoji = require('markdown-it-emoji/light')
|
const markdownItEmoji = require('markdown-it-emoji/light')
|
||||||
const MarkdownItClass = require('markdown-it')
|
const MarkdownItClass = require('markdown-it')
|
||||||
|
|
||||||
const markdownItWithHTML = new MarkdownItClass('default', { linkify: true, breaks: true, html: true })
|
const markdownItForSafeHtml = new MarkdownItClass('default', { linkify: true, breaks: true, html: true })
|
||||||
const markdownItWithoutHTML = new MarkdownItClass('default', { linkify: true, breaks: true, html: false })
|
.enable(TEXT_WITH_HTML_RULES)
|
||||||
|
.use(markdownItEmoji)
|
||||||
|
|
||||||
|
const markdownItForPlainText = new MarkdownItClass('default', { linkify: false, breaks: true, html: false })
|
||||||
|
.use(markdownItEmoji)
|
||||||
|
.use(plainTextPlugin)
|
||||||
|
|
||||||
const toSafeHtml = (text: string) => {
|
const toSafeHtml = (text: string) => {
|
||||||
if (!text) return ''
|
if (!text) return ''
|
||||||
|
@ -17,9 +22,7 @@ const toSafeHtml = (text: string) => {
|
||||||
const textWithLineFeed = text.replace(/<br.?\/?>/g, '\r\n')
|
const textWithLineFeed = text.replace(/<br.?\/?>/g, '\r\n')
|
||||||
|
|
||||||
// Convert possible markdown (emojis, emphasis and lists) to html
|
// Convert possible markdown (emojis, emphasis and lists) to html
|
||||||
const html = markdownItWithHTML.enable(TEXT_WITH_HTML_RULES)
|
const html = markdownItForSafeHtml.render(textWithLineFeed)
|
||||||
.use(markdownItEmoji)
|
|
||||||
.render(textWithLineFeed)
|
|
||||||
|
|
||||||
// Convert to safe Html
|
// Convert to safe Html
|
||||||
return sanitizeHtml(html, defaultSanitizeOptions)
|
return sanitizeHtml(html, defaultSanitizeOptions)
|
||||||
|
@ -28,12 +31,10 @@ const toSafeHtml = (text: string) => {
|
||||||
const mdToOneLinePlainText = (text: string) => {
|
const mdToOneLinePlainText = (text: string) => {
|
||||||
if (!text) return ''
|
if (!text) return ''
|
||||||
|
|
||||||
markdownItWithoutHTML.use(markdownItEmoji)
|
markdownItForPlainText.render(text)
|
||||||
.use(plainTextPlugin)
|
|
||||||
.render(text)
|
|
||||||
|
|
||||||
// Convert to safe Html
|
// Convert to safe Html
|
||||||
return sanitizeHtml(markdownItWithoutHTML.plainText, textOnlySanitizeOptions)
|
return sanitizeHtml(markdownItForPlainText.plainText, textOnlySanitizeOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -47,30 +48,39 @@ export {
|
||||||
|
|
||||||
// Thanks: https://github.com/wavesheep/markdown-it-plain-text
|
// Thanks: https://github.com/wavesheep/markdown-it-plain-text
|
||||||
function plainTextPlugin (markdownIt: any) {
|
function plainTextPlugin (markdownIt: any) {
|
||||||
let lastSeparator = ''
|
|
||||||
|
|
||||||
function plainTextRule (state: any) {
|
function plainTextRule (state: any) {
|
||||||
const text = scan(state.tokens)
|
const text = scan(state.tokens)
|
||||||
|
|
||||||
markdownIt.plainText = text.replace(/\s+/g, ' ')
|
// markdownIt.plainText = text.replace(/\s+/g, ' ')
|
||||||
|
markdownIt.plainText = text
|
||||||
}
|
}
|
||||||
|
|
||||||
function scan (tokens: any[]) {
|
function scan (tokens: any[]) {
|
||||||
|
let lastSeparator = ''
|
||||||
let text = ''
|
let text = ''
|
||||||
|
|
||||||
for (const token of tokens) {
|
function buildSeparator (token: any) {
|
||||||
if (token.children !== null) {
|
|
||||||
text += scan(token.children)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if (token.type === 'list_item_close') {
|
if (token.type === 'list_item_close') {
|
||||||
lastSeparator = ', '
|
lastSeparator = ', '
|
||||||
} else if (/[a-zA-Z]+_close/.test(token.type)) {
|
}
|
||||||
|
|
||||||
|
if (token.tag === 'br' || token.type === 'paragraph_close') {
|
||||||
lastSeparator = ' '
|
lastSeparator = ' '
|
||||||
} else if (token.content) {
|
}
|
||||||
text += lastSeparator
|
}
|
||||||
text += token.content
|
|
||||||
|
for (const token of tokens) {
|
||||||
|
buildSeparator(token)
|
||||||
|
|
||||||
|
if (token.type !== 'inline') continue
|
||||||
|
|
||||||
|
for (const child of token.children) {
|
||||||
|
buildSeparator(child)
|
||||||
|
|
||||||
|
if (!child.content) continue
|
||||||
|
|
||||||
|
text += lastSeparator + child.content
|
||||||
|
lastSeparator = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,5 +30,11 @@ describe('Markdown helpers', function () {
|
||||||
|
|
||||||
expect(result).to.equal('Hello coucou')
|
expect(result).to.equal('Hello coucou')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should convert tags to plain text', function () {
|
||||||
|
const result = mdToOneLinePlainText(`#déconversion\n#newage\n#histoire`)
|
||||||
|
|
||||||
|
expect(result).to.equal('#déconversion #newage #histoire')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue