Skip to content

Commit 89b457d

Browse files
committed
fix: use DEP code as anchor for deprecation headings in legacy-html
When generating legacy slugs for the deprecations API doc, headings in the form 'DEP0001: some description' now return just the DEP code (e.g. DEP0001) as the anchor ID. This matches the behavior of the old tooling and preserves existing external links like deprecations.html#DEP0190. The fix lives in createLegacySlugger so it stays within the legacy generator, as the legacy anchor is the one exposed on the old-format HTML page. Fixes: #750
1 parent 8b865f6 commit 89b457d

5 files changed

Lines changed: 50 additions & 55 deletions

File tree

src/generators/legacy-html/utils/__tests__/slugger.test.mjs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,36 @@ describe('createLegacySlugger', () => {
3636
assert.strictEqual(getLegacySlug('Hello', 'fs'), 'fs_hello_2');
3737
assert.strictEqual(getLegacySlug('World', 'fs'), 'fs_world');
3838
});
39+
40+
describe('deprecation headings', () => {
41+
it('returns the DEP code for deprecation headings in the deprecations doc', () => {
42+
const getLegacySlug = createLegacySlugger();
43+
assert.strictEqual(
44+
getLegacySlug(
45+
'DEP0001: `http.OutgoingMessage.prototype.flush`',
46+
'deprecations'
47+
),
48+
'DEP0001'
49+
);
50+
});
51+
52+
it('returns the DEP code regardless of the description text', () => {
53+
const getLegacySlug = createLegacySlugger();
54+
assert.strictEqual(
55+
getLegacySlug(
56+
'DEP0190: spawning .bat and .cmd files with child_process.spawn() with shell option',
57+
'deprecations'
58+
),
59+
'DEP0190'
60+
);
61+
});
62+
63+
it('does not apply deprecation special-casing outside the deprecations doc', () => {
64+
const getLegacySlug = createLegacySlugger();
65+
assert.notStrictEqual(
66+
getLegacySlug('DEP0190: some heading', 'child_process'),
67+
'DEP0190'
68+
);
69+
});
70+
});
3971
});

src/generators/legacy-html/utils/slugger.mjs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,31 @@
11
'use strict';
22

3+
// Matches headings in the deprecations API doc (e.g., "DEP0001: some title")
4+
// and captures the deprecation code (e.g., "DEP0001") as the first group
5+
const DEPRECATION_HEADING_REGEX = /^(DEP\d+):/;
6+
37
/**
48
* Creates a stateful slugger for legacy anchor links.
59
*
610
* Generates underscore-separated slugs in the form `{apiStem}_{text}`,
711
* appending `_{n}` for duplicates to preserve historical anchor compatibility.
812
*
13+
* For the deprecations API doc, headings matching the `DEP####:` pattern use
14+
* just the deprecation code (e.g., `DEP0001`) as the anchor, matching the
15+
* behavior of the old tooling and preserving existing external links.
16+
*
917
* @returns {(text: string, apiStem: string) => string}
1018
*/
1119
export const createLegacySlugger =
1220
(counters = {}) =>
1321
(text, apiStem) => {
22+
const depMatch =
23+
apiStem === 'deprecations' && DEPRECATION_HEADING_REGEX.exec(text);
24+
25+
if (depMatch) {
26+
return depMatch[1];
27+
}
28+
1429
const id = `${apiStem}_${text}`
1530
.toLowerCase()
1631
.replace(/^[^a-z0-9]+|[^a-z0-9]+$/g, '')

src/generators/metadata/constants.mjs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,5 @@ export const DOC_API_HEADING_TYPES = [
5959
// This regex is used to match basic TypeScript generic types (e.g., Promise<string>)
6060
export const TYPE_GENERIC_REGEX = /^([^<]+)<([^>]+)>$/;
6161

62-
// This regex matches headings in the deprecations API doc (e.g., "DEP0001: some title")
63-
// and captures the deprecation code (e.g., "DEP0001") as the first group
64-
export const DEPRECATION_HEADING_REGEX = /^(DEP\d+):/;
65-
6662
// This is the base URL of the Man7 documentation
6763
export const DOC_MAN_BASE_URL = 'http://man7.org/linux/man-pages/man';

src/generators/metadata/utils/__tests__/parse.test.mjs

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -222,43 +222,6 @@ describe('parseApiDoc', () => {
222222
});
223223
});
224224

225-
describe('deprecation heading slugs', () => {
226-
it('uses the DEP code as slug for headings in the deprecations doc', () => {
227-
const tree = u('root', [
228-
h('DEP0001: `http.OutgoingMessage.prototype.flush`', 3),
229-
]);
230-
const [entry] = parseApiDoc({ path: '/deprecations', tree }, typeMap);
231-
232-
assert.strictEqual(entry.heading.data.slug, 'DEP0001');
233-
});
234-
235-
it('uses the DEP code as slug regardless of the heading text that follows', () => {
236-
const tree = u('root', [
237-
h(
238-
'DEP0190: spawning .bat and .cmd files with child_process.spawn() with shell option',
239-
3
240-
),
241-
]);
242-
const [entry] = parseApiDoc({ path: '/deprecations', tree }, typeMap);
243-
244-
assert.strictEqual(entry.heading.data.slug, 'DEP0190');
245-
});
246-
247-
it('does not use the DEP code shortcut for non-deprecations docs', () => {
248-
const tree = u('root', [h('DEP0190: some section heading', 3)]);
249-
const [entry] = parseApiDoc({ path, tree }, typeMap);
250-
251-
assert.notStrictEqual(entry.heading.data.slug, 'DEP0190');
252-
});
253-
254-
it('uses normal slug for non-DEP headings in the deprecations doc', () => {
255-
const tree = u('root', [h('List of deprecated APIs', 2)]);
256-
const [entry] = parseApiDoc({ path: '/deprecations', tree }, typeMap);
257-
258-
assert.strictEqual(entry.heading.data.slug, 'list-of-deprecated-apis');
259-
});
260-
});
261-
262225
describe('document without headings', () => {
263226
it('produces one entry for content with no headings', () => {
264227
const tree = u('root', [

src/generators/metadata/utils/parse.mjs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ import {
2222
import { UNIST } from '../../../utils/queries/index.mjs';
2323
import { getRemark as remark } from '../../../utils/remark.mjs';
2424
import { relative } from '../../../utils/url.mjs';
25-
import {
26-
DEPRECATION_HEADING_REGEX,
27-
IGNORE_STABILITY_STEMS,
28-
} from '../constants.mjs';
25+
import { IGNORE_STABILITY_STEMS } from '../constants.mjs';
2926

3027
/**
3128
* This generator generates a flattened list of metadata entries from a API doc
@@ -90,16 +87,8 @@ export const parseApiDoc = ({ path, tree }, typeMap) => {
9087
heading: headingNode,
9188
});
9289

93-
// Generate slug and update heading data.
94-
// For the deprecations API doc, headings like "DEP0001: some title" use
95-
// just the deprecation code (e.g., "DEP0001") as the anchor to preserve
96-
// compatibility with existing external links.
97-
const depMatch =
98-
api === 'deprecations' &&
99-
DEPRECATION_HEADING_REGEX.exec(metadata.heading.data.text);
100-
metadata.heading.data.slug = depMatch
101-
? depMatch[1]
102-
: nodeSlugger.slug(metadata.heading.data.text);
90+
// Generate slug and update heading data
91+
metadata.heading.data.slug = nodeSlugger.slug(metadata.heading.data.text);
10392

10493
// Find the next heading to determine section boundaries
10594
const nextHeadingNode =

0 commit comments

Comments
 (0)