Skip to content

Commit

Permalink
rewrite changes as new feature to prevent breaking changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Simek committed Jul 27, 2020
1 parent 532dc50 commit 159c152
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 18 deletions.
7 changes: 7 additions & 0 deletions docs/api-site-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,10 @@ Set this to `true` if you want to enable the scroll to top button at the bottom

Optional options configuration for the scroll to top button. You do not need to use this, even if you set `scrollToTop` to `true`; it just provides you more configuration control of the button. You can find more options [here](https://github.com/vfeskov/vanilla-back-to-top/blob/v7.1.14/OPTIONS.md). By default, we set the zIndex option to 100.

#### `slugPreprocessor` [function]

Define the slug preprocessor function if you want to customize the text used for generating the hash links. Function provides the base string as the first argument and must always return a string.

#### `stylesheets` [array]

An array of CSS sources to load. The values can be either strings or plain objects of attribute-value maps. The link tag will be inserted in the HTML head.
Expand Down Expand Up @@ -463,6 +467,9 @@ const siteConfig = {
scrollToTopOptions: {
zIndex: 100,
},
// Remove the HTML tags and HTML tags content before generating the slug
slugPreprocessor: (slugBase) =>
slugBase.replace(/<([^>]+?)([^>]*?)>(.*?)<\/\1>/gi, ''),
};

module.exports = siteConfig;
Expand Down
14 changes: 12 additions & 2 deletions packages/docusaurus-1.x/lib/core/__tests__/toc.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ describe('getTOC', () => {
test('html tag in source', () => {
const headings = getTOC(`## <a name="foo"></a> Foo`, 'h2', []);

expect(headings[0].hashLink).toEqual('foo');
expect(headings[0].hashLink).toEqual('a-namefooa-foo');
expect(headings[0].rawContent).toEqual(`<a name="foo"></a> Foo`);
expect(headings[0].content).toEqual(`<a name="foo"></a> Foo`);
});

test('transform markdown syntax to html syntax', () => {
const headings = getTOC(`## <a name="foo"></a> _Foo_`, 'h2', []);

expect(headings[0].hashLink).toEqual('_foo_');
expect(headings[0].hashLink).toEqual('a-namefooa-_foo_');
expect(headings[0].rawContent).toEqual(`<a name="foo"></a> _Foo_`);
expect(headings[0].content).toEqual(`<a name="foo"></a> <em>Foo</em>`);

Expand All @@ -69,6 +69,16 @@ describe('getTOC', () => {
expect(headings[0].rawContent).toEqual(`function1 [array<string>]`);
expect(headings[0].content).toEqual(`function1 [array<string>]`);
});

test('test slugPreprocessor', () => {
const headings = getTOC(`## <a name="foo"></a> Foo`, 'h2', [], (s) =>
s.replace(/foo/gi, 'bar'),
);

expect(headings[0].hashLink).toEqual('a-namebara-bar');
expect(headings[0].rawContent).toEqual(`<a name="foo"></a> Foo`);
expect(headings[0].content).toEqual(`<a name="foo"></a> Foo`);
});
});

describe('insertTOC', () => {
Expand Down
11 changes: 6 additions & 5 deletions packages/docusaurus-1.x/lib/core/anchors.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const toSlug = require('./toSlug');
/**
* The anchors plugin adds GFM-style anchors to headings.
*/
function anchors(md) {
function anchors(md, slugPreprocessor) {
const originalRender = md.renderer.rules.heading_open;

md.renderer.rules.heading_open = function (tokens, idx, options, env) {
Expand All @@ -22,10 +22,11 @@ function anchors(md) {
const textToken = tokens[idx + 1];

if (textToken.content) {
const anchor = toSlug(
textToken.content.replace(/<([^>]+?)([^>]*?)>(.*?)<\/\1>/gi, ''),
slugger,
);
const slugBase =
slugPreprocessor && typeof slugPreprocessor === 'function'
? slugPreprocessor(textToken.content)
: textToken.content;
const anchor = toSlug(slugBase, slugger);
return `<h${tokens[idx].hLevel}><a class="anchor" aria-hidden="true" id="${anchor}"></a><a href="#${anchor}" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>`;
}

Expand Down
14 changes: 12 additions & 2 deletions packages/docusaurus-1.x/lib/core/nav/OnPageNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,18 @@ class OnPageNav extends React.Component {
render() {
const customTags = siteConfig.onPageNavHeadings;
const headings = customTags
? getTOC(this.props.rawContent, customTags.topLevel, customTags.sub)
: getTOC(this.props.rawContent);
? getTOC(
this.props.rawContent,
customTags.topLevel,
customTags.sub,
siteConfig.slugPreprocessor,
)
: getTOC(
this.props.rawContent,
undefined,
undefined,
siteConfig.slugPreprocessor,
);

return <Headings headings={headings} />;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-1.x/lib/core/renderMarkdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class MarkdownRenderer {
const md = new Markdown(markdownOptions);

// Register anchors plugin
md.use(anchors);
md.use(anchors, siteConfig.slugPreprocessor);

// Linkify
md.use(linkify);
Expand Down
20 changes: 13 additions & 7 deletions packages/docusaurus-1.x/lib/core/toc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ const tocRegex = new RegExp('<AUTOGENERATED_TABLE_OF_CONTENTS>', 'i');
* Array of heading objects with `hashLink`, `content` and `children` fields
*
*/
function getTOC(content, headingTags = 'h2', subHeadingTags = 'h3') {
function getTOC(
content,
headingTags = 'h2',
subHeadingTags = 'h3',
slugPreprocessor = undefined,
) {
const tagToLevel = (tag) => Number(tag.slice(1));
const headingLevels = [].concat(headingTags).map(tagToLevel);
const subHeadingLevels = subHeadingTags
Expand All @@ -38,10 +43,11 @@ function getTOC(content, headingTags = 'h2', subHeadingTags = 'h3') {
headings.forEach((heading) => {
const rawContent = heading.content;
const rendered = md.renderInline(rawContent);
const hashLink = toSlug(
rawContent.replace(/<([^>]+?)([^>]*?)>(.*?)<\/\1>/gi, ''),
slugger,
);
const slugBase =
slugPreprocessor && typeof slugPreprocessor === 'function'
? slugPreprocessor(rawContent)
: rawContent;
const hashLink = toSlug(slugBase, slugger);
if (!allowedHeadingLevels.includes(heading.lvl)) {
return;
}
Expand All @@ -63,12 +69,12 @@ function getTOC(content, headingTags = 'h2', subHeadingTags = 'h3') {

// takes the content of a doc article and returns the content with a table of
// contents inserted
function insertTOC(rawContent) {
function insertTOC(rawContent, slugPreprocessor = undefined) {
if (!rawContent || !tocRegex.test(rawContent)) {
return rawContent;
}
const filterRe = /^`[^`]*`/;
const headers = getTOC(rawContent, 'h3', null);
const headers = getTOC(rawContent, 'h3', null, slugPreprocessor);
const tableOfContents = headers
.filter((header) => filterRe.test(header.rawContent))
.map((header) => ` - [${header.rawContent}](#${header.hashLink})`)
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-1.x/lib/server/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function mdToHtmlify(oldContent, mdToHtml, metadata, siteConfig) {

function getMarkup(rawContent, mdToHtml, metadata, siteConfig) {
// generate table of contents
let content = insertTOC(rawContent);
let content = insertTOC(rawContent, siteConfig.slugPreprocessor);

// replace any links to markdown files to their website html links
content = mdToHtmlify(content, mdToHtml, metadata, siteConfig);
Expand Down

0 comments on commit 159c152

Please sign in to comment.