@@ -6,6 +6,19 @@ import { TOC_MAX_HEADING_DEPTH } from '../constants.mjs';
66
77const SHORT_SIGNATURE_TYPES = new Set ( [ 'classMethod' , 'ctor' , 'method' ] ) ;
88
9+ /**
10+ * Formats a full heading label for the table of contents.
11+ * @param {import('../../metadata/types').HeadingData } data
12+ */
13+ const formatHeading = data =>
14+ data . text
15+ // Remove any containing code blocks
16+ . replace ( / ` / g, '' )
17+ // Remove any prefixes (i.e. 'Class:')
18+ . replace ( / ^ [ ^ : ] + : / , '' )
19+ // Trim the remaining whitespace
20+ . trim ( ) ;
21+
922/**
1023 * Shortens method-like headings so the table of contents remains scannable.
1124 * @param {import('../../metadata/types').HeadingData } data
@@ -48,25 +61,11 @@ const shouldIncludeEntryInToC = ({ heading }) =>
4861/**
4962 * Extracts and formats heading information from an API documentation entry.
5063 * @param {import('../../metadata/types').MetadataEntry } entry
64+ * @param {string } heading
5165 */
52- const extractHeading = entry => {
66+ const extractHeading = ( entry , heading ) => {
5367 const data = entry . heading . data ;
5468
55- const cliFlagOrEnv = [ ...data . text . matchAll ( / ` ( - [ \w - ] + | [ A - Z 0 - 9 _ ] + = ) / g) ] ;
56-
57- const heading =
58- cliFlagOrEnv . length > 0
59- ? cliFlagOrEnv . at ( - 1 ) [ 1 ]
60- : SHORT_SIGNATURE_TYPES . has ( data . type )
61- ? formatCodeHeading ( data )
62- : data . text
63- // Remove any containing code blocks
64- . replace ( / ` / g, '' )
65- // Remove any prefixes (i.e. 'Class:')
66- . replace ( / ^ [ ^ : ] + : / , '' )
67- // Trim the remaining whitespace
68- . trim ( ) ;
69-
7069 return {
7170 depth : entry . heading . depth ,
7271 value : heading ,
@@ -76,10 +75,45 @@ const extractHeading = entry => {
7675 } ;
7776} ;
7877
78+ /**
79+ * Extracts both the full heading and the optional compact heading candidate.
80+ * @param {import('../../metadata/types').MetadataEntry } entry
81+ */
82+ const prepareHeading = entry => {
83+ const data = entry . heading . data ;
84+ const cliFlagOrEnv = [ ...data . text . matchAll ( / ` ( - [ \w - ] + | [ A - Z 0 - 9 _ ] + = ) / g) ] ;
85+
86+ if ( cliFlagOrEnv . length > 0 ) {
87+ return { entry, heading : cliFlagOrEnv . at ( - 1 ) [ 1 ] , compactHeading : null } ;
88+ }
89+
90+ return {
91+ entry,
92+ heading : formatHeading ( data ) ,
93+ compactHeading : SHORT_SIGNATURE_TYPES . has ( data . type )
94+ ? formatCodeHeading ( data )
95+ : null ,
96+ } ;
97+ } ;
98+
7999/**
80100 * Build the list of heading metadata for sidebar navigation.
81101 *
82102 * @param {Array<import('../../metadata/types').MetadataEntry> } entries - All API metadata entries
83103 */
84- export const extractHeadings = entries =>
85- entries . filter ( shouldIncludeEntryInToC ) . map ( extractHeading ) ;
104+ export const extractHeadings = entries => {
105+ const headings = entries . filter ( shouldIncludeEntryInToC ) . map ( prepareHeading ) ;
106+ const compactHeadingCounts = Map . groupBy (
107+ headings . filter ( ( { compactHeading } ) => compactHeading ) ,
108+ ( { compactHeading } ) => compactHeading
109+ ) ;
110+
111+ return headings . map ( ( { entry, heading, compactHeading } ) =>
112+ extractHeading (
113+ entry ,
114+ compactHeading && compactHeadingCounts . get ( compactHeading ) . length === 1
115+ ? compactHeading
116+ : heading
117+ )
118+ ) ;
119+ } ;
0 commit comments