1616
1717import { join } from 'node:path' ;
1818import { asString , Dictionary , ensureObject , ensureString } from '@salesforce/ts-types' ;
19- import { CommandClass , CommandParameterData , punctuate , replaceConfigVariables } from '../utils.js' ;
19+ import {
20+ CommandClass ,
21+ CommandParameterData ,
22+ commandFileBase ,
23+ escapeAngleBrackets ,
24+ punctuate ,
25+ replaceConfigVariables ,
26+ stateLabel ,
27+ } from '../utils.js' ;
2028import { buildCommandParameters , FlagInfo , formatParagraphs , readBinary } from '../ditamap/command-helpers.js' ;
2129import { MarkdownBase } from './markdown-base.js' ;
2230
@@ -40,19 +48,11 @@ export class MarkdownCommand extends MarkdownBase {
4048
4149 public constructor (
4250 topic : string ,
43- subtopic : string | null ,
4451 command : CommandClass ,
4552 commandMeta : Record < string , unknown > = { } ,
4653 outputDir : string
4754 ) {
48- const commandWithUnderscores = ensureString ( command . id ) . replace ( / : / g, '_' ) ;
49- // If the command ID has no subtopic (e.g. "doctor"), its filename would collide with the topic
50- // index file (cli_reference_doctor.md), so append _command to disambiguate.
51- const isTopicLevelCommand = ! ensureString ( command . id ) . includes ( ':' ) ;
52- const baseName = isTopicLevelCommand
53- ? `cli_reference_${ commandWithUnderscores } _command`
54- : `cli_reference_${ commandWithUnderscores } ` ;
55- const filename = MarkdownBase . file ( baseName ) ;
55+ const filename = MarkdownBase . file ( commandFileBase ( ensureString ( command . id ) ) ) ;
5656 super ( filename , outputDir ) ;
5757 this . destination = join ( outputDir , topic , filename ) ;
5858
@@ -102,12 +102,12 @@ export class MarkdownCommand extends MarkdownBase {
102102 lines . push ( '<!-- prettier-ignore-start -->' ) ;
103103 lines . push ( '' ) ;
104104
105- const stateLabel = resolveStateLabel ( this . state , this . deprecated ) ;
106- lines . push ( `# ${ this . commandName } ${ stateLabel ? ` (${ stateLabel } )` : '' } ` ) ;
105+ const label = stateLabel ( this . state , this . deprecated ) ;
106+ lines . push ( `# ${ this . commandName } ${ label ? ` (${ label } )` : '' } ` ) ;
107107 lines . push ( '' ) ;
108108
109109 if ( this . summary ) {
110- lines . push ( this . summary ) ;
110+ lines . push ( escapeAngleBrackets ( this . summary ) ) ;
111111 lines . push ( '' ) ;
112112 }
113113
@@ -180,7 +180,7 @@ export class MarkdownCommand extends MarkdownBase {
180180
181181function escapeForMarkdown ( text : string ) : string {
182182 // Escape HTML entities for markdown safety
183- let result = text . replace ( / < / g , '<' ) . replace ( / > / g , '>' ) ;
183+ let result = escapeAngleBrackets ( text ) ;
184184
185185 // Normalize whitespace: collapse multiple spaces/tabs/newlines to single space
186186 result = result . replace ( / \s + / g, ' ' ) ;
@@ -226,14 +226,6 @@ function convertBulletListsToHtml(paragraphs: string[]): string[] {
226226 return result ;
227227}
228228
229- function resolveStateLabel ( state : unknown , deprecated : boolean ) : string | null {
230- if ( deprecated ) return 'Deprecated' ;
231- if ( state === 'beta' ) return 'Beta' ;
232- if ( state === 'preview' ) return 'Developer Preview' ;
233- if ( state === 'closedPilot' || state === 'openPilot' ) return 'Pilot' ;
234- return null ;
235- }
236-
237229function resolveDisclaimer (
238230 commandName : string ,
239231 state : unknown ,
0 commit comments