import crypto from 'crypto' import scopeCss from '@patarapolw/scope-css' import cheerio from 'cheerio' import jieba from 'nodejieba' import showdown from 'showdown' export class MakeHTML { $ = cheerio.load('') mdConverter = new showdown.Converter({ noHeaderId: true, parseImgDimensions: true, simplifiedAutoLink: true, // literalMidWordUnderscores: true, strikethrough: true, tables: true, tasklists: true, simpleLineBreaks: true, openLinksInNewWindow: true, backslashEscapesHTMLTags: true, emoji: true, underline: true, metadata: true, }) constructor(private slug: string) { /** * ! For some reasons default underscore italic fails to render... */ this.mdConverter.addExtension( { type: 'lang', regex: /([^\\])_{1}(.*?[^\\])_{1}/g, replace: '$1$2', }, 'underscore-italic' ) } parse(md: string): string { const id = 'md-' + crypto .createHash('sha256') .update(this.slug || md) .digest() .toString('hex') .substr(8) const $div = this.$(`
`) $div.html(this.mdConverter.makeHtml(md)) $div.find('style').each((_, el) => { const $el = this.$(el) const html = $el.html() || '' if (html.trim()) { $el.html(scopeCss(html, `#${id}`)) } }) return this.$('
').append($div).html() || '' } clean(md: string): string { const $div = this.$('
') $div.html(this.mdConverter.makeHtml(md)) $div.remove('style') return jieba.cutForSearch($div.html() || '').join(' ') } }