From 275c6d9f9f1b2a179227b42fee82748537f35d77 Mon Sep 17 00:00:00 2001 From: christophe geiser Date: Fri, 23 Aug 2024 18:01:58 +0200 Subject: [PATCH] feat: add raw to HeadingData (#579) * feat: add raw to HeadingData This is to simplify handling of heading text for cases like: `## [linked title](./link)` (text is going to be `linked title`, but you would like to consume just `linked title`) * added test and modified README * test: added a test for upper case --- README.md | 3 ++- lib/index.cjs | 2 +- lib/index.umd.js | 2 +- spec/index.test.js | 26 +++++++++++++++++++++++--- src/index.d.ts | 1 + src/index.js | 5 ++--- 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 86164a4..8312640 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ marked("# heading"); The headings will each be an object with the following properties: - `text`: The rendered HTML for the heading - `level`: The heading level (1-7) + - `raw`: The raw text (stripped of HTML rendering if any; this is usefull for situation like `marked("# [heading](./link)");`) - `id`: The id given to the heading including any prefix ```js @@ -42,7 +43,7 @@ marked.use(gfmHeadingId({prefix: "my-prefix-"}), { return ` ${html}`; } diff --git a/lib/index.cjs b/lib/index.cjs index 5ca8f96..ad44903 100644 --- a/lib/index.cjs +++ b/lib/index.cjs @@ -122,7 +122,7 @@ function gfmHeadingId({ prefix = '', globalSlugs = false } = {}) { .replace(/<[!\/a-z].*?>/gi, ''); const level = depth; const id = `${prefix}${slugger.slug(raw)}`; - const heading = { level, text, id }; + const heading = { level, text, id, raw }; headings.push(heading); return `${text}\n`; diff --git a/lib/index.umd.js b/lib/index.umd.js index 18f4391..3e95479 100644 --- a/lib/index.umd.js +++ b/lib/index.umd.js @@ -126,7 +126,7 @@ .replace(/<[!\/a-z].*?>/gi, ''); const level = depth; const id = `${prefix}${slugger.slug(raw)}`; - const heading = { level, text, id }; + const heading = { level, text, id, raw }; headings.push(heading); return `${text}\n`; diff --git a/spec/index.test.js b/spec/index.test.js index 1b6cc18..e814736 100644 --- a/spec/index.test.js +++ b/spec/index.test.js @@ -103,6 +103,8 @@ describe('marked-gfm-heading-id', () => { # Hello **world!** # Hello world! + +# just Capspaces `; expect(marked(markdown)).toMatchInlineSnapshot(` @@ -124,30 +126,48 @@ describe('marked-gfm-heading-id', () => {

comment

Hello world!

Hello world!

+

just Capspaces

" `); - expect(headings.length).toBe(18); + expect(headings.length).toBe(19); expect(headings[0].id).toBe('foo-1'); + expect(headings[0].raw).toBe('foo 1'); expect(headings[1].id).toBe('foo'); + expect(headings[1].raw).toBe('foo'); expect(headings[2].id).toBe('foo-2'); + expect(headings[2].raw).toBe('foo'); expect(headings[3].id).toBe('html-in-header'); + expect(headings[3].raw).toBe('Html in header'); expect(headings[4].id).toBe('just-test'); + expect(headings[4].raw).toBe('just test'); expect(headings[5].id).toBe('just-test-2'); - + expect(headings[5].raw).toBe('just test 2'); expect(headings[6].id).toBe('just--test-2-spaces-'); + expect(headings[6].raw).toBe('just test 2 spaces '); expect(headings[7].id).toBe('just-test-3'); + expect(headings[7].raw).toBe('just test 3'); expect(headings[8].id).toBe('just-test-4'); + expect(headings[8].raw).toBe('just test 4'); expect(headings[9].id).toBe('just-non-tags'); + expect(headings[9].raw).toBe('just non tags'); expect(headings[10].id).toBe('just-spaces'); - + expect(headings[10].raw).toBe('just spaces'); expect(headings[11].id).toBe('just--weird-chars'); + expect(headings[11].raw).toBe('just #$% weird chars'); expect(headings[12].id).toBe('followed-by-weird-chars'); + expect(headings[12].raw).toBe('followed by#$% weird chars'); expect(headings[13].id).toBe('followed--space-then-weird-chars'); + expect(headings[13].raw).toBe('followed space then weird chars'); expect(headings[14].id).toBe(''); expect(headings[15].id).toBe('comment-'); + expect(headings[15].raw).toBe('comment '); expect(headings[16].id).toBe('hello-world'); + expect(headings[16].raw).toBe('Hello world!'); expect(headings[17].id).toBe('hello-world-1'); + expect(headings[17].raw).toBe('Hello world!'); + expect(headings[18].id).toBe('just-capspaces'); + expect(headings[18].raw).toBe('just Capspaces'); }); test('globalSlugs usage - No Clearing.', () => { diff --git a/src/index.d.ts b/src/index.d.ts index bca7a79..ea29f53 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -22,6 +22,7 @@ export function gfmHeadingId(options?: GfmHeadingIdOptions): MarkedExtension; export interface HeadingData { level: number; text: string; + raw: string; id: string; } diff --git a/src/index.js b/src/index.js index c7bedf4..28a45e7 100644 --- a/src/index.js +++ b/src/index.js @@ -36,12 +36,11 @@ export function gfmHeadingId({ prefix = '', globalSlugs = false } = {}) { heading({ tokens, depth }) { const text = this.parser.parseInline(tokens); const raw = unescape(this.parser.parseInline(tokens, this.parser.textRenderer)) - .toLowerCase() .trim() .replace(/<[!\/a-z].*?>/gi, ''); const level = depth; - const id = `${prefix}${slugger.slug(raw)}`; - const heading = { level, text, id }; + const id = `${prefix}${slugger.slug(raw.toLowerCase())}`; + const heading = { level, text, id, raw }; headings.push(heading); return `${text}\n`;