Skip to content

Commit 13d7dc8

Browse files
authored
Merge pull request #83 from wp-blocks/array-parsing
Fix: multiple translations inside an array
2 parents afadcc8 + f2cb48a commit 13d7dc8

1 file changed

Lines changed: 45 additions & 14 deletions

File tree

src/parser/tree.ts

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)