From 8425cb23e1bc763856dd5afebf7098c024ae15cb Mon Sep 17 00:00:00 2001 From: Harsha Teja Kanna Date: Mon, 30 Sep 2024 00:36:09 -0400 Subject: [PATCH] Added link reference 'definition' token type --- lib/renderer.mjs | 2 +- lib/rules_block/reference.mjs | 15 +++++++- test/misc.mjs | 68 +++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/lib/renderer.mjs b/lib/renderer.mjs index a58914c..a3bd58b 100644 --- a/lib/renderer.mjs +++ b/lib/renderer.mjs @@ -187,7 +187,7 @@ Renderer.prototype.renderToken = function renderToken (tokens, idx, options) { // - a // > // - if (token.block && token.nesting !== -1 && idx && tokens[idx - 1].hidden) { + if (token.block && token.nesting !== -1 && idx && tokens[idx - 1].hidden && tokens[idx - 1].type !== 'definition') { result += '\n' } diff --git a/lib/rules_block/reference.mjs b/lib/rules_block/reference.mjs index 4166286..e1f994a 100644 --- a/lib/rules_block/reference.mjs +++ b/lib/rules_block/reference.mjs @@ -190,7 +190,8 @@ export default function reference (state, startLine, _endLine, silent) { return false } - const label = normalizeReference(str.slice(1, labelEnd)) + const label_raw = str.slice(1, labelEnd) + const label = normalizeReference(label_raw) if (!label) { // CommonMark 0.20 disallows empty labels return false @@ -208,5 +209,17 @@ export default function reference (state, startLine, _endLine, silent) { } state.line = nextLine + + const token = state.push('definition', '', 0) + token.meta = { + label: label_raw, + destination: href, + title + } + token.map = [startLine, state.line] + token.block = true + token.hidden = true + token.children = [] + return true } diff --git a/test/misc.mjs b/test/misc.mjs index 9c297e9..0e36c79 100644 --- a/test/misc.mjs +++ b/test/misc.mjs @@ -472,3 +472,71 @@ describe('Token attributes', function () { assert.strictEqual(t.attrGet('myattr'), 'myvalue') }) }) + +describe('Definition', function () { + function type_filter (tokens, type) { + return tokens.filter(function (t) { return t.type === type }) + } + + it('Should not render link reference definition', function () { + const md = markdownit() + + assert.strictEqual( + md.render('[foo]: /url "title"\n\n[foo]', {}), + '

foo

\n' + ) + }) + + it('Should not render newline after link reference definition', function () { + const md = markdownit() + + assert.strictEqual( + md.render('[foo]: /url "title"\nbar', {}), + '

bar

\n' + ) + }) + + it('Should add meta to link reference definition', function () { + const md = markdownit() + + let tokens = md.parse('[foo]: /url "title"\n\n[foo]', {}) + assert.strictEqual(type_filter(tokens, 'definition').length, 1) + tokens = type_filter(tokens, 'definition') + assert.deepEqual( + tokens[0].meta, + { label: 'foo', destination: '/url', title: 'title' } + ) + }) + + it('Should add sourcemap info to link reference definition token', function () { + const md = markdownit() + + let tokens = md.parse("[foo]: /url '\ntitle\nline1\nline2\n'\n\n[foo]", {}) + assert.strictEqual(type_filter(tokens, 'definition').length, 1) + tokens = type_filter(tokens, 'definition') + assert.deepEqual( + tokens[0].map, + [0, 5] + ) + assert.deepEqual( + tokens[0].meta, + { label: 'foo', destination: '/url', title: '\ntitle\nline1\nline2\n' } + ) + }) + + it('Empty link destination should be empty string in the link reference definition token', function () { + const md = markdownit() + + let tokens = md.parse('[foo]: <>\n\n[foo]', {}) + assert.strictEqual(type_filter(tokens, 'definition').length, 1) + tokens = type_filter(tokens, 'definition') + assert.deepEqual( + tokens[0].map, + [0, 1] + ) + assert.deepEqual( + tokens[0].meta, + { label: 'foo', destination: '', title: '' } + ) + }) +})