Skip to content

Commit

Permalink
fix(tocObj): skip permalink symbol
Browse files Browse the repository at this point in the history
  • Loading branch information
curbengh committed Feb 23, 2020
1 parent 7e5633a commit 6b18598
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 1 deletion.
12 changes: 11 additions & 1 deletion lib/toc_obj.js
@@ -1,6 +1,7 @@
'use strict';
const { DomHandler, DomUtils, Parser } = require('htmlparser2');
const escapeHTML = require('./escape_html');
const nonWord = /^\s*[^a-zA-Z0-9]\s*$/;

const parseHtml = html => {
const handler = new DomHandler(null, {});
Expand Down Expand Up @@ -30,7 +31,16 @@ function tocObj(str, options = {}) {
const el = headings[i];
const level = +el.name[1];
const id = getId(el);
const text = escapeHTML(DomUtils.getText(el));
let text = '';
for (const element of el.children) {
const elText = DomUtils.getText(element);
// Skip permalink symbol
// permalink is a single non-word character, word = [a-Z0-9]
// permalink may be wrapped in whitespace(s)
if (element.name !== 'a' || !nonWord.test(elText)) {
text += escapeHTML(elText);
}
}

result.push({ text, id, level });
}
Expand Down
69 changes: 69 additions & 0 deletions test/toc_obj.spec.js
Expand Up @@ -87,4 +87,73 @@ describe('tocObj', () => {

result.length.should.eql(0);
});

it('empty text', () => {
const input = '<h1></h1>';
const result = tocObj(input);

result[0].text.should.eql('');
});

describe('children element', () => {
it('<a> element with permalink + text', () => {
const input = [
'<h1><a>#</a>foo</h1>',
'<h1>foo<a>#</a></h1>',
'<h1><a>#</a>foo<a>#</a></h1>',
'<h1><a># </a>foo</h1>',
'<h1><a># </a>foo<a> #</a></h1>',
'<h1><a>号</a>foo</h1>'
];
const result = input.map(str => tocObj(str));

result.forEach(str => str[0].text.should.eql('foo'));
});

it('<a> element - no text', () => {
const input = '<h1><a>foo</a></h1>';
const result = tocObj(input);

result[0].text.should.eql('foo');
});

it('non-permalink <a> element + text', () => {
const input = [
'<h1><a>foo</a>bar</h1>',
'<h1>foo<a>bar</a></h1>'
];
const result = input.map(str => tocObj(str));

result.forEach(str => str[0].text.should.eql('foobar'));
});

it('non-permalink <a> element + unicode text', () => {
const input = [
'<h1><a>这是</a>测试</h1>',
'<h1>这是<a>测试</a></h1>'
];
const result = input.map(str => tocObj(str));

result.forEach(str => str[0].text.should.eql('这是测试'));
});

it('multiple <a> elements', () => {
const input = '<h1><a>foo</a><a>bar</a></h1>';
const result = tocObj(input);

result[0].text.should.eql('foobar');
});

it('element + text', () => {
const input = [
'<h1><i>foo</i>barbaz</h1>',
'<h1><i>foo</i>bar</i>baz</h1>',
'<h1>foo<i>bar</i>baz</h1>',
'<h1>foobarba<i>z</i></h1>'
];
const result = input.map(str => tocObj(str));

result.forEach(str => str[0].text.should.eql('foobarbaz'));
});
});
});

0 comments on commit 6b18598

Please sign in to comment.