Šķîþ ţö ḿàîñ çöñţéñţ

ĴàṽàŠçŕîþţ Šçŕîþţ Šţéþ

Ţĥé script ţööļ ŕüñš ýöüŕ ÉŠ5 ĴàṽàŠçŕîþţ öñ éàçĥ Þàŕţ ţĥàţ þàššéš ţĥŕöüĝĥ à ƒļöŵ. Üšé îţ ţö ƒîļţéŕ, ŕöüţé öŕ éđîţ Þàŕţš ŵîţĥöüţ ŵŕîţîñĝ à Ĝö ţööļ.

Ţĥé ŕüñţîḿé îš ĝöĵà, à þüŕé Ĝö ÉŠ5 éñĝîñé ŵîţĥ ñö çĝö đéþéñđéñçý.

Ĥöŵ îţ ŵöŕķš​

Ţĥé šçŕîþţ ţööļ ŕéçéîṽéš éàçĥ Þàŕţ öñé àţ à ţîḿé. Ƒöŕ éàçĥ Þàŕţ, ýöüŕ šçŕîþţ ŕüñš ŵîţĥ àççéšš ţö à part öƃĵéçţ àñđ ţĥŕéé çöñţŕöļ ƒüñçţîöñš: emit(), skip(), àñđ log(). ΃ ýöüŕ šçŕîþţ çàļļš ñéîţĥéŕ emit() ñöŕ skip(), ţĥé Þàŕţ þàššéš ţĥŕöüĝĥ üñçĥàñĝéđ.

Ýöü çàñ ŵŕîţé ýöüŕ ļöĝîç îñ éîţĥéŕ öƒ ţŵö éǫüîṽàļéñţ ƒöŕḿš: àš ţöþ-ļéṽéļ çöđé àĝàîñšţ ţĥé îḿþļîçîţ part ĝļöƃàļ (üšéđ ţĥŕöüĝĥöüţ ţĥé éẋàḿþļéš ƃéļöŵ), öŕ àš à function process(part) ţĥàţ ţĥé ţööļ çàļļš öñçé þéŕ Þàŕţ (šéé Ƒüñçţîöñ ƒöŕḿ). Ƃöţĥ ĥàṽé îđéñţîçàļ çàþàƃîļîţîéš; ţĥé ƒüñçţîöñ ƒöŕḿ àđđš à ŕéţüŕñ-ṽàļüé çöñṽéñîéñçé.

Ţĥé ĴàṽàŠçŕîþţ ÀÞÎ​

Ţĥé þàŕţ öƃĵéçţ​

part.type; // "block", "data", "media", "layer-start", "layer-end",
// "group-start", "group-end"

Ƒöŕ ƃļöçķ þàŕţš, ţĥé block þŕöþéŕţý þŕöṽîđéš àççéšš ţö ţŕàñšļàţàƃļé çöñţéñţ:

part.block.id; // Block ID string
part.block.translatable; // boolean

// Source runs (flat array)
part.block.source[0].content.text; // text of the first run

// Target runs by locale (object)
part.block.targets["fr"][0].content.text; // French target's first run text

éḿîţ(þàŕţ)​

Éḿîţ à ḿöđîƒîéđ (öŕ ñéŵ) Þàŕţ ţö ţĥé öüţþüţ çĥàññéļ. Öñçé ýöü çàļļ emit(), öñļý ŵĥàţ ýöü éḿîţ ŕéàçĥéš đöŵñšţŕéàḿ ţööļš, àñđ ţĥé öŕîĝîñàļ Þàŕţ îš đŕöþþéđ.

// Modify a target translation and emit
if (part.block.targets["fr"]) {
var seg = part.block.targets["fr"][0];
seg.content.text = seg.content.text.toUpperCase();
}
emit(part);

Ƃý đéƒàüļţ ţĥé šçŕîþţ ḿàý ŕéàđ ţĥé šöüŕçé ƃüţ öñļý ţàŕĝéţ éđîţš àŕé ŕéàđ ƃàçķ, ƃéçàüšé ţĥé šöüŕçé îš ŕéàđ-öñļý (šéé Çöñƒîĝüŕàţîöñ ŕéƒéŕéñçé).

šķîþ()​

Đŕöþ ţĥé çüŕŕéñţ Þàŕţ. Đöŵñšţŕéàḿ ţööļš àñđ ţĥé ŵŕîţéŕ ñéṽéŕ šéé îţ.

if (part.type === "block" && part.block.source[0].content.text === "") {
skip();
}

ļöĝ(ḿéššàĝé)​

Ŵŕîţé à ḿéššàĝé ţö šţđéŕŕ ƒöŕ đéƃüĝĝîñĝ.

log("Processing block: " + part.block.id);

Çöñţŕöļ ƒļöŵ šüḿḿàŕý​

Šçŕîþţ ƃéĥàṽîöŕŔéšüļţ
Ñö emit() öŕ skip() çàļļéđÞàŕţ þàššéš ţĥŕöüĝĥ üñçĥàñĝéđ
emit(part) çàļļéđÖñļý éḿîţţéđ þàŕţš àŕé ƒöŕŵàŕđéđ
skip() çàļļéđÞàŕţ îš đŕöþþéđ
emit() çàļļéđ ḿüļţîþļé ţîḿéšÀļļ éḿîţţéđ þàŕţš àŕé ƒöŕŵàŕđéđ (öñé-ţö-ḿàñý)

Ƒüñçţîöñ ƒöŕḿ​

Îñšţéàđ öƒ ŵŕîţîñĝ ţöþ-ļéṽéļ çöđé àĝàîñšţ ţĥé îḿþļîçîţ part ĝļöƃàļ, ýöü çàñ đéƒîñé à process ƒüñçţîöñ. Ţĥé ţööļ çàļļš îţ öñçé þéŕ Þàŕţ, þàššîñĝ ţĥé þàŕţ àš îţš àŕĝüḿéñţ:

function process(part) {
if (part.type === "block" && part.block.targets["fr"]) {
var seg = part.block.targets["fr"][0];
seg.content.text = seg.content.text.toUpperCase();
}
return part; // emit the (modified) part
}

Îñšîđé process, emit(), skip(), àñđ log() ƃéĥàṽé éẋàçţļý àš îñ ţĥé îḿþļîçîţ-ĝļöƃàļš ƒöŕḿ. Àš à çöñṽéñîéñçé, ţĥé ƒüñçţîöñ'š ŕéţüŕñ ṽàļüé îš àļšö ĥöñöŕéđ, ƃüţ öñļý ŵĥéñ ýöü ĥàṽé ñöţ àļŕéàđý çàļļéđ emit() öŕ skip() (àñ éẋþļîçîţ çàļļ àļŵàýš ŵîñš):

process(part) ŕéţüŕñšŔéšüļţ
à þàŕţ öƃĵéçţţĥàţ þàŕţ îš éḿîţţéđ
àñ àŕŕàý öƒ þàŕţšàļļ àŕé éḿîţţéđ (öñé-ţö-ḿàñý)
nullţĥé þàŕţ îš đŕöþþéđ (éǫüîṽàļéñţ ţö skip())
ñöţĥîñĝ (undefined)ţĥé þàŕţ þàššéš ţĥŕöüĝĥ üñçĥàñĝéđ

Ţĥé ƒüñçţîöñ ƒöŕḿ ŵöŕķš îđéñţîçàļļý ŵîţĥ --code, --script-file, àñđ ţĥé ÝÀḾĻ code/scriptFile çöñƒîĝ. Îţ ŕéàđš ñàţüŕàļļý ƒöŕ ţŕàñšƒöŕḿš ţĥàţ çöḿþüţé àñđ ŕéţüŕñ à ŕéšüļţ; ţĥé îḿþļîçîţ-ĝļöƃàļš ƒöŕḿ îš ţéŕšéŕ ƒöŕ šîḿþļé ƒîļţéŕš. Šöüŕçé éđîţš šţîļļ ŕéǫüîŕé allowSourceMutation (šéé Çöñƒîĝüŕàţîöñ ŕéƒéŕéñçé) îñ éîţĥéŕ ƒöŕḿ.

ÇĻÎ üšàĝé​

Îñļîñé çöđé​

kapi exec script -i input.xliff --code 'if (part.type === "block") {
var text = part.block.source[0].content.text;
if (text.length > 100) { skip(); }
}'

Šçŕîþţ ƒîļé​

kapi exec script -i input.xliff --script-file filter.js

Ŵĥéŕé filter.js çöñţàîñš:

if (part.type === "block") {
var text = part.block.source[0].content.text;
if (text.length <= 5) {
skip();
}
}

ÝÀḾĻ ƒļöŵ üšàĝé​

Üšé ţĥé šçŕîþţ šţéþ îñļîñé îñ à ƒļöŵ đéƒîñîţîöñ:

steps:
- tool: script
label: Filter short segments
config:
code: |
if (part.type === 'block') {
var text = part.block.source[0].content.text;
if (text.length < 3) {
skip();
}
}

- tool: pseudo-translate
config:
targetLocale: fr

Öŕ ŕéƒéŕéñçé àñ éẋţéŕñàļ ƒîļé:

steps:
- tool: script
config:
scriptFile: ./scripts/filter.js

- tool: pseudo-translate
config:
targetLocale: fr

Éẋàḿþļéš​

Ƒîļţéŕ ƃý šöüŕçé ţéẋţ ļéñĝţĥ​

Šķîþ ƃļöçķš ŵĥéŕé ţĥé šöüŕçé ţéẋţ îš šĥöŕţéŕ ţĥàñ à ţĥŕéšĥöļđ:

if (part.type === "block") {
var text = part.block.source[0].content.text;
if (text.length < 10) {
skip();
}
}

Ḿöđîƒý ţàŕĝéţ ţéẋţ​

Àþþéñđ à ḿàŕķéŕ ţö àļļ Ƒŕéñçĥ ţŕàñšļàţîöñš:

if (part.type === "block" && part.block.targets["fr"]) {
var seg = part.block.targets["fr"][0];
seg.content.text = seg.content.text + " [REVIEW]";
emit(part);
}

Çöñđîţîöñàļ ŕöüţîñĝ​

Öñļý þàšš ţŕàñšļàţàƃļé ƃļöçķš ţĥŕöüĝĥ ţö đöŵñšţŕéàḿ ţööļš:

if (part.type !== "block") {
// Let structural parts (layers, data) pass through
emit(part);
} else if (part.block.translatable) {
emit(part);
} else {
skip();
}

Ţŕàñšƒöŕḿ šöüŕçé ţéẋţ​

Ñöŕḿàļîžé ŵĥîţéšþàçé îñ ţĥé šöüŕçé ƃéƒöŕé ţŕàñšļàţîöñ. Šöüŕçé éđîţš àŕé îĝñöŕéđ ƃý đéƒàüļţ, ƃéçàüšé ţĥé šöüŕçé îš ŕéàđ-öñļý ţö ţĥé šçŕîþţ (îḿḿüţàƃîļîţý çöñţŕàçţ). Öþţ îñ ŵîţĥ allowSourceMutation: true, àñđ þļàçé ţĥé šţéþ àĥéàđ öƒ ţĥé šţéþš ţĥàţ šĥöüļđ öƃšéŕṽé ţĥé ŕéŵŕîţţéñ šöüŕçé, ţýþîçàļļý ƒîŕšţ (šéé ƒļöŵ àüţĥöŕîñĝ):

steps:
- tool: script
config:
allowSourceMutation: true
code: |
if (part.type === 'block') {
var text = part.block.source[0].content.text;
text = text.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '');
part.block.source[0].content.text = text;
emit(part);
}
- tool: translate

Ļöĝ àñđ þàšš ţĥŕöüĝĥ​

Îñšþéçţ ţĥé þîþéļîñé ŵîţĥöüţ çĥàñĝîñĝ àñýţĥîñĝ:

if (part.type === "block") {
log("Block " + part.block.id + ": " + part.block.source[0].content.text);
}
// No emit() or skip() -- part passes through unchanged

Çöñƒîĝüŕàţîöñ ŕéƒéŕéñçé​

ÞŕöþéŕţýŢýþéĐéšçŕîþţîöñ
sourcešţŕîñĝḾöđé šéļéçţöŕ: inline (đéƒàüļţ) öŕ file
codešţŕîñĝÎñļîñé ĴàṽàŠçŕîþţ çöđé (ÉŠ5)
scriptFilešţŕîñĝÞàţĥ ţö à .js ƒîļé
allowSourceMutationƃööļéàñÞéŕḿîţ ţĥé šçŕîþţ ţö ḿöđîƒý ţĥé šöüŕçé ţéẋţ. Öƒƒ ƃý đéƒàüļţ: ţĥé šöüŕçé îš ŕéàđ-öñļý àñđ šöüŕçé éđîţš àŕé îĝñöŕéđ üñļéšš ţĥîš îš šéţ.

Þŕöṽîđé éîţĥéŕ code öŕ scriptFile. Ţĥé öþţîöñàļ source ƒîéļđ šéļéçţš ţĥé ḿöđé éẋþļîçîţļý (inline öŕ file) ƒöŕ ÜÎ àñđ ṽàļîđàţîöñ; ŵĥéñ öḿîţţéđ, ţĥé ḿöđé îš îñƒéŕŕéđ ƒŕöḿ ŵĥîçĥéṽéŕ öƒ code/scriptFile îš šéţ.

Ñöţéš​

  • Ţĥé ŕüñţîḿé îš ÉŠ5 öñļý (ñö let, const, àŕŕöŵ ƒüñçţîöñš, öŕ ţéḿþļàţé ļîţéŕàļš). Üšé var ƒöŕ ṽàŕîàƃļé đéçļàŕàţîöñš.
  • Éàçĥ ţööļ îñšţàñçé ĝéţš îţš öŵñ ĝöĵà ŕüñţîḿé, šö ţŵö šçŕîþţ šţéþš šĥàŕé ñö šţàţé.
  • Ţĥé šçŕîþţ ŕüñš šýñçĥŕöñöüšļý ƒöŕ éàçĥ Þàŕţ. À ļöñĝ-ŕüññîñĝ šçŕîþţ ƃļöçķš ţĥé ƒļöŵ.
  • Ţàŕĝéţ ţéẋţ éđîţš öñ ƃļöçķ þàŕţš àŕé ŕéàđ ƃàçķ. Šöüŕçé éđîţš àŕé ŕéàđ ƃàçķ öñļý ŵĥéñ allowSourceMutation: true; öţĥéŕŵîšé ţĥé šöüŕçé îš ŕéàđ-öñļý. Çĥàñĝéš ţö öţĥéŕ Þàŕţ ţýþéš àŕé ñöţ þéŕšîšţéđ.

Ŕéļàţéđ​