From 837008b7dd8633aee2484e01d3b85e1e0cf66c26 Mon Sep 17 00:00:00 2001
From: Cerallin <66366855+Cerallin@users.noreply.github.com>
Date: Sat, 29 Jan 2022 13:23:21 +0800
Subject: [PATCH] feat(toc_obj): Support unnumbered headings (#269)
* feat(toc_obj): Support unnumbered headings
* Update readme
* Rollback TOC
* Fix typo
* Fix lint
---
README.md | 9 ++++++++-
lib/toc_obj.js | 12 +++++++++++-
test/toc_obj.spec.js | 14 ++++++++++++++
3 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 58350c3d..a4e55a60 100644
--- a/README.md
+++ b/README.md
@@ -544,7 +544,7 @@ wordWrap('Once upon a time', {width: 1})
### tocObj(str, [options])
-Generate a table of contents in JSON format based on the given html string.
+Generate a table of contents in JSON format based on the given html string. Headings with attribute `data-toc-unnumbered="true"` will be marked as unnumbered.
Option | Description | Default
--- | --- | ---
@@ -601,6 +601,13 @@ tocObj(html, { max_depth: 2 });
{ text: 'Title 2.1', id: 'title_2_1', level: 2 },
]
*/
+
+tocObj('
Reference
')
+/*
+[
+ { text: 'Reference', id: 'reference', level: 1, unnumbered: true }
+]
+*/
```
### truncate(str, [options])
diff --git a/lib/toc_obj.js b/lib/toc_obj.js
index f5164a4c..29da241c 100644
--- a/lib/toc_obj.js
+++ b/lib/toc_obj.js
@@ -13,6 +13,13 @@ const getId = ({ attribs = {}, parent }) => {
return attribs.id || (!parent ? '' : getId(parent));
};
+/**
+ * Identify a heading that to be unnumbered or not.
+ */
+const isUnnumbered = ({ attribs = {} }) => {
+ return attribs['data-toc-unnumbered'] === 'true';
+};
+
function tocObj(str, options = {}) {
const { min_depth, max_depth } = Object.assign({
min_depth: 1,
@@ -31,6 +38,7 @@ function tocObj(str, options = {}) {
const el = headings[i];
const level = +el.name[1];
const id = getId(el);
+ const unnumbered = isUnnumbered(el);
let text = '';
for (const element of el.children) {
const elText = DomUtils.getText(element);
@@ -43,7 +51,9 @@ function tocObj(str, options = {}) {
}
if (!text) text = escapeHTML(DomUtils.getText(el));
- result.push({ text, id, level });
+ const res = { text, id, level };
+ if (unnumbered) res.unnumbered = true;
+ result.push(res);
}
return result;
diff --git a/test/toc_obj.spec.js b/test/toc_obj.spec.js
index 96614e30..07665eeb 100644
--- a/test/toc_obj.spec.js
+++ b/test/toc_obj.spec.js
@@ -165,5 +165,19 @@ describe('tocObj', () => {
result.forEach(str => str[0].text.should.eql('foobarbaz'));
});
+
+ it('unnumbered headings', () => {
+ const input = [
+ 'Title 1
',
+ 'Title 2
'
+ ].join('');
+
+ const expected = [
+ { text: 'Title 1', id: 'title_1', level: 1, unnumbered: true },
+ { text: 'Title 2', id: 'title_2', level: 2 }
+ ];
+
+ tocObj(input).should.eql(expected);
+ });
});
});