@lokascript/i18n 2.5.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.cjs +1274 -154
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +3 -3
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +1274 -155
- package/dist/browser.js.map +1 -1
- package/dist/dictionaries/index.cjs +364 -133
- package/dist/dictionaries/index.cjs.map +1 -1
- package/dist/dictionaries/index.d.cts +1 -1
- package/dist/dictionaries/index.d.ts +1 -1
- package/dist/dictionaries/index.js +364 -133
- package/dist/dictionaries/index.js.map +1 -1
- package/dist/index.cjs +8860 -7740
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -37
- package/dist/index.d.ts +37 -37
- package/dist/index.js +8860 -7741
- package/dist/index.js.map +1 -1
- package/dist/lokascript-i18n.min.js +1 -1
- package/dist/lokascript-i18n.min.js.map +1 -1
- package/dist/lokascript-i18n.mjs +1697 -146
- package/dist/lokascript-i18n.mjs.map +1 -1
- package/dist/plugins/vite.cjs +359 -132
- package/dist/plugins/vite.cjs.map +1 -1
- package/dist/plugins/vite.js +359 -132
- package/dist/plugins/vite.js.map +1 -1
- package/dist/plugins/webpack.cjs +359 -132
- package/dist/plugins/webpack.cjs.map +1 -1
- package/dist/plugins/webpack.js +359 -132
- package/dist/plugins/webpack.js.map +1 -1
- package/dist/{transformer-BLv389qz.d.ts → transformer-BA8YX9u1.d.ts} +120 -2
- package/dist/{transformer-PFsYELrc.d.cts → transformer-DM7iplCU.d.cts} +120 -2
- package/dist/{types-BcALAO6h.d.cts → types-BYtpqGq3.d.cts} +1 -1
- package/dist/{types-BcALAO6h.d.ts → types-BYtpqGq3.d.ts} +1 -1
- package/package.json +6 -6
- package/src/browser.ts +1 -0
- package/src/command-primary-roles.test.ts +59 -0
- package/src/constants.ts +51 -0
- package/src/dictionaries/ar.ts +8 -3
- package/src/dictionaries/bn.ts +3 -1
- package/src/dictionaries/de.ts +19 -4
- package/src/dictionaries/derive.ts +4 -0
- package/src/dictionaries/en.ts +9 -0
- package/src/dictionaries/es.ts +2 -2
- package/src/dictionaries/fr.ts +6 -2
- package/src/dictionaries/he.ts +7 -1
- package/src/dictionaries/hi.ts +17 -10
- package/src/dictionaries/id.ts +15 -8
- package/src/dictionaries/it.ts +6 -3
- package/src/dictionaries/ja.ts +10 -4
- package/src/dictionaries/ko.ts +9 -4
- package/src/dictionaries/ms.ts +2 -1
- package/src/dictionaries/pl.ts +11 -3
- package/src/dictionaries/pt.ts +10 -4
- package/src/dictionaries/qu.ts +46 -22
- package/src/dictionaries/ru.ts +14 -7
- package/src/dictionaries/sw.ts +37 -10
- package/src/dictionaries/th.ts +3 -1
- package/src/dictionaries/tl.ts +14 -7
- package/src/dictionaries/tr.ts +22 -9
- package/src/dictionaries/uk.ts +13 -7
- package/src/dictionaries/vi.ts +3 -3
- package/src/dictionaries/zh.ts +10 -2
- package/src/examples/new-languages.ts +1 -1
- package/src/grammar/grammar.test.ts +1242 -1
- package/src/grammar/index.ts +1 -0
- package/src/grammar/profiles/index.ts +358 -12
- package/src/grammar/transformer.ts +1053 -16
- package/src/grammar/types.ts +22 -1
- package/src/index.ts +1 -0
- package/src/new-languages.test.ts +7 -3
- package/src/parser/parser-integration.test.ts +5 -1
- package/src/positional-keyword-drift.test.ts +138 -0
package/src/grammar/index.ts
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* language-specific markers and rules.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { LanguageProfile } from '../types';
|
|
9
|
+
import type { LanguageProfile, SemanticRole } from '../types';
|
|
10
|
+
import { reorderRoles, insertMarkers } from '../types';
|
|
10
11
|
|
|
11
12
|
// =============================================================================
|
|
12
13
|
// English (Reference Language)
|
|
@@ -104,6 +105,41 @@ export const japaneseProfile: LanguageProfile = {
|
|
|
104
105
|
insertMarkers: true,
|
|
105
106
|
},
|
|
106
107
|
},
|
|
108
|
+
{
|
|
109
|
+
name: 'set-to',
|
|
110
|
+
description: 'Transform set X to Y to Japanese verb-final order',
|
|
111
|
+
priority: 90,
|
|
112
|
+
match: {
|
|
113
|
+
commands: ['set', '設定'],
|
|
114
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
115
|
+
// Skip a set whose value swept up a trailing block terminator (`set X to Y
|
|
116
|
+
// end` — the body of an inline `if … then set … end`): verb-final reorder
|
|
117
|
+
// would push the verb past `end` and break the block. These parse fine
|
|
118
|
+
// verb-medial (the default).
|
|
119
|
+
predicate: parsed => !/(^|\s)end$/i.test((parsed.original ?? '').trim()),
|
|
120
|
+
},
|
|
121
|
+
transform: {
|
|
122
|
+
// X を Y に 設定 — verb-final, matching the generated SOV set pattern
|
|
123
|
+
// (markerOverride: を on the destination / に on the value). Default reorder
|
|
124
|
+
// emitted verb-MEDIAL (`X を 設定 Y に`), unmatched by any set pattern.
|
|
125
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
126
|
+
insertMarkers: true,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'bind-to',
|
|
131
|
+
description: 'Transform bind $var to #el to Japanese verb-final order',
|
|
132
|
+
priority: 90,
|
|
133
|
+
match: {
|
|
134
|
+
commands: ['bind', 'バインド'],
|
|
135
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
136
|
+
},
|
|
137
|
+
transform: {
|
|
138
|
+
// $var を #el に バインド
|
|
139
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
140
|
+
insertMarkers: true,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
107
143
|
],
|
|
108
144
|
};
|
|
109
145
|
|
|
@@ -127,6 +163,10 @@ export const koreanProfile: LanguageProfile = {
|
|
|
127
163
|
{ form: '를', role: 'patient', position: 'postposition', required: true, alternatives: ['을'] },
|
|
128
164
|
{ form: '에', role: 'destination', position: 'postposition', required: true },
|
|
129
165
|
{ form: '에서', role: 'source', position: 'postposition', required: true },
|
|
166
|
+
// Event marker — the semantic *-event-ko-sov-* patterns anchor on 할 때
|
|
167
|
+
// (the generator profile's eventMarker); without it every ko handler
|
|
168
|
+
// emitted a bare event name no fused pattern could anchor.
|
|
169
|
+
{ form: '할 때', role: 'event', position: 'postposition', required: true },
|
|
130
170
|
{
|
|
131
171
|
form: '로',
|
|
132
172
|
role: 'style',
|
|
@@ -158,6 +198,56 @@ export const koreanProfile: LanguageProfile = {
|
|
|
158
198
|
insertMarkers: true,
|
|
159
199
|
},
|
|
160
200
|
},
|
|
201
|
+
{
|
|
202
|
+
name: 'put-into',
|
|
203
|
+
description: 'Transform put X into Y to Korean verb-final order',
|
|
204
|
+
priority: 90,
|
|
205
|
+
match: {
|
|
206
|
+
commands: ['put', '넣다'],
|
|
207
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
208
|
+
// Standalone put only (e.g. a then-chain clause): an event handler whose
|
|
209
|
+
// action is `put` must keep the event mid-stream, so don't verb-final it.
|
|
210
|
+
predicate: parsed => !parsed.roles.has('event'),
|
|
211
|
+
},
|
|
212
|
+
transform: {
|
|
213
|
+
// X 를 Y 에 넣다 (patient, destination, verb-last)
|
|
214
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
215
|
+
insertMarkers: true,
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: 'set-to',
|
|
220
|
+
description: 'Transform set X to Y to Korean verb-final order',
|
|
221
|
+
priority: 90,
|
|
222
|
+
match: {
|
|
223
|
+
commands: ['set', '설정'],
|
|
224
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
225
|
+
// Skip a set whose value swept up a trailing block terminator (`set X to Y
|
|
226
|
+
// end` — the body of an inline `if … then set … end`): verb-final reorder
|
|
227
|
+
// would push the verb past `end` and break the block. These parse fine
|
|
228
|
+
// verb-medial (the default).
|
|
229
|
+
predicate: parsed => !/(^|\s)end$/i.test((parsed.original ?? '').trim()),
|
|
230
|
+
},
|
|
231
|
+
transform: {
|
|
232
|
+
// X 를 Y 에 설정 — verb-final, matching the generated SOV set pattern.
|
|
233
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
234
|
+
insertMarkers: true,
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
name: 'bind-to',
|
|
239
|
+
description: 'Transform bind $var to #el to Korean verb-final order',
|
|
240
|
+
priority: 90,
|
|
241
|
+
match: {
|
|
242
|
+
commands: ['bind', '바인드'],
|
|
243
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
244
|
+
},
|
|
245
|
+
transform: {
|
|
246
|
+
// $var 를 #el 에 바인드
|
|
247
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
248
|
+
insertMarkers: true,
|
|
249
|
+
},
|
|
250
|
+
},
|
|
161
251
|
],
|
|
162
252
|
};
|
|
163
253
|
|
|
@@ -198,20 +288,33 @@ export const chineseProfile: LanguageProfile = {
|
|
|
198
288
|
requiredRoles: ['event', 'action'],
|
|
199
289
|
},
|
|
200
290
|
transform: {
|
|
201
|
-
// 当
|
|
291
|
+
// 当 EVENT 时 ACTION [patient] [destination] [source] [style] [method] ...
|
|
202
292
|
roleOrder: ['event', 'action', 'patient'],
|
|
203
293
|
insertMarkers: true,
|
|
204
|
-
custom: (parsed,
|
|
205
|
-
// Handle 当...时 circumfix
|
|
294
|
+
custom: (parsed, profile) => {
|
|
295
|
+
// Handle 当...时 circumfix wrapping the event, then emit the action,
|
|
296
|
+
// then any remaining roles in canonical order with their markers.
|
|
297
|
+
// Earlier this function emitted only event/action/patient and silently
|
|
298
|
+
// dropped destination, source, style, etc. — that produced truncated
|
|
299
|
+
// output for `send X to Y`, `fetch /api with method:...`, etc.
|
|
206
300
|
const event = parsed.roles.get('event');
|
|
207
301
|
const action = parsed.roles.get('action');
|
|
208
|
-
const patient = parsed.roles.get('patient');
|
|
209
302
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
303
|
+
// Build the post-action role list using the canonical order minus
|
|
304
|
+
// event/action, plus a safety net for any roles not in the order.
|
|
305
|
+
const remaining = new Map(parsed.roles);
|
|
306
|
+
remaining.delete('event');
|
|
307
|
+
remaining.delete('action');
|
|
308
|
+
|
|
309
|
+
const remainingOrder: SemanticRole[] = (profile.canonicalOrder || []).filter(
|
|
310
|
+
r => r !== 'event' && r !== 'action'
|
|
311
|
+
);
|
|
312
|
+
const reordered = reorderRoles(remaining, remainingOrder);
|
|
313
|
+
const markedTokens = insertMarkers(reordered, profile.markers, profile.adpositionType);
|
|
314
|
+
|
|
315
|
+
const parts: string[] = ['当', event?.translated || event?.value || '', '时'];
|
|
316
|
+
if (action) parts.push(action.translated || action.value);
|
|
317
|
+
parts.push(...markedTokens);
|
|
215
318
|
|
|
216
319
|
return parts.filter(Boolean).join(' ');
|
|
217
320
|
},
|
|
@@ -231,6 +334,30 @@ export const chineseProfile: LanguageProfile = {
|
|
|
231
334
|
insertMarkers: true,
|
|
232
335
|
},
|
|
233
336
|
},
|
|
337
|
+
{
|
|
338
|
+
name: 'bind-to',
|
|
339
|
+
description: 'Bind binds a variable to an element: 绑定 X 到 Y (no 把)',
|
|
340
|
+
priority: 90,
|
|
341
|
+
match: {
|
|
342
|
+
commands: ['bind', '绑定'],
|
|
343
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
344
|
+
},
|
|
345
|
+
transform: {
|
|
346
|
+
// Plain SVO without the 把 object-fronting: the bound variable is the
|
|
347
|
+
// semantic destination (not a fronted patient), and `到` marks the
|
|
348
|
+
// target element. Custom so the patient does not pick up 把.
|
|
349
|
+
roleOrder: ['action', 'patient', 'destination'],
|
|
350
|
+
custom: parsed => {
|
|
351
|
+
const action = parsed.roles.get('action');
|
|
352
|
+
const patient = parsed.roles.get('patient');
|
|
353
|
+
const destination = parsed.roles.get('destination');
|
|
354
|
+
const verb = action?.translated || action?.value || '';
|
|
355
|
+
const v = patient?.translated || patient?.value || '';
|
|
356
|
+
const d = destination?.translated || destination?.value || '';
|
|
357
|
+
return [verb, v, '到', d].filter(Boolean).join(' ');
|
|
358
|
+
},
|
|
359
|
+
},
|
|
360
|
+
},
|
|
234
361
|
],
|
|
235
362
|
};
|
|
236
363
|
|
|
@@ -339,6 +466,56 @@ export const turkishProfile: LanguageProfile = {
|
|
|
339
466
|
insertMarkers: true,
|
|
340
467
|
},
|
|
341
468
|
},
|
|
469
|
+
{
|
|
470
|
+
name: 'put-into',
|
|
471
|
+
description: 'Transform put X into Y to Turkish verb-final order',
|
|
472
|
+
priority: 90,
|
|
473
|
+
match: {
|
|
474
|
+
commands: ['put', 'koy'],
|
|
475
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
476
|
+
// Standalone put only (e.g. a then-chain clause): an event handler whose
|
|
477
|
+
// action is `put` must keep the event mid-stream, so don't verb-final it.
|
|
478
|
+
predicate: parsed => !parsed.roles.has('event'),
|
|
479
|
+
},
|
|
480
|
+
transform: {
|
|
481
|
+
// X i Y e koy (patient, destination, verb-last)
|
|
482
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
483
|
+
insertMarkers: true,
|
|
484
|
+
},
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
name: 'set-to',
|
|
488
|
+
description: 'Transform set X to Y to Turkish verb-final order',
|
|
489
|
+
priority: 90,
|
|
490
|
+
match: {
|
|
491
|
+
commands: ['set', 'ayarla'],
|
|
492
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
493
|
+
// Skip a set whose value swept up a trailing block terminator (`set X to Y
|
|
494
|
+
// end` — the body of an inline `if … then set … end`): verb-final reorder
|
|
495
|
+
// would push the verb past `end` and break the block. These parse fine
|
|
496
|
+
// verb-medial (the default).
|
|
497
|
+
predicate: parsed => !/(^|\s)end$/i.test((parsed.original ?? '').trim()),
|
|
498
|
+
},
|
|
499
|
+
transform: {
|
|
500
|
+
// X i Y e ayarla — verb-final, matching the generated SOV set pattern.
|
|
501
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
502
|
+
insertMarkers: true,
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
name: 'bind-to',
|
|
507
|
+
description: 'Transform bind $var to #el to Turkish verb-final order',
|
|
508
|
+
priority: 90,
|
|
509
|
+
match: {
|
|
510
|
+
commands: ['bind'],
|
|
511
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
512
|
+
},
|
|
513
|
+
transform: {
|
|
514
|
+
// $var i #el e bağla
|
|
515
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
516
|
+
insertMarkers: true,
|
|
517
|
+
},
|
|
518
|
+
},
|
|
342
519
|
],
|
|
343
520
|
};
|
|
344
521
|
|
|
@@ -473,6 +650,35 @@ export const indonesianProfile: LanguageProfile = {
|
|
|
473
650
|
],
|
|
474
651
|
};
|
|
475
652
|
|
|
653
|
+
// =============================================================================
|
|
654
|
+
// Malay (SVO, Austronesian) — grammar mirrors Indonesian (shared function words:
|
|
655
|
+
// pada / ke / dari / dengan / sebagai). Without this profile the transformer threw
|
|
656
|
+
// "Unknown target locale: ms", so no ms translation could be generated at all.
|
|
657
|
+
// =============================================================================
|
|
658
|
+
|
|
659
|
+
export const malayProfile: LanguageProfile = {
|
|
660
|
+
code: 'ms',
|
|
661
|
+
name: 'Bahasa Melayu',
|
|
662
|
+
|
|
663
|
+
wordOrder: 'SVO',
|
|
664
|
+
adpositionType: 'preposition',
|
|
665
|
+
morphology: 'agglutinative',
|
|
666
|
+
direction: 'ltr',
|
|
667
|
+
|
|
668
|
+
canonicalOrder: ['event', 'action', 'patient', 'destination'],
|
|
669
|
+
|
|
670
|
+
markers: [
|
|
671
|
+
// ms marks the event clause with `apabila` ("when/on") — matching the semantic
|
|
672
|
+
// ms event-handler pattern (`apabila {event} {body}`) and the ms dict's
|
|
673
|
+
// `on: apabila`. (Indonesian uses `pada` here; the two diverge on the event head.)
|
|
674
|
+
{ form: 'apabila', role: 'event', position: 'preposition', required: true },
|
|
675
|
+
{ form: 'ke', role: 'destination', position: 'preposition', required: false },
|
|
676
|
+
{ form: 'dari', role: 'source', position: 'preposition', required: false },
|
|
677
|
+
{ form: 'dengan', role: 'style', position: 'preposition', required: false },
|
|
678
|
+
{ form: 'sebagai', role: 'method', position: 'preposition', required: false },
|
|
679
|
+
],
|
|
680
|
+
};
|
|
681
|
+
|
|
476
682
|
// =============================================================================
|
|
477
683
|
// Quechua (SOV, Quechuan)
|
|
478
684
|
// =============================================================================
|
|
@@ -521,7 +727,10 @@ export const swahiliProfile: LanguageProfile = {
|
|
|
521
727
|
{ form: 'kwa', role: 'destination', position: 'preposition', required: false },
|
|
522
728
|
{ form: 'kutoka', role: 'source', position: 'preposition', required: false },
|
|
523
729
|
{ form: 'na', role: 'style', position: 'preposition', required: false },
|
|
524
|
-
|
|
730
|
+
// `kuwa`, not `kama`: sw `kama` is the IF keyword — rendering the method
|
|
731
|
+
// role ("as X") with it grew a phantom `if` at semantic parse time. See the
|
|
732
|
+
// matching comment in dictionaries/sw.ts (modifiers.as).
|
|
733
|
+
{ form: 'kuwa', role: 'method', position: 'preposition', required: false }, // "as/become"
|
|
525
734
|
],
|
|
526
735
|
};
|
|
527
736
|
|
|
@@ -568,6 +777,56 @@ export const bengaliProfile: LanguageProfile = {
|
|
|
568
777
|
insertMarkers: true,
|
|
569
778
|
},
|
|
570
779
|
},
|
|
780
|
+
{
|
|
781
|
+
name: 'put-into',
|
|
782
|
+
description: 'Transform put X into Y to Bengali verb-final order',
|
|
783
|
+
priority: 90,
|
|
784
|
+
match: {
|
|
785
|
+
commands: ['put', 'রাখুন'],
|
|
786
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
787
|
+
// Standalone put only (e.g. a then-chain clause): an event handler whose
|
|
788
|
+
// action is `put` must keep the event mid-stream, so don't verb-final it.
|
|
789
|
+
predicate: parsed => !parsed.roles.has('event'),
|
|
790
|
+
},
|
|
791
|
+
transform: {
|
|
792
|
+
// X কে Y তে রাখুন (patient, destination, verb-last)
|
|
793
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
794
|
+
insertMarkers: true,
|
|
795
|
+
},
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
name: 'set-to',
|
|
799
|
+
description: 'Transform set X to Y to Bengali verb-final order',
|
|
800
|
+
priority: 90,
|
|
801
|
+
match: {
|
|
802
|
+
commands: ['set', 'সেট'],
|
|
803
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
804
|
+
// Skip a set whose value swept up a trailing block terminator (`set X to Y
|
|
805
|
+
// end` — the body of an inline `if … then set … end`): verb-final reorder
|
|
806
|
+
// would push the verb past `end` and break the block. These parse fine
|
|
807
|
+
// verb-medial (the default).
|
|
808
|
+
predicate: parsed => !/(^|\s)end$/i.test((parsed.original ?? '').trim()),
|
|
809
|
+
},
|
|
810
|
+
transform: {
|
|
811
|
+
// X কে Y তে সেট — verb-final, matching the generated SOV set pattern.
|
|
812
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
813
|
+
insertMarkers: true,
|
|
814
|
+
},
|
|
815
|
+
},
|
|
816
|
+
{
|
|
817
|
+
name: 'bind-to',
|
|
818
|
+
description: 'Transform bind $var to #el to Bengali verb-final order',
|
|
819
|
+
priority: 90,
|
|
820
|
+
match: {
|
|
821
|
+
commands: ['bind', 'বাইন্ড'],
|
|
822
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
823
|
+
},
|
|
824
|
+
transform: {
|
|
825
|
+
// $var কে #el তে বাইন্ড
|
|
826
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
827
|
+
insertMarkers: true,
|
|
828
|
+
},
|
|
829
|
+
},
|
|
571
830
|
],
|
|
572
831
|
};
|
|
573
832
|
|
|
@@ -726,6 +985,61 @@ export const hindiProfile: LanguageProfile = {
|
|
|
726
985
|
insertMarkers: true,
|
|
727
986
|
},
|
|
728
987
|
},
|
|
988
|
+
{
|
|
989
|
+
name: 'put-into',
|
|
990
|
+
description: 'Transform put X into Y to Hindi verb-final order',
|
|
991
|
+
priority: 90,
|
|
992
|
+
match: {
|
|
993
|
+
commands: ['put', 'रखें'],
|
|
994
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
995
|
+
},
|
|
996
|
+
transform: {
|
|
997
|
+
// "hi" को #out में रखें
|
|
998
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
999
|
+
insertMarkers: true,
|
|
1000
|
+
},
|
|
1001
|
+
},
|
|
1002
|
+
{
|
|
1003
|
+
name: 'set-to',
|
|
1004
|
+
description: 'Transform set X to Y to Hindi verb-final order',
|
|
1005
|
+
priority: 90,
|
|
1006
|
+
match: {
|
|
1007
|
+
commands: ['set', 'सेट'],
|
|
1008
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
1009
|
+
// Skip a set whose value swept up a trailing block terminator (`set X to Y
|
|
1010
|
+
// end` — the body of an inline `if … then set … end`): verb-final reorder
|
|
1011
|
+
// would push the verb past `end` and break the block. These parse fine
|
|
1012
|
+
// verb-medial (the default).
|
|
1013
|
+
predicate: parsed => !/(^|\s)end$/i.test((parsed.original ?? '').trim()),
|
|
1014
|
+
},
|
|
1015
|
+
transform: {
|
|
1016
|
+
// #x.innerText को इसका.name में सेट — verb-final, matching the generated
|
|
1017
|
+
// SOV set pattern (set schema markerOverride puts को on the destination /
|
|
1018
|
+
// में on the value). The default reorder emitted verb-MEDIAL
|
|
1019
|
+
// (`#x को सेट … में`), which no set pattern matched → bare-event fallback.
|
|
1020
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
1021
|
+
insertMarkers: true,
|
|
1022
|
+
},
|
|
1023
|
+
},
|
|
1024
|
+
{
|
|
1025
|
+
name: 'bind-to',
|
|
1026
|
+
description: 'Transform bind $var to #el to Hindi verb-final order',
|
|
1027
|
+
priority: 90,
|
|
1028
|
+
match: {
|
|
1029
|
+
commands: ['bind', 'बाइंड', 'बांधें'],
|
|
1030
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
1031
|
+
},
|
|
1032
|
+
transform: {
|
|
1033
|
+
// $greeting को #name-input में bind — verb-final, matching the generated SOV
|
|
1034
|
+
// bind pattern (`{destination} को {source} में bind`). The default reorder
|
|
1035
|
+
// emitted verb-MEDIAL (`$greeting को bind #name-input में`), which the
|
|
1036
|
+
// verb-final pattern never matched → the bare-event fallback mis-anchored
|
|
1037
|
+
// the fronted `$greeting` as a phantom `on` event (the rf=0.00 bind residue).
|
|
1038
|
+
// ja/ko/zh/tr/bn already carry this rule; hi was the only SOV gap.
|
|
1039
|
+
roleOrder: ['patient', 'destination', 'action'],
|
|
1040
|
+
insertMarkers: true,
|
|
1041
|
+
},
|
|
1042
|
+
},
|
|
729
1043
|
],
|
|
730
1044
|
};
|
|
731
1045
|
|
|
@@ -748,7 +1062,11 @@ export const tagalogProfile: LanguageProfile = {
|
|
|
748
1062
|
markers: [
|
|
749
1063
|
{ form: 'kapag', role: 'event', position: 'preposition', required: true },
|
|
750
1064
|
{ form: 'sa', role: 'destination', position: 'preposition', required: false },
|
|
751
|
-
|
|
1065
|
+
// mula_sa (underscore) matches the tl dict and the semantic profile's
|
|
1066
|
+
// source marker — the spaced form emitted two tokens the generated
|
|
1067
|
+
// patterns' single mula_sa literal could never match, so `remove X
|
|
1068
|
+
// mula sa Y` lost its source and the schema default fabricated me.
|
|
1069
|
+
{ form: 'mula_sa', role: 'source', position: 'preposition', required: false },
|
|
752
1070
|
{ form: 'nang', role: 'style', position: 'preposition', required: false },
|
|
753
1071
|
{ form: 'bilang', role: 'method', position: 'preposition', required: false },
|
|
754
1072
|
],
|
|
@@ -854,6 +1172,33 @@ export const hebrewProfile: LanguageProfile = {
|
|
|
854
1172
|
{ form: 'עם', role: 'style', position: 'preposition', required: false },
|
|
855
1173
|
{ form: 'כ', role: 'method', position: 'preposition', required: false },
|
|
856
1174
|
],
|
|
1175
|
+
|
|
1176
|
+
rules: [
|
|
1177
|
+
{
|
|
1178
|
+
name: 'bind-to',
|
|
1179
|
+
description: 'Bind binds a variable to an element: קשור X ל Y',
|
|
1180
|
+
priority: 90,
|
|
1181
|
+
match: {
|
|
1182
|
+
commands: ['bind', 'קשור'],
|
|
1183
|
+
requiredRoles: ['action', 'patient', 'destination'],
|
|
1184
|
+
},
|
|
1185
|
+
transform: {
|
|
1186
|
+
// The bound variable is the semantic destination (kept bare, no את
|
|
1187
|
+
// object marker), and ל marks the target element. Custom so the
|
|
1188
|
+
// variable does not pick up את and the element uses ל (not על).
|
|
1189
|
+
roleOrder: ['action', 'patient', 'destination'],
|
|
1190
|
+
custom: parsed => {
|
|
1191
|
+
const action = parsed.roles.get('action');
|
|
1192
|
+
const patient = parsed.roles.get('patient');
|
|
1193
|
+
const destination = parsed.roles.get('destination');
|
|
1194
|
+
const verb = action?.translated || action?.value || '';
|
|
1195
|
+
const v = patient?.translated || patient?.value || '';
|
|
1196
|
+
const d = destination?.translated || destination?.value || '';
|
|
1197
|
+
return [verb, v, 'ל', d].filter(Boolean).join(' ');
|
|
1198
|
+
},
|
|
1199
|
+
},
|
|
1200
|
+
},
|
|
1201
|
+
],
|
|
857
1202
|
};
|
|
858
1203
|
|
|
859
1204
|
// =============================================================================
|
|
@@ -872,6 +1217,7 @@ export const profiles: Record<string, LanguageProfile> = {
|
|
|
872
1217
|
fr: frenchProfile,
|
|
873
1218
|
pt: portugueseProfile,
|
|
874
1219
|
id: indonesianProfile,
|
|
1220
|
+
ms: malayProfile,
|
|
875
1221
|
qu: quechuaProfile,
|
|
876
1222
|
sw: swahiliProfile,
|
|
877
1223
|
bn: bengaliProfile,
|