Skip to content

Commit

Permalink
feat: add globalSlugs option (#543)
Browse files Browse the repository at this point in the history
Co-authored-by: Tony Brix <tony@brix.ninja>
Co-authored-by: David Bolack <dbolack@gmail.com>
  • Loading branch information
3 people committed Jun 10, 2024
1 parent 6644f42 commit 41da687
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 16 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,14 @@ marked("# heading");
// <h1 id="my-prefix-heading">heading</h1>
```

## Clear Heading List

`resetHeadings` is a function to purge the stored list of headings and reset the Slugger. This is only needed when the globalSlugs option ( see below) is set to true and you wish to reset the slugger and exportable Headers list.

## `options`

| option | type | default | description |
|--------|--------|---------|:--------------------------------|
| prefix | string | `""` | A string to prepend to all ids. |
| option | type | default | description |
|-------------|--------|---------|:----------------------------------------------|
| prefix | string | `""` | A string to prepend to all ids. |
| globalSlugs | bool | `false` | Track ids from one use of marked to the next. This ensures unique headers when parsing multiple markdown fragments and rendering the results as a single document. When set to false, the slugger and headers lists are cleared on every marked run.

17 changes: 13 additions & 4 deletions lib/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -80,22 +80,25 @@ function slug (value, maintainCase) {
return value.replace(regex, '').replace(/ /g, '-')
}

let slugger;
let slugger = new BananaSlug();

let headings = [];

function gfmHeadingId({ prefix = '' } = {}) {
function gfmHeadingId({ prefix = '', globalSlugs = false } = {}) {
return {
headerIds: false, // prevent deprecation warning; remove this once headerIds option is removed
hooks: {
preprocess(src) {
headings = [];
slugger = new BananaSlug();
if (!globalSlugs) {
headings = [];
slugger = new BananaSlug();
}
return src;
}
},
renderer: {
heading(text, level, raw) {
console.log('Updated code Again!');
raw = raw
.toLowerCase()
.trim()
Expand All @@ -114,5 +117,11 @@ function getHeadingList() {
return headings;
}

function resetHeadings() {
headings = [];
slugger = new BananaSlug();
}

exports.getHeadingList = getHeadingList;
exports.gfmHeadingId = gfmHeadingId;
exports.resetHeadings = resetHeadings;
17 changes: 13 additions & 4 deletions lib/index.umd.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,25 @@
return value.replace(regex, '').replace(/ /g, '-')
}

let slugger;
let slugger = new BananaSlug();

let headings = [];

function gfmHeadingId({ prefix = '' } = {}) {
function gfmHeadingId({ prefix = '', globalSlugs = false } = {}) {
return {
headerIds: false, // prevent deprecation warning; remove this once headerIds option is removed
hooks: {
preprocess(src) {
headings = [];
slugger = new BananaSlug();
if (!globalSlugs) {
headings = [];
slugger = new BananaSlug();
}
return src;
}
},
renderer: {
heading(text, level, raw) {
console.log('Updated code Again!');
raw = raw
.toLowerCase()
.trim()
Expand All @@ -118,7 +121,13 @@
return headings;
}

function resetHeadings() {
headings = [];
slugger = new BananaSlug();
}

exports.getHeadingList = getHeadingList;
exports.gfmHeadingId = gfmHeadingId;
exports.resetHeadings = resetHeadings;

}));
95 changes: 94 additions & 1 deletion spec/index.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { marked } from 'marked';
import { getHeadingList, gfmHeadingId } from '../src/index.js';
import { getHeadingList, gfmHeadingId, resetHeadings } from '../src/index.js';

describe('marked-gfm-heading-id', () => {
beforeEach(() => {
Expand Down Expand Up @@ -149,4 +149,97 @@ describe('marked-gfm-heading-id', () => {
expect(headings[16].id).toBe('hello-world');
expect(headings[17].id).toBe('hello-world-1');
});

test('globalSlugs usage - No Clearing.', () => {
marked.use(gfmHeadingId({ globalSlugs: true }));
const markdownOne = `
# foo 1
# foo
# foo
`;
const markdownTwo = `
# foo 1
# foo
# foo
`;
expect(marked(markdownOne)).toMatchInlineSnapshot(`
"<h1 id="foo-1-1">foo 1</h1>
<h1 id="foo-3">foo</h1>
<h1 id="foo-4">foo</h1>
"
`);
expect(marked(markdownTwo)).toMatchInlineSnapshot(`
"<h1 id="foo-1-2">foo 1</h1>
<h1 id="foo-5">foo</h1>
<h1 id="foo-6">foo</h1>
"
`);
});

test('globalSlugs usage - Pre-Clearing.', () => {
resetHeadings();
marked.use(gfmHeadingId({ globalSlugs: true }));
const markdownOne = `
# foo 1
# foo
# foo
`;
const markdownTwo = `
# foo 1
# foo
# foo
`;
expect(marked(markdownOne)).toMatchInlineSnapshot(`
"<h1 id="foo-1">foo 1</h1>
<h1 id="foo">foo</h1>
<h1 id="foo-2">foo</h1>
"
`);
expect(marked(markdownTwo)).toMatchInlineSnapshot(`
"<h1 id="foo-1-1">foo 1</h1>
<h1 id="foo-3">foo</h1>
<h1 id="foo-4">foo</h1>
"
`);
});

test('globalSlugs usage - Pre and middle clearing.', () => {
resetHeadings();
marked.use(gfmHeadingId({ globalSlugs: true }));
const markdownOne = `
# foo 1
# foo
# foo
`;
const markdownTwo = `
# foo 1
# foo
# foo
`;
expect(marked(markdownOne)).toMatchInlineSnapshot(`
"<h1 id="foo-1">foo 1</h1>
<h1 id="foo">foo</h1>
<h1 id="foo-2">foo</h1>
"
`);
resetHeadings();
expect(marked(markdownTwo)).toMatchInlineSnapshot(`
"<h1 id="foo-1">foo 1</h1>
<h1 id="foo">foo</h1>
<h1 id="foo-2">foo</h1>
"
`);
});
});
5 changes: 5 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,8 @@ export interface HeadingData {
* @returns A string formatted the same as what would {@link gfmHeadingId} do.
*/
export function getHeadingList(): HeadingData[];

/**
* Clears the stored list of Headings as computed by gfmHeadingId
*/
export function resetHeadings(): void;
14 changes: 10 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import GithubSlugger from 'github-slugger';
let slugger;
let slugger = new GithubSlugger();

let headings = [];

export function gfmHeadingId({ prefix = '' } = {}) {
export function gfmHeadingId({ prefix = '', globalSlugs = false } = {}) {
return {
headerIds: false, // prevent deprecation warning; remove this once headerIds option is removed
hooks: {
preprocess(src) {
headings = [];
slugger = new GithubSlugger();
if (!globalSlugs) {
resetHeadings();
}
return src;
}
},
Expand All @@ -32,3 +33,8 @@ export function gfmHeadingId({ prefix = '' } = {}) {
export function getHeadingList() {
return headings;
}

export function resetHeadings() {
headings = [];
slugger = new GithubSlugger();
}

0 comments on commit 41da687

Please sign in to comment.