From 740a081c6db60a4b60e5cf9c3d0ca5d8c2d67dc0 Mon Sep 17 00:00:00 2001 From: Ze Yu Date: Wed, 17 Feb 2021 22:47:21 +0800 Subject: [PATCH] Eslint appropriate lib/markdown-it files The lib/markdown-it directory in the core package is entirely ignored by our eslint rules. Let's tighten the eslint ignore rules to only ignore adapted source files that are largely unchanged from the original source. This allows easily referencing the original source material if needed. --- .eslintignore | 5 +- .../markdown-it/highlight/HighlightRule.js | 24 ++++---- .../highlight/HighlightRuleComponent.js | 14 ++--- packages/core/src/lib/markdown-it/index.js | 59 +++++++++++-------- .../markdown-it/plugins/markdown-it-icons.js | 53 ++++++++--------- 5 files changed, 81 insertions(+), 74 deletions(-) diff --git a/.eslintignore b/.eslintignore index ba48e019fd..f7462f15c3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,7 +1,8 @@ *.min.* node_modules -packages/core/src/lib/markdown-it/* -packages/core/src/lib/markdown-it-shared/* +packages/core/src/lib/markdown-it/patches/* +packages/core/src/lib/markdown-it/plugins/* +!packages/core/src/lib/markdown-it/plugins/markdown-it-icons.js !.eslintrc.js diff --git a/packages/core/src/lib/markdown-it/highlight/HighlightRule.js b/packages/core/src/lib/markdown-it/highlight/HighlightRule.js index 2602b12353..6abe98fb98 100644 --- a/packages/core/src/lib/markdown-it/highlight/HighlightRule.js +++ b/packages/core/src/lib/markdown-it/highlight/HighlightRule.js @@ -7,16 +7,16 @@ class HighlightRule { */ this.ruleComponents = ruleComponents; } - + static parseRule(ruleString) { const components = ruleString.split('-').map(HighlightRuleComponent.parseRuleComponent); return new HighlightRule(components); } - + offsetLines(offset) { this.ruleComponents.forEach(comp => comp.offsetLineNumber(offset)); } - + shouldApplyHighlight(lineNumber) { const compares = this.ruleComponents.map(comp => comp.compareLine(lineNumber)); if (this.isLineRange()) { @@ -24,29 +24,29 @@ class HighlightRule { const withinRangeEnd = compares[1] >= 0; return withinRangeStart && withinRangeEnd; } - + const atLineNumber = compares[0] === 0; return atLineNumber; } - + applyHighlight(line) { const isLineSlice = this.ruleComponents.length === 1 && this.ruleComponents[0].isSlice; - + if (this.isLineRange()) { const shouldWholeLine = this.ruleComponents.some(comp => comp.isUnboundedSlice()); return shouldWholeLine ? HighlightRule._highlightWholeLine(line) : HighlightRule._highlightTextOnly(line); } - + if (isLineSlice) { // TODO: Implement slice-index based highlighting return HighlightRule._highlightWholeLine(line); } - + return HighlightRule._highlightTextOnly(line); } - + static _highlightWholeLine(codeStr) { return `${codeStr}\n`; } @@ -57,10 +57,10 @@ class HighlightRule { const content = codeStr.substr(codeStartIdx); return [indents, content]; } - + static _highlightTextOnly(codeStr) { const [indents, content] = HighlightRule._splitCodeAndIndentation(codeStr); - return `${indents}${content}\n` + return `${indents}${content}\n`; } isLineRange() { @@ -69,5 +69,5 @@ class HighlightRule { } module.exports = { - HighlightRule + HighlightRule, }; diff --git a/packages/core/src/lib/markdown-it/highlight/HighlightRuleComponent.js b/packages/core/src/lib/markdown-it/highlight/HighlightRuleComponent.js index 63e0073028..36dd0341c6 100644 --- a/packages/core/src/lib/markdown-it/highlight/HighlightRuleComponent.js +++ b/packages/core/src/lib/markdown-it/highlight/HighlightRuleComponent.js @@ -6,20 +6,20 @@ class HighlightRuleComponent { this.isSlice = isSlice || false; this.bounds = bounds || []; } - + static parseRuleComponent(compString) { // tries to match with the line slice pattern const matches = compString.match(LINESLICE_REGEX); if (matches) { const groups = matches.slice(1); // keep the capturing group matches only const lineNumber = parseInt(groups.shift(), 10); - + const isUnbounded = groups.every(x => x === ''); if (isUnbounded) { return new HighlightRuleComponent(lineNumber, true); } - - const bounds = groups.map(x => x !== '' ? parseInt(x, 10) : -1); + + const bounds = groups.map(x => (x !== '' ? parseInt(x, 10) : -1)); return new HighlightRuleComponent(lineNumber, true, bounds); } @@ -27,14 +27,14 @@ class HighlightRuleComponent { const lineNumber = parseInt(compString, 10); return new HighlightRuleComponent(lineNumber); } - + offsetLineNumber(offset) { this.lineNumber += offset; } /** * Compares the component's line number to a given line number. - * + * * @param lineNumber The line number to compare * @returns {number} A negative number, zero, or a positive number when the given line number * is after, at, or before the component's line number @@ -49,5 +49,5 @@ class HighlightRuleComponent { } module.exports = { - HighlightRuleComponent + HighlightRuleComponent, }; diff --git a/packages/core/src/lib/markdown-it/index.js b/packages/core/src/lib/markdown-it/index.js index d2d70c1850..216f3467b9 100644 --- a/packages/core/src/lib/markdown-it/index.js +++ b/packages/core/src/lib/markdown-it/index.js @@ -1,9 +1,14 @@ +const katex = require('katex'); const hljs = require('highlight.js'); const markdownIt = require('markdown-it')({ html: true, - linkify: true + linkify: true, }); -const slugify = require('@sindresorhus/slugify'); + +const _ = {}; +_.constant = require('lodash/constant'); + +const logger = require('../../utils/logger'); const { HighlightRule } = require('./highlight/HighlightRule.js'); @@ -19,11 +24,11 @@ markdownIt.use(createDoubleDelimiterInlineRule('%%', 'dimmed', 'emphasis')) markdownIt.use(require('markdown-it-mark')) .use(require('markdown-it-sub')) .use(require('markdown-it-sup')) - .use(require('markdown-it-imsize'), {autofill: false}) + .use(require('markdown-it-imsize'), { autofill: false }) .use(require('markdown-it-table-of-contents')) - .use(require('markdown-it-task-lists'), {enabled: true}) - .use(require('markdown-it-linkify-images'), {imgClass: 'img-fluid'}) - .use(require('markdown-it-texmath'), {engine: require('katex'), delimiters: 'brackets'}) + .use(require('markdown-it-task-lists'), { enabled: true }) + .use(require('markdown-it-linkify-images'), { imgClass: 'img-fluid' }) + .use(require('markdown-it-texmath'), { engine: katex, delimiters: 'brackets' }) .use(require('./patches/markdown-it-attrs-nunjucks')) .use(require('./plugins/markdown-it-radio-button')) .use(require('./plugins/markdown-it-block-embed')) @@ -31,12 +36,9 @@ markdownIt.use(require('markdown-it-mark')) .use(require('./plugins/markdown-it-footnotes')); // fix table style -markdownIt.renderer.rules.table_open = (tokens, idx) => { - return '
'; -}; -markdownIt.renderer.rules.table_close = (tokens, idx) => { - return '
'; -}; +markdownIt.renderer.rules.table_open = _.constant( + '
'); +markdownIt.renderer.rules.table_close = _.constant('
'); function getAttributeAndDelete(token, attr) { const index = token.attrIndex(attr); @@ -72,14 +74,18 @@ markdownIt.renderer.rules.fence = (tokens, idx, options, env, slf) => { Note the line break contained inside a element. So we have to split by lines THEN syntax highlight. */ - let state = null; // state stores the current parse state of hljs, so that we can pass it on line by line + + // state stores the current parse state of hljs, so that we can pass it on line by line + let state = null; lines = str.split('\n').map((line) => { const highlightedLine = hljs.highlight(lang, line, true, state); state = highlightedLine.top; return highlightedLine.value; }); highlighted = true; - } catch (_) {} + } catch (ex) { + logger.error(`Error processing code block line ${ex}`); + } } if (!highlighted) { lines = markdownIt.utils.escapeHtml(str).split('\n'); @@ -107,7 +113,7 @@ markdownIt.renderer.rules.fence = (tokens, idx, options, env, slf) => { // wrap all lines with so we can number them str = lines.map((line, index) => { const currentLineNumber = index + 1; - const rule = highlightRules.find(rule => rule.shouldApplyHighlight(currentLineNumber)) + const rule = highlightRules.find(highlightRule => highlightRule.shouldApplyHighlight(currentLineNumber)); if (rule) { return rule.applyHighlight(line); } @@ -125,7 +131,9 @@ markdownIt.renderer.rules.fence = (tokens, idx, options, env, slf) => { const codeBlockContent = `
${str}
`; if (heading) { const renderedHeading = markdownIt.renderInline(heading); - const headingStyle = (renderedHeading === heading) ? 'code-block-heading' : 'code-block-heading inline-markdown-heading'; + const headingStyle = (renderedHeading === heading) + ? 'code-block-heading' + : 'code-block-heading inline-markdown-heading'; return '
' + `
${renderedHeading}
` + `
${codeBlockContent}
` @@ -138,24 +146,23 @@ markdownIt.renderer.rules.fence = (tokens, idx, options, env, slf) => { markdownIt.renderer.rules.code_inline = (tokens, idx, options, env, slf) => { const token = tokens[idx]; const lang = token.attrGet('class'); - const inlineClass = `hljs inline`; + const inlineClass = 'hljs inline'; if (lang && hljs.getLanguage(lang)) { token.attrSet('class', `${inlineClass} ${lang}`); - return '' - + hljs.highlight(lang, token.content, true).value - + ''; - } else { - token.attrSet('class', `${inlineClass} no-lang`); - return '' - + markdownIt.utils.escapeHtml(token.content) - + ''; + return `${ + hljs.highlight(lang, token.content, true).value + }`; } + token.attrSet('class', `${inlineClass} no-lang`); + return `${ + markdownIt.utils.escapeHtml(token.content) + }`; }; const fixedNumberEmojiDefs = require('./patches/markdown-it-emoji-fixed'); markdownIt.use(require('markdown-it-emoji'), { - defs: fixedNumberEmojiDefs + defs: fixedNumberEmojiDefs, }); module.exports = markdownIt; diff --git a/packages/core/src/lib/markdown-it/plugins/markdown-it-icons.js b/packages/core/src/lib/markdown-it/plugins/markdown-it-icons.js index 96dde1dcf2..3ee154a89c 100644 --- a/packages/core/src/lib/markdown-it/plugins/markdown-it-icons.js +++ b/packages/core/src/lib/markdown-it/plugins/markdown-it-icons.js @@ -1,32 +1,31 @@ const octicons = require('@primer/octicons'); module.exports = require('markdown-it-regexp')( - /:(fa[brs]|glyphicon|octicon|octiconlight)-([a-z-]+)~?([a-z-]+)?:/, - (match, _) => { - let iconFontType = match[1]; - let iconFontName = match[2]; - let iconClass = match[3]; + /:(fa[brs]|glyphicon|octicon|octiconlight)-([a-z-]+)~?([a-z-]+)?:/, + (match) => { + const iconFontType = match[1]; + const iconFontName = match[2]; + const iconClass = match[3]; - if (iconFontType === 'glyphicon') { - return ``; - } else if (iconFontType === 'octicon') { - // ensure octicons are valid - if (!octicons.hasOwnProperty(iconFontName)) { - return ``; - } - return iconClass - ? octicons[iconFontName].toSVG({"class": iconClass}) - : octicons[iconFontName].toSVG(); - } else if (iconFontType === 'octiconlight') { - // ensure octicons are valid - if (!octicons.hasOwnProperty(iconFontName)) { - return ``; - } - return iconClass - ? octicons[iconFontName].toSVG({"style": "color: #fff;", "class": iconClass}) - : octicons[iconFontName].toSVG({"style": "color: #fff;"}); - } else { // If icon is a Font Awesome icon - return ``; - } - } + if (iconFontType === 'glyphicon') { + return ``; + } else if (iconFontType === 'octicon') { + // ensure octicons are valid + if (!(iconFontName in octicons)) { + return ''; + } + return iconClass + ? octicons[iconFontName].toSVG({ class: iconClass }) + : octicons[iconFontName].toSVG(); + } else if (iconFontType === 'octiconlight') { + // ensure octicons are valid + if (!(iconFontName in octicons)) { + return ''; + } + return iconClass + ? octicons[iconFontName].toSVG({ style: 'color: #fff;', class: iconClass }) + : octicons[iconFontName].toSVG({ style: 'color: #fff;' }); + } // If icon is a Font Awesome icon + return ``; + }, );