Skip to content

Commit e23dd3e

Browse files
committed
fix(vitepress): updated anchor slugs to correctly handle all use-cases (#725)
1 parent 843d93d commit e23dd3e

File tree

4 files changed

+41
-9
lines changed

4 files changed

+41
-9
lines changed

.changeset/grumpy-carrots-swim.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'typedoc-vitepress-theme': patch
3+
---
4+
5+
- Updated anchor slugs to correctly handle all use-cases.

packages/typedoc-vitepress-theme/src/index.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { DEFAULT_SIDEBAR_OPTIONS } from './options.js';
1414
import * as options from './options/declarations.js';
1515
import { presets } from './options/presets.js';
1616
import { getSidebar } from './sidebars/sidebars.js';
17+
import { slugifyAnchor } from './utils/utils.js';
1718

1819
export function load(app: MarkdownApplication) {
1920
Object.entries(options).forEach(([name, option]) => {
@@ -74,12 +75,3 @@ export function load(app: MarkdownApplication) {
7475
}
7576
});
7677
}
77-
78-
function slugifyAnchor(anchor: string) {
79-
return anchor
80-
.toLowerCase()
81-
.trim()
82-
.replace(/[^\w\s-]/g, '')
83-
.replace(/[\s_-]+/g, '-')
84-
.replace(/^-+|-+$/g, '');
85-
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { slugifyAnchor } from './utils';
2+
3+
describe('slugifyAnchor', () => {
4+
it('should anchors with underscores', () => {
5+
expect(slugifyAnchor('_prop_with_underscore_')).toBe(
6+
'prop-with-underscore',
7+
);
8+
});
9+
10+
it('should anchors with colons', () => {
11+
expect(slugifyAnchor('prop:colon')).toBe('prop-colon');
12+
});
13+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// eslint-disable-next-line no-control-regex
2+
const rControl = /[\u0000-\u001f]/g;
3+
const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.?/]+/g;
4+
const rCombining = /[\u0300-\u036F]/g;
5+
6+
export const slugifyAnchor = (str: string): string =>
7+
str
8+
.normalize('NFKD')
9+
// Remove accents
10+
.replace(rCombining, '')
11+
// Remove control characters
12+
.replace(rControl, '')
13+
// Replace special characters
14+
.replace(rSpecial, '-')
15+
// Remove continuos separators
16+
.replace(/-{2,}/g, '-')
17+
// Remove prefixing and trailing separators
18+
.replace(/^-+|-+$/g, '')
19+
// ensure it doesn't start with a number (#121)
20+
.replace(/^(\d)/, '_$1')
21+
// lowercase
22+
.toLowerCase();

0 commit comments

Comments
 (0)