@@ -155,7 +155,7 @@ export function doTree(
155155 }
156156
157157 // The arguments are the last child
158- const argsNode = node . lastChild ;
158+ const argsNode = node . childForFieldName ( "arguments" ) ;
159159 if (
160160 argsNode === null ||
161161 argsNode . childCount === 0 ||
@@ -164,12 +164,8 @@ export function doTree(
164164 return ;
165165 }
166166
167- // Get the whole gettext translation string
168- // eslint-disable-next-line @typescript-eslint/no-unused-vars
169- const [ _fn , raw ] = node . children ;
170-
171167 // Safety check: verify we actually have an arguments node
172- if ( ! raw ) return ;
168+ if ( ! argsNode ) return ;
173169
174170 const translation : Partial < {
175171 msgctxt : string ;
@@ -186,23 +182,58 @@ export function doTree(
186182 const translationKeys =
187183 i18nFunctions [ functionName as keyof typeof i18nFunctions ] ;
188184
189- // Slice the children to skip the opening and closing parentheses/brackets
190- const children = raw . children . slice ( 1 , - 1 ) ;
185+ // Slice the children to skip the opening and closing parentheses/brackets or process them directly
186+ // We iterate over all children and handle them based on type
187+ const children = argsNode . children ;
191188 let translationKeyIndex = 0 ;
192189
193190 // Get the translation from the arguments
194191 for ( const child of children ) {
195192 let node = child ;
196193
194+ // Skip parentheses and commas
195+ if (
196+ node . type === "(" ||
197+ node . type === ")" ||
198+ node . type === "," ||
199+ node . type === "[" ||
200+ node . type === "]"
201+ ) {
202+ continue ;
203+ }
204+
205+ // Skip comments
206+ if ( node . type === "comment" ) {
207+ continue ;
208+ }
209+
197210 // unwrap the argument node, which is used in PHP.
198211 if ( child . type === "argument" ) {
199212 if ( child . children . length === 0 ) continue ;
200- node = child . children [ 0 ] ;
201- }
202213
203- if ( node ?. type === "," ) {
204- // skip the comma between arguments
205- continue ;
214+ // Check if this is a named argument
215+ const nameNode = child . childForFieldName ( "name" ) ;
216+
217+ // Iterate over children to find the value
218+ // The value is the child that is NOT the name node, not a comment, and not punctuation.
219+ let foundValue = false ;
220+ for ( const argChild of child . children ) {
221+ if ( argChild . id === nameNode ?. id ) {
222+ continue ; // Skip the name label
223+ }
224+ if ( argChild . type === "comment" || argChild . type === ":" ) {
225+ continue ; // Skip comments and colon
226+ }
227+ // Found the value!
228+ node = argChild ;
229+ foundValue = true ;
230+ break ;
231+ }
232+
233+ // If we didn't find a value (e.g. only comments?), skip this argument
234+ if ( ! foundValue ) {
235+ continue ;
236+ }
206237 }
207238
208239 // Stop if we have more arguments than keys defined
@@ -213,7 +244,7 @@ export function doTree(
213244 // the translation key (eg. msgid)
214245 const currentKey = translationKeys [
215246 translationKeyIndex
216- ] as keyof typeof translation ;
247+ ] as keyof typeof translation ;
217248
218249 // Resolve the value using our new function (handles quotes and escapes)
219250 let nodeValue : string = resolveStringValue ( node ) ;
0 commit comments