@@ -113,45 +113,93 @@ const convert_code_block_to_new_file_diff = (lines: string[]): Diff | null => {
113113 // Regex to find file path. It can be commented or not.
114114 // It handles paths with slashes, backslashes, dots, alphanumerics, underscores, and hyphens.
115115 const path_regex = / (?: (?: \/ \/ | # | - - | < ! - - ) \s * ) ? ( [ \w . / \\ - ] + ) /
116+ const xml_path_regex = / < f i l e \s + p a t h = [ " ' ] ( [ ^ " ' ] + ) [ " ' ] /
116117
117118 let file_path : string | undefined
118119 let path_line_index = - 1
120+ let content_lines : string [ ] = [ ]
119121
120- // Look for a file path in the first few lines of the code block
121- for ( let i = 0 ; i < Math . min ( lines . length , 5 ) ; i ++ ) {
122- const line = lines [ i ] . trim ( )
123- const match = line . match ( path_regex )
124-
125- if ( match && match [ 1 ] ) {
126- const potential_path = match [ 1 ]
127-
128- if (
129- ( potential_path . includes ( '.' ) || potential_path . includes ( '/' ) ) &&
130- ! potential_path . includes ( ' ' )
131- ) {
132- const rest_of_line = line
133- . substring ( line . indexOf ( potential_path ) + potential_path . length )
134- . trim ( )
135- // e.g. `25:5` for line and column, or `-->` for html comments
136- const is_just_path_and_location = / ^ (?: \d + : \d + ) ? \s * ( - - > ) ? \s * $ / . test (
137- rest_of_line
138- )
139-
140- if ( is_just_path_and_location ) {
141- file_path = potential_path . replace ( / \\ / g, '/' ) // normalize backslashes
142- path_line_index = i
143- break // Found it, stop searching.
122+ // Check for XML path format
123+ const first_line = lines . length > 0 ? lines [ 0 ] . trim ( ) : ''
124+ const xml_match = first_line . match ( xml_path_regex )
125+
126+ if ( xml_match && xml_match [ 1 ] ) {
127+ file_path = xml_match [ 1 ] . replace ( / \\ / g, '/' )
128+
129+ const file_tag_start = lines . findIndex ( ( l ) => l . trim ( ) . startsWith ( '<file' ) )
130+ let file_tag_end = - 1
131+ for ( let i = lines . length - 1 ; i >= 0 ; i -- ) {
132+ if ( lines [ i ] . trim ( ) . startsWith ( '</file>' ) ) {
133+ file_tag_end = i
134+ break
135+ }
136+ }
137+
138+ if (
139+ file_tag_start !== - 1 &&
140+ file_tag_end !== - 1 &&
141+ file_tag_end > file_tag_start
142+ ) {
143+ const inner_lines = lines . slice ( file_tag_start + 1 , file_tag_end )
144+
145+ const cdata_start = inner_lines . findIndex ( ( l ) =>
146+ l . trim ( ) . startsWith ( '<![CDATA[' )
147+ )
148+ let cdata_end = - 1
149+ for ( let i = inner_lines . length - 1 ; i >= 0 ; i -- ) {
150+ if ( inner_lines [ i ] . trim ( ) . endsWith ( ']]>' ) ) {
151+ cdata_end = i
152+ break
144153 }
145154 }
155+
156+ if ( cdata_start !== - 1 && cdata_end !== - 1 && cdata_end > cdata_start ) {
157+ content_lines = inner_lines . slice ( cdata_start + 1 , cdata_end )
158+ } else {
159+ content_lines = inner_lines
160+ }
161+ } else {
162+ // malformed, maybe path is on first line, and content follows
163+ content_lines = lines . slice ( 1 )
164+ }
165+ } else {
166+ // Look for a file path in the first few lines of the code block
167+ for ( let i = 0 ; i < Math . min ( lines . length , 5 ) ; i ++ ) {
168+ const line = lines [ i ] . trim ( )
169+ const match = line . match ( path_regex )
170+
171+ if ( match && match [ 1 ] ) {
172+ const potential_path = match [ 1 ]
173+
174+ if (
175+ ( potential_path . includes ( '.' ) || potential_path . includes ( '/' ) ) &&
176+ ! potential_path . includes ( ' ' )
177+ ) {
178+ const rest_of_line = line
179+ . substring ( line . indexOf ( potential_path ) + potential_path . length )
180+ . trim ( )
181+ // e.g. `25:5` for line and column, or `-->` for html comments
182+ const is_just_path_and_location = / ^ (?: \d + : \d + ) ? \s * ( - - > ) ? \s * $ / . test (
183+ rest_of_line
184+ )
185+
186+ if ( is_just_path_and_location ) {
187+ file_path = potential_path . replace ( / \\ / g, '/' ) // normalize backslashes
188+ path_line_index = i
189+ break // Found it, stop searching.
190+ }
191+ }
192+ }
193+ }
194+ if ( path_line_index !== - 1 ) {
195+ content_lines = lines . filter ( ( _ , index ) => index !== path_line_index )
146196 }
147197 }
148198
149199 if ( ! file_path ) {
150200 return null
151201 }
152202
153- const content_lines = lines . filter ( ( _ , index ) => index !== path_line_index )
154-
155203 const patch_lines = content_lines . map ( ( line ) => `+${ line } ` )
156204 const patch_content = [
157205 `--- /dev/null` ,
0 commit comments