diff --git a/lib/index.cjs b/lib/index.cjs
index 64fcf0c..e6a6f46 100644
--- a/lib/index.cjs
+++ b/lib/index.cjs
@@ -82,22 +82,37 @@ function slug (value, maintainCase) {
let slugger;
+let headings = [];
+
function gfmHeadingId({ prefix = '' } = {}) {
return {
headerIds: false, // prevent deprecation warning; remove this once headerIds option is removed
hooks: {
preprocess(src) {
+ headings = [];
slugger = new BananaSlug();
return src;
}
},
renderer: {
heading(text, level, raw) {
- raw = raw.toLowerCase().trim().replace(/<[!\/a-z].*?>/ig, '');
- return `${text}\n`;
+ raw = raw
+ .toLowerCase()
+ .trim()
+ .replace(/<[!\/a-z].*?>/gi, '');
+ const id = `${prefix}${slugger.slug(raw)}`;
+ const heading = { level, text, id };
+ headings.push(heading);
+
+ return `${text}\n`;
}
}
};
}
+function getHeadingList() {
+ return headings;
+}
+
+exports.getHeadingList = getHeadingList;
exports.gfmHeadingId = gfmHeadingId;
diff --git a/lib/index.umd.js b/lib/index.umd.js
index b09f4cb..af1f244 100644
--- a/lib/index.umd.js
+++ b/lib/index.umd.js
@@ -86,24 +86,39 @@
let slugger;
+ let headings = [];
+
function gfmHeadingId({ prefix = '' } = {}) {
return {
headerIds: false, // prevent deprecation warning; remove this once headerIds option is removed
hooks: {
preprocess(src) {
+ headings = [];
slugger = new BananaSlug();
return src;
}
},
renderer: {
heading(text, level, raw) {
- raw = raw.toLowerCase().trim().replace(/<[!\/a-z].*?>/ig, '');
- return `${text}\n`;
+ raw = raw
+ .toLowerCase()
+ .trim()
+ .replace(/<[!\/a-z].*?>/gi, '');
+ const id = `${prefix}${slugger.slug(raw)}`;
+ const heading = { level, text, id };
+ headings.push(heading);
+
+ return `${text}\n`;
}
}
};
}
+ function getHeadingList() {
+ return headings;
+ }
+
+ exports.getHeadingList = getHeadingList;
exports.gfmHeadingId = gfmHeadingId;
}));
diff --git a/spec/index.test.js b/spec/index.test.js
index 7312789..c469a37 100644
--- a/spec/index.test.js
+++ b/spec/index.test.js
@@ -1,5 +1,5 @@
import { marked } from 'marked';
-import { gfmHeadingId } from '../src/index.js';
+import { getHeadingList, gfmHeadingId } from '../src/index.js';
describe('marked-gfm-heading-id', () => {
beforeEach(() => {
@@ -57,7 +57,16 @@ describe('marked-gfm-heading-id', () => {
});
test('weird headings', () => {
- marked.use(gfmHeadingId());
+ let headings = [];
+ marked.use(gfmHeadingId(), {
+ hooks: {
+ postprocess(html) {
+ headings = getHeadingList();
+ return html;
+ }
+ }
+ });
+
const markdown = `
# foo 1
@@ -117,5 +126,27 @@ describe('marked-gfm-heading-id', () => {
Hello world!
"
`);
+
+ expect(headings.length).toBe(18);
+ expect(headings[0].id).toBe('foo-1');
+ expect(headings[1].id).toBe('foo');
+ expect(headings[2].id).toBe('foo-2');
+ expect(headings[3].id).toBe('html-in-header');
+ expect(headings[4].id).toBe('just-test');
+ expect(headings[5].id).toBe('just-test-2');
+
+ expect(headings[6].id).toBe('just--test-2-spaces-');
+ expect(headings[7].id).toBe('just-test-3');
+ expect(headings[8].id).toBe('just-test-4');
+ expect(headings[9].id).toBe('just-non-tags');
+ expect(headings[10].id).toBe('just-spaces');
+
+ expect(headings[11].id).toBe('just--weird-chars');
+ expect(headings[12].id).toBe('followed-by-weird-chars');
+ expect(headings[13].id).toBe('followed--space-then-weird-chars');
+ expect(headings[14].id).toBe('');
+ expect(headings[15].id).toBe('comment-');
+ expect(headings[16].id).toBe('hello-world');
+ expect(headings[17].id).toBe('hello-world-1');
});
});
diff --git a/src/index.d.ts b/src/index.d.ts
index 0feaa6b..4ea422a 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -1,4 +1,4 @@
-import type { MarkedExtension, marked } from "marked"
+import type {MarkedExtension, marked} from 'marked';
/** Options for configuring marked-gfm-heading-id extension */
interface GfmHeadingIdOptions {
@@ -10,6 +10,25 @@ interface GfmHeadingIdOptions {
* Add `id` attribute to headings (h1, h2, h3, etc) like GitHub.
*
* @param options Options for the extension
- * @returns A {@link marked.MarkedExtension | MarkedExtension} to be passed to {@link marked.use | `marked.use()`}
+ * @returns A {@link marked.MarkedExtension | MarkedExtension} to be passed
+ * to {@link marked.use | `marked.use()`}
*/
export function gfmHeadingId(options?: GfmHeadingIdOptions): MarkedExtension;
+
+/**
+ * Headings information, can be used to create table of content
+ */
+export interface HeadingData {
+ level: number;
+ text: string;
+ id: string;
+}
+
+/**
+ * Returns a list of headings with the ids as computed by gfmHeadingId
+ *
+ * @param tokens a lexer output
+ * @param options Options for the extension
+ * @returns A string formatted the same as what would {@link gfmHeadingId} do.
+ */
+export function getHeadingList(): HeadingData[];
diff --git a/src/index.js b/src/index.js
index bce6dd2..aa6f12b 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,20 +1,34 @@
import GithubSlugger from 'github-slugger';
let slugger;
+let headings = [];
+
export function gfmHeadingId({ prefix = '' } = {}) {
return {
headerIds: false, // prevent deprecation warning; remove this once headerIds option is removed
hooks: {
preprocess(src) {
+ headings = [];
slugger = new GithubSlugger();
return src;
}
},
renderer: {
heading(text, level, raw) {
- raw = raw.toLowerCase().trim().replace(/<[!\/a-z].*?>/ig, '');
- return `${text}\n`;
+ raw = raw
+ .toLowerCase()
+ .trim()
+ .replace(/<[!\/a-z].*?>/gi, '');
+ const id = `${prefix}${slugger.slug(raw)}`;
+ const heading = { level, text, id };
+ headings.push(heading);
+
+ return `${text}\n`;
}
}
};
}
+
+export function getHeadingList() {
+ return headings;
+}