@@ -48,7 +48,7 @@ const onAtNotationMatch = (data, { key }) => {
4848
4949const onAtNotationFunctionMatch = ( data , { key, fullMatch, dir } ) => {
5050 if ( data . indexOf ( '.md' ) !== - 1 || data . indexOf ( '.mdx' ) !== - 1 || data . indexOf ( '.' ) === - 1 ) {
51- const result = readFile ( dir , data ) ;
51+ const result = readFileFromPath ( dir , data ) ;
5252 return result ? / @ s h o r t : ( .* ) / g. exec ( result ) [ 1 ] : fullMatch ;
5353 }
5454 return fullMatch ;
@@ -88,11 +88,71 @@ const readFile = (workingDir, filePath) => {
8888 return fs . readFileSync ( path . normalize ( finalPath ) , 'utf8' ) ;
8989} ;
9090
91+ const getContentRelativePath = ( dir , filePath ) => {
92+ // Already a docs-root-relative path (no ./ or ../ prefix) — return as-is
93+ if ( ! filePath . startsWith ( '.' ) ) {
94+ return filePath ;
95+ }
96+
97+ const absolutePath = path . resolve ( dir , filePath ) . replace ( / \\ / g, '/' ) ;
98+ const i18nDir = path . join ( __dirname , 'i18n' ) . replace ( / \\ / g, '/' ) ;
99+ const docsDir = path . join ( __dirname , 'docs' ) . replace ( / \\ / g, '/' ) ;
100+
101+ if ( absolutePath . startsWith ( i18nDir + '/' ) ) {
102+ const currentIndex = absolutePath . indexOf ( '/current/' ) ;
103+ if ( currentIndex !== - 1 ) {
104+ return absolutePath . substring ( currentIndex + '/current/' . length ) ;
105+ }
106+ }
107+
108+ if ( absolutePath . startsWith ( docsDir + '/' ) ) {
109+ return absolutePath . substring ( docsDir . length + 1 ) ;
110+ }
111+
112+ return filePath ;
113+ } ;
114+
115+ // Returns the content root for i18n files (i18n/XX/.../current), or null for docs/ files.
116+ const getLocaleContentRoot = ( dir ) => {
117+ const normalizedDir = dir . replace ( / \\ / g, '/' ) ;
118+ const currentIndex = normalizedDir . indexOf ( '/current/' ) ;
119+ if ( currentIndex !== - 1 && normalizedDir . includes ( '/i18n/' ) ) {
120+ return normalizedDir . substring ( 0 , currentIndex + '/current' . length ) ;
121+ }
122+ return null ;
123+ } ;
124+
125+ // Reads a file by path, supporting both relative (../foo.md) and docs-root-relative (api/foo.md) formats.
126+ // For i18n files, tries the localized version first before falling back to docs/.
127+ const readFileFromPath = ( dir , filePath ) => {
128+ const result = readFile ( dir , filePath ) ;
129+ if ( result ) return result ;
130+
131+ // If path doesn't start with . it may be docs-root-relative
132+ if ( ! filePath . startsWith ( '.' ) ) {
133+ // For i18n files: try the locale's content root first (localized version)
134+ const localeRoot = getLocaleContentRoot ( dir ) ;
135+ if ( localeRoot ) {
136+ const localeResult = readFile ( localeRoot , filePath ) ;
137+ if ( localeResult ) return localeResult ;
138+ }
139+
140+ // Fall back to docs/ (English)
141+ const docsDir = path . join ( __dirname , 'docs' ) . replace ( / \\ / g, '/' ) ;
142+ return readFile ( docsDir , filePath ) ;
143+ }
144+
145+ return false ;
146+ } ;
147+
91148const onEmptyLinkMatch = ( data , { key, fullMatch, dir } ) => {
92149 const filePath = fullMatch . substring ( fullMatch . indexOf ( '(' ) + 1 , fullMatch . length - 1 ) ;
93150 if ( filePath . indexOf ( '.md' ) !== - 1 || filePath . indexOf ( '.mdx' ) !== - 1 || filePath . indexOf ( '.' ) === - 1 ) {
94- const data = readFile ( dir , filePath ) ;
95- return data ? `[${ / .* s i d e b a r _ l a b e l : ( .+ ) / g. exec ( data ) [ 1 ] } ]${ fullMatch . match ( / \( \D + \) / g) [ 0 ] } ` : fullMatch ;
151+ const fileData = readFileFromPath ( dir , filePath ) ;
152+ if ( ! fileData ) return fullMatch ;
153+ const label = / .* s i d e b a r _ l a b e l : ( .+ ) / g. exec ( fileData ) [ 1 ] ;
154+ const normalizedPath = getContentRelativePath ( dir , filePath ) ;
155+ return `[${ label } ](${ normalizedPath } )` ;
96156 }
97157 return fullMatch ;
98158} ;
0 commit comments