diff --git a/package-lock.json b/package-lock.json index 0d7676b6..cc3b517f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8956,7 +8956,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { "version": "1.16.1", diff --git a/src/transform/md.ts b/src/transform/md.ts index 17ae57b9..245d17c6 100644 --- a/src/transform/md.ts +++ b/src/transform/md.ts @@ -110,15 +110,11 @@ function initParser(md: MarkdownIt, options: OptionsType, env: EnvType) { }; } -function initCompiler(md: MarkdownIt, options: OptionsType, env: EnvType<{termTokens?: Token[]}>) { +function initCompiler(md: MarkdownIt, options: OptionsType, env: EnvType) { const {needToSanitizeHtml = false, sanitizeOptions} = options; return (tokens: Token[]) => { - // TODO: define postprocess step on term plugin - const {termTokens = []} = env; - delete env.termTokens; - - const html = md.renderer.render([...tokens, ...termTokens], md.options, env); + const html = md.renderer.render(tokens, md.options, env); return needToSanitizeHtml ? sanitizeHtml(html, sanitizeOptions) : html; }; diff --git a/src/transform/plugins/term/termDefinitions.ts b/src/transform/plugins/term/termDefinitions.ts index a8ab772b..25c127be 100644 --- a/src/transform/plugins/term/termDefinitions.ts +++ b/src/transform/plugins/term/termDefinitions.ts @@ -37,7 +37,6 @@ export function termDefinitions(md: MarkdownIt, options: MarkdownItPluginOpts) { const newLineReg = new RegExp(/^(\r\n|\r|\n)/); const termReg = new RegExp(/^\[\*(\w+)\]:/); - let currentLine = startLine; // Allow multiline term definition @@ -74,7 +73,16 @@ export function termDefinitions(md: MarkdownIt, options: MarkdownItPluginOpts) { return false; } - return processTermDefinition(md, options, state, currentLine, endLine, label, title); + return processTermDefinition( + md, + options, + state, + currentLine, + startLine, + endLine, + label, + title, + ); }; } @@ -83,6 +91,7 @@ function processTermDefinition( options: MarkdownItPluginOpts, state: StateBlock, currentLine: number, + startLine: number, endLine: number, label: string, title: string, @@ -121,32 +130,48 @@ function processTermDefinition( state.env.terms[':' + label] = title; } - const termNodes = []; - token = new state.Token('template_open', 'template', 1); + token.map = [startLine, currentLine + 1]; token.attrSet('id', ':' + label + '_template'); - termNodes.push(token); + token.attrSet('label', label); - token = new state.Token('term_open', 'dfn', 1); + state.tokens.push(token); + + token = new state.Token('dfn_open', 'dfn', 1); token.attrSet('class', 'yfm yfm-term_dfn'); token.attrSet('id', ':' + label + '_element'); token.attrSet('role', 'tooltip'); - termNodes.push(token); - termNodes.push(...md.parse(title, {})); + state.tokens.push(token); - token = new state.Token('term_close', 'dfn', -1); - termNodes.push(token); + const titleTokens = md.parse(title, state.env); - token = new state.Token('template_close', 'template', -1); - termNodes.push(token); + for (const titleToken of titleTokens) { + if (titleToken.children?.length) { + titleToken.content = ''; + } + + if (!titleToken.map) { + state.tokens.push(titleToken); + continue; + } - if (!state.env.termTokens) { - state.env.termTokens = []; + const [start, end] = titleToken.map; + + titleToken.map = [start + startLine, end + startLine]; + state.tokens.push(titleToken); } - state.env.termTokens.push(...termNodes); + token = new state.Token('dfn_close', 'dfn', -1); + + state.tokens.push(token); + + token = new state.Token('template_close', 'template', -1); + + state.tokens.push(token); + /** current line links to end of term definition */ state.line = currentLine + 1; + return true; } diff --git a/test/term.test.ts b/test/term.test.ts index 2699278f..6653365a 100644 --- a/test/term.test.ts +++ b/test/term.test.ts @@ -32,12 +32,11 @@ describe('Terms', () => { const input = readFileSync(inputPath, 'utf8'); const result = transformYfm(input, inputPath); - expect(clearRandomId(result)).toEqual( - '

Web

\n' + - '

The HTML specification

\n' + - '', - ); + expect(clearRandomId(result)).toEqual(`\ +

Web

+

The HTML specification

+`); }); test('Should create term in table with definition template', () => { @@ -45,25 +44,24 @@ describe('Terms', () => { const input = readFileSync(inputPath, 'utf8'); const result = transformYfm(input, inputPath); - expect(clearRandomId(result)).toEqual( - '

Web

\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '\n' + - '
LanguageInitial release
HTML1993
\n' + - '', - ); + expect(clearRandomId(result)).toEqual(`\ +

Web

+ + + + + + + + + + + + + +
LanguageInitial release
HTML1993
+`); }); test('Should create term in code with definition template', () => { @@ -71,49 +69,48 @@ describe('Terms', () => { const input = readFileSync(inputPath, 'utf8'); const result = transformYfm(input, inputPath); - expect(clearRandomId(result)).toEqual( - '

Web

\n' + - '\n' + - '
\n' + - '
HTML: Lorem\n' +
-                '
\n' + - '\n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - ' \n' + - '
\n' + - '', - ); + expect(clearRandomId(result)).toEqual(`\ +

Web

+ +
+
HTML: Lorem
+
+ + + + + + + + +
+`); }); test('Term should use content from include', () => { @@ -121,11 +118,10 @@ describe('Terms', () => { const input = readFileSync(inputPath, 'utf8'); const result = transformYfm(input, inputPath); - expect(clearRandomId(result)).toEqual( - '

Web

\n' + - '

The HTML specification

\n' + - '', - ); + expect(clearRandomId(result)).toEqual(`\ +

Web

+

The HTML specification

+`); }); });