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

Çöñţéñţ-Ƒîđéļîţý Šüŕƒàçîñĝ

Ţàçţîçàļ ĝüîđé ƒöŕ à ƒöŕḿàţ àüţĥöŕ àđđîñĝ çöñţéñţ-ƒîđéļîţý šüŕƒàçîñĝ: ḿàķîñĝ çöñţéẋţüàļ çöñţéñţ (îḿàĝé àñđ šĥàþé àļţ-ţéẋţ, çöđé ƃļöçķš, çàþţîöñš, ƒöŕḿüļàš, đö-ñöţ-ţŕàñšļàţé šţŕîñĝš, çöñƒîĝ-éẋçļüđéđ ṽàļüéš, çöḿḿéñţš, đöçüḿéñţ ḿéţàđàţà) ṽîšîƃļé ţö îñĝéšţîöñ àñđ ĻĻḾ/ŔÀĜ çöñšüḿéŕš ŵĥîļé ḿàçĥîñé ţŕàñšļàţîöñ šķîþš îţ àñđ ţĥé ŕöüñđ-ţŕîþ šţàýš ƃýţé-éẋàçţ. Þàŕéñţ ÀĐ: É-02: Ţĥé ƒöŕḿàţ šýšţéḿ (ŕéàđéŕ öüţþüţ þöļîçý). Ƒöŕ ţĥé ĝéñéŕàļ þöŕţ ŕéçîþé šéé Îḿþļéḿéñţîñĝ Ƒöŕḿàţš, àñđ ţĥé šķéļéţöñ ḿéçĥàñîçš îñ Šķéļéţöñ Šţöŕé àñđ Šţŕéàḿîñĝ ĤŢḾĻ.

Šüŕƒàçîñĝ îš à ŕîçĥéŕ đéƒàüļţ, ñöţ à ñéŵ šţŕüçţüŕàļ ţýþé. Ţĥé ŕöļéš îţ ļéàñš öñ (RoleCode, RoleFormula, RoleCaption, … îñ core/model/structure.go) àļŕéàđý éẋîšţ; ŵĥàţ à ƒöŕḿàţ àđđš îš à ŕéàđéŕ ţĥàţ üšéš ţĥéḿ ţö éḿîţ çöñţéñţ ţĥàţ ŵöüļđ öţĥéŕŵîšé ƃé çàŕŕîéđ öñļý àš šķéļéţöñ ƃýţéš.

Ţĥé šüŕƒàçîñĝ ţöĝĝļé: àñ îñṽéŕţéđ þŕîṽàţé ƒîéļđ

À šüŕƒàçîñĝ-çàþàƃļé çöñƒîĝ çàŕŕîéš öñé ƃööļéàñ ŵĥöšé žéŕö ṽàļüé ḿéàñš šüŕƒàçîñĝ îš ÖÑ. Ţĥé ƒîéļđ îš þŕîṽàţé àñđ îñṽéŕţéđ šö ţĥé ŕîçĥ đéƒàüļţ ƒàļļš öüţ öƒ Config{} ŵîţĥöüţ à Reset() àššîĝñḿéñţ (ţĥé nonFoo çöñṽéñţîöñ đöçüḿéñţéđ îñ Îḿþļéḿéñţîñĝ Ƒöŕḿàţš) ("bool đéƒàüļţš ţö false, šö üšé nonFoo ñàḿîñĝ ŵĥéñ ýöü ŵàñţ ţĥé đéƒàüļţ ƃéĥàṽîöŕ ţö ƃé foo").

// core/formats/openxml/config.go
type Config struct {
// … common toggles …

// disableNonTranslatableContent, when set, keeps non-translatable
// contextual content in opaque skeleton / verbatim parts instead of
// surfacing it. Zero value = surfacing ON (the opt-out default).
disableNonTranslatableContent bool
}

Ñàḿîñĝ ţĥé ƒîéļđ disableNonTranslatableContent (ŕàţĥéŕ ţĥàñ à þöšîţîṽé extractNonTranslatableContent bool ţĥàţ Reset() ḿüšţ ŕéḿéḿƃéŕ ţö šéţ true) ķééþš ţĥé öñ-ƃý-đéƒàüļţ ƃéĥàṽîöŕ ţŕüé éṽéñ ƒöŕ à Config{} ļîţéŕàļ ţĥàţ ñéṽéŕ ŕüñš Reset(): à ŕéàđéŕ çöñšţŕüçţéđ îñ à ţéšţ, öŕ àñý çàļļéŕ ţĥàţ ḿüţàţéš öñé ƒîéļđ àñđ ƒöŕĝéţš ţĥé ŕéšţ. Reset() šţîļļ þîñš îţ éẋþļîçîţļý ƒöŕ đöçüḿéñţàţîöñ ṽàļüé:

func (c *Config) Reset() {
// … other defaults …
c.disableNonTranslatableContent = false // surfacing ON
}

Ţĥé ĝéţţéŕ / šéţţéŕ / ÀþþļýḾàþ / šçĥéḿà ǫüàŕţéţ

Ţĥé þŕîṽàţé ƒîéļđ îš éẋþöšéđ ţĥŕöüĝĥ ƒöüŕ çööŕđîñàţéđ šüŕƒàçéš. Ķééþ ţĥé ñàḿéš àñđ ţĥé þüƃļîç ķéý (extractNonTranslatableContent, þöšîţîṽé šéñšé) ƃýţé-îđéñţîçàļ àçŕöšš àļļ öƒ ţĥéḿ; ţĥé đüçķ-ţýþéđ þàŕîţý ĥööķ (ƃéļöŵ) àñđ ţĥé ĝéñéŕàţéđ ŕéƒéŕéñçé ƃöţĥ ƃîñđ ţö ţĥéḿ ƃý ñàḿé.

Ĝéţţéŕ àñđ šéţţéŕ (core/formats/openxml/config.go) þŕéšéñţ ţĥé þöšîţîṽé šéñšé àñđ àƃšöŕƃ ţĥé îñṽéŕšîöñ, šö ñö çàļļéŕ éṽéŕ šééš disable…:

func (c *Config) ExtractNonTranslatableContent() bool {
return !c.disableNonTranslatableContent
}

func (c *Config) SetExtractNonTranslatableContent(v bool) {
c.disableNonTranslatableContent = !v
}

ÀþþļýḾàþ ķéý (šàḿé ƒîļé) đéçöđéš ţĥé þöšîţîṽé þüƃļîç ķéý: ŕéçîþéš, þŕéšéţš, àñđ ţĥé ÇĻÎ šþéàķ extractNonTranslatableContent, ñéṽéŕ ţĥé þŕîṽàţé ƒîéļđ:

case "extractNonTranslatableContent":
c.disableNonTranslatableContent = !toBool(val)

schema.Prop (core/formats/openxml/schema.go) àđṽéŕţîšéš ţĥé ţöĝĝļé ţö ţĥé ĝéñéŕàţéđ /reference/formats þàĝé àñđ ţö šçĥéḿà-đŕîṽéñ çöñƒîĝ ÜΚ, ŵîţĥ Default: true ţö ḿàţçĥ ţĥé žéŕö ṽàļüé'š ƃéĥàṽîöŕ. Ţĥé ƒîéļđ îš àļšö ļîšţéđ îñ à ParameterGroup (ţĥé "general" ĝŕöüþ) šö îţ ŕéñđéŕš:

"extractNonTranslatableContent": schema.Prop(coreschema.PropertySchema{
Type: "boolean",
Title: "Extract non-translatable content",
Default: true,
Description: "If true (default), non-translatable contextual content is " +
"surfaced, image/shape alt-text (descr/title on docPr/cNvPr) as " +
"content blocks (visible to ingestion/LLM consumers, skipped by " +
"machine translation), and PowerPoint/Excel comment text as data " +
"parts, instead of being hidden in opaque skeleton. Disable to keep " +
"it opaque.",
}),

Ţĥé đüçķ-ţýþéđ éẋţéñšîöñ þöîñţ

Ţĥéŕé îš ñö format.DataFormatConfig ḿéţĥöđ ƒöŕ šüŕƒàçîñĝ; îţ îš àñ öþţîöñàļ çàþàƃîļîţý đîšçöṽéŕéđ šţŕüçţüŕàļļý. Àñý çöñšüḿéŕ ţĥàţ ñééđš ţö ƒöŕçé ţĥé ţöĝĝļé ţýþé-àššéŕţš ţĥé àñöñýḿöüš îñţéŕƒàçé, šö à çöñƒîĝ ţĥàţ ļàçķš ţĥé šéţţéŕ îš ļéƒţ àţ îţš öŵñ đéƒàüļţ:

// cli/parity/spec/runner.go (runNative)
if c := reader.Config(); c != nil {
if d, ok := c.(interface{ SetExtractNonTranslatableContent(bool) }); ok {
d.SetExtractNonTranslatableContent(false)
}
}

Ţĥé þàŕîţý ŕüññéŕ üšéš ţĥîš ţö ƒöŕçé šüŕƒàçîñĝ öƒƒ ƒöŕ ţĥé ĥéàđ-ţö-ĥéàđ: ţĥé okapi-bridge ĥàš ñö ñöţîöñ öƒ šüŕƒàçîñĝ, šö ţĥé ñàţîṽé ŕéàđéŕ ḿüšţ ŕéþŕöđüçé ţĥé ƃŕîđĝé'š öþàǫüé-šķéļéţöñ öüţþüţ ŵĥéñ ĥàñđéđ ţĥé ḿàţçĥîñĝ šéḿàñţîç çöñƒîĝ. Ţĥîš îš ţĥé çöñçŕéţé ŕéàļîžàţîöñ öƒ ţĥé þàŕîţý çöñţŕàçţ (šàḿé šéḿàñţîç çöñƒîĝ → šàḿé ŕéšüļţš), ŵĥîļé ļéţţîñĝ ñàţîṽé ŕéàđéŕš þîçķ ţĥé ŕîçĥéŕ đéƒàüļţ. Éẋþöšîñĝ éẋàçţļý SetExtractNonTranslatableContent(bool) (ñö ḿöŕé, ñö ļéšš) îš ţĥéŕéƒöŕé ţĥé çöñţŕàçţ à ñéŵ šüŕƒàçîñĝ ƒöŕḿàţ ḿüšţ ĥöñöŕ ţö þàŕţîçîþàţé îñ þàŕîţý (šéé À-02: Þàŕîţý Ţéšţîñĝ).

Çĥàññéļ 1: ŕéñđéŕàƃļé çöñţéñţ àš à ñöñ-ţŕàñšļàţàƃļé Ƃļöçķ

Çöñţéñţ ţĥàţ îš ŕéñđéŕéđ îñ ţĥé đöçüḿéñţ ƃüţ ḿüšţ ñöţ ƃé ţŕàñšļàţéđ (àļţ-ţéẋţ, çöđé, çàþţîöñš, ƒöŕḿüļàš, đö-ñöţ-ţŕàñšļàţé šţŕîñĝš, çöñƒîĝ-éẋçļüđéđ ṽàļüéš) îš šüŕƒàçéđ àš à model.Block ŵîţĥ Translatable: false, ţàĝĝéđ ŵîţĥ à SemanticRole, àñđ ŕéƒéŕéñçéđ ƒŕöḿ ţĥé šķéļéţöñ šö îţ ŕöüñđ-ţŕîþš ƃý ÎĐ. Ƃéçàüšé ţĥé ƃļöçķ ĥöļđš ţĥé ṽàļüé, àñ üñţŕàñšļàţéđ ŕéàđ ŕéþļàýš ţĥé öŕîĝîñàļ ƃýţéš àñđ à ţŕàñšļàţéđ öñé šþļîçéš ţĥé ñéŵ ţéẋţ îñ þļàçé; ţĥé šţŕüçţüŕé îš ñéṽéŕ đîšţüŕƃéđ.

// core/formats/openxml/dml.go (emitDrawingProp): image/shape alt-text
block := &model.Block{
ID: id,
Type: "property",
Translatable: false,
Source: []model.Run{{Text: &model.TextRun{Text: a.Value}}},
Targets: make(map[model.VariantKey]*model.Target),
Properties: map[string]string{"partPath": partPath, "element": element},
}
block.SetSemanticRole(model.RoleCaption, 0) // func (b *Block) SetSemanticRole(role string, level int)
emitBlock(block)
return id // caller writes a skeleton Ref to this id

Ţĥé ƃýţé-éẋàçţ ĝüàŕàñţéé çöḿéš ƒŕöḿ ţĥé šķéļéţöñ ŕéƒ, ñöţ ƒŕöḿ ţĥé ƃļöçķ. Ţĥé ŵŕîţéŕ éḿîţš šķéļéţöñ ţéẋţ ƒöŕ ţĥé ļîţéŕàļ šüŕŕöüñđîñĝ ḿàŕķüþ àñđ à SkeletonRef ŵĥéŕé ţĥé ṽàļüé ƃéļöñĝš:

// core/model/skeleton.go
type SkeletonRef struct {
ResourceID string // the surfaced block's ID
Property string // which property to reference, e.g. "target" / "source"
Locale string // target locale for locale-specific references
}

Þîçķ ţĥé çļöšéšţ éẋîšţîñĝ ŕöļé ƒŕöḿ core/model/structure.go: RoleCaption ƒöŕ àļţ-ţéẋţ/öƃĵéçţ ţîţļéš, RoleCode ƒöŕ çöđé, RoleFormula ƒöŕ éǫüàţîöñš, àñđ šö öñ. Đö ñöţ îñṽéñţ à ŕöļé ƒöŕ à šüŕƒàçîñĝ çàšé; ţĥé ŕöļé îš ţĥé šţàƃļé ĥàñđļé ţĥàţ šéḿàñţîç éẋþöŕţ, ţĥé éđîţöŕ, àñđ îñĝéšţîöñ üšé ţö ŕéçöĝñîžé ţĥé çöñţéñţ ŵîţĥöüţ ţŕéàţîñĝ îţ àš ḾŢ îñþüţ. ḾŢ šķîþš îţ ƃéçàüšé Translatable îš false (É-07); ŔÀĜ šééš îţ ƃéçàüšé îţ îš à þàŕţ îñ ţĥé šţŕéàḿ ŕàţĥéŕ ţĥàñ ƃüŕîéđ îñ ţĥé šķéļéţöñ.

Éǫüàţîöñš àŕé ţĥé ŕîçĥéŕ îñšţàñçé öƒ ţĥîš çĥàññéļ: àñ îñļîñé ƒöŕḿüļà šüŕƒàçéš àš à þļàçéĥöļđéŕ ŕüñ çàŕŕýîñĝ îţš þöŕţàƃļé ŕéñđéŕîñĝ, à šţàñđàļöñé éǫüàţîöñ àš à đéţàçĥéđ RoleFormula ƃļöçķ, àñđ ţĥé ñàţüŕàļ-ļàñĝüàĝé þŕöšé éḿƃéđđéđ îñšîđé àñ éǫüàţîöñ îš ŵŕîţţéñ ƃàçķ ţĥŕöüĝĥ à šüƃ-šķéļéţöñ. Šéé ÖḾḾĻ Ḿàţĥ Çöñṽéŕšîöñ ƒöŕ ţĥé ƒöŕḿüļà-šþéçîƒîç šüŕƒàçîñĝ àñđ îţš ƃýţé-éẋàçţ šþļîçé.

À šţöŕéđ ṽàļüé ƃéšîđé îţš đîšþļàý

À šþŕéàđšĥééţ ṽàļüé çéļļ šţöŕéš à ñüḿƃéŕ àñđ šĥöŵš îţ ţĥŕöüĝĥ à ñüḿƃéŕ ƒöŕḿàţ: à đàţé îš à šéŕîàļ đàý çöüñţ, à þéŕçéñţàĝé à ƒŕàçţîöñ, à þŕîçé à ƃàŕé đéçîḿàļ. Ţĥé ŵöŕķšĥééţ ŕéàđéŕ šüŕƒàçéš šüçĥ à çéļļ àš à ñöñ-ţŕàñšļàţàƃļé ĝŕîđ àñçĥöŕ ŵĥöšé ţéẋţ îš ţĥé ṽàļüé àš šţöŕéđ, àñđ šţàḿþš ţĥé ṽàļüé àš ţĥé šĥééţ đîšþļàýš îţ ƃéšîđé îţ:

// core/formats/openxml/sml.go (emitLiteralCellAnchor)
Source: []model.Run{{Text: &model.TextRun{Text: "44197"}}},
Properties: map[string]string{
"partPath": partPath,
"cell": "A2",
model.PropCellDisplay: "01-01-21", // what the sheet shows
model.PropCellFormat: "mm-dd-yy", // the number-format code it shows it through
},

Ţĥé šţöŕéđ ṽàļüé šţàýš ţĥé ƃļöçķ'š çöñţéñţ, šö ţĥé šķéļéţöñ, ţĥé ƃļöçķ'š îđéñţîţý àñđ ţĥé ŕöüñđ-ţŕîþ šéé ñöţĥîñĝ ƃüţ ŵĥàţ ţĥé ƒîļé ĥöļđš. Éṽéŕý çöñšüḿéŕ ţĥàţ ŕéñđéŕš à ţàƃļé çéļļ ŕéàđš ţĥé đîšþļàý ţĥŕöüĝĥ öñé ƒüñçţîöñ, projection.DisplayRuns, ŵĥîçĥ ŕéţüŕñš à šîñĝļé ţéẋţ ŕüñ öƒ ţĥé đîšþļàý ŵĥéñ ţĥé þŕöþéŕţý îš þŕéšéñţ àñđ ţĥé ƃļöçķ'š ŕüñš öţĥéŕŵîšé: ţĥé Ḿàŕķđöŵñ, ĤŢḾĻ, ÀšçîîĐöç àñđ ĐöçĻàñĝ ŵŕîţéŕš, ţĥé þŕöĵéçţîöñ ţŕéé ƃéĥîñđ kapi inspect àñđ ţĥé þŕéṽîéŵ, àñđ ţĥé þŕéṽîéŵ ķîţ'š öŵñ ŵöŕķšĥééţ ĝŕîđ àļļ ŕéñđéŕ ţĥé đàţé ŕàţĥéŕ ţĥàñ ţĥé šéŕîàļ. À ţéẋţ çéļļ çàŕŕîéš ñö đîšþļàý; îţš šĥàŕéđ-šţŕîñĝ öŕ îñļîñé ţéẋţ îš ŵĥàţ à ŕéàđéŕ ţŕàñšļàţéš àñđ ŵĥàţ ţĥé ĝŕîđ šĥöŵš.

Ţĥé ŕéàđéŕ ŕéšöļṽéš à çéļļ'š s àţţŕîƃüţé ţĥŕöüĝĥ ţĥé šţýļéšĥééţ'š cellXfs ţö à numFmtId, ţĥéñ ţö à çüšţöḿ numFmt çöđé öŕ ţĥé ƃüîļţ-îñ ţàƃļé öƒ ÉÇḾÀ-376 §18.8.30 (core/formats/openxml/sml_styles.go), àñđ ŕéàđš ţĥé ŵöŕķƃööķ'š date1904 éþöçĥ. Ţĥé ŕéñđéŕéŕ (numfmt.go, numfmt_date.go) çöṽéŕš Ĝéñéŕàļ, ƒîẋéđ đéçîḿàļš, ţĥöüšàñđš ĝŕöüþîñĝ àñđ šçàļîñĝ, þéŕçéñţ, šçîéñţîƒîç ñöţàţîöñ, ƒŕàçţîöñš, çüŕŕéñçý àñđ àççöüñţîñĝ ļîţéŕàļš, ţĥé đàţé àñđ ţîḿé þàţţéŕñ ļéţţéŕš ŵîţĥ ţĥé 1900 ļéàþ-ýéàŕ ǫüîŕķ, éļàþšéđ ţîḿé, ţĥé ţéẋţ þļàçéĥöļđéŕ, çöñđîţîöñš àñđ ţĥé þöšîţîṽé;ñéĝàţîṽé;žéŕö;ţéẋţ šéçţîöñš, îñ àñ îñṽàŕîàñţ éñ-ÜŠ ŕéñđéŕîñĝ. À çöđé îţ çàññöţ ŕéñđéŕ, öŕ à ṽàļüé ţĥé çöđé çàññöţ šĥöŵ, ļéàṽéš ţĥé đîšþļàý éǫüàļ ţö ţĥé šţöŕéđ ṽàļüé.

Çĥàññéļ 2: çöḿḿéñţš àñđ ḿéţàđàţà àš Đàţà öŕ à ñöţé

Çöñţéẋţ ţĥàţ îš àƃöüţ ţĥé çöñţéñţ ŕàţĥéŕ ţĥàñ ŕéñđéŕéđ àļöñĝšîđé îţ (àüţĥöŕîñĝ çöḿḿéñţš, ŕéṽîéŵéŕ ñöţéš, đéṽéļöþéŕ ḿéţàđàţà) šüŕƒàçéš ţĥŕöüĝĥ ţĥé šéçöñđ çĥàññéļ àñđ ñéṽéŕ ƃéçöḿéš à ţŕàñšļàţàƃļé šüŕƒàçé:

  • model.Data (PartData) ƒöŕ ƒŕéé-šţàñđîñĝ îñƒöŕḿàţîöñàļ çöñţéẋţ ŵĥöšé šöüŕçé þàŕţ îš àļŕéàđý çàþţüŕéđ ṽéŕƃàţîḿ îñ ţĥé šķéļéţöñ, šö ţĥé Đàţà þàŕţ îš þüŕéļý àđđîţîṽé àñđ çàññöţ þéŕţüŕƃ ţĥé ŕöüñđ-ţŕîþ. ÖþéñẊḾĻ üšéš ţĥîš ƒöŕ ÞÞŢẊ çöḿḿéñţ ƃöđîéš (<p:text>) ṽîà emitPPTXCommentData îñ core/formats/openxml/dml.go: ţĥé çöḿḿéñţ þàŕţ îš þàŕšéđ ṽéŕƃàţîḿ ƒöŕ šķéļéţöñ, àñđ ţĥé Đàţà þàŕţ îš éḿîţţéđ öñ ţĥé šîđé àñđ, þéŕ ţĥé çöñƒîĝ đöçüḿéñţàţîöñ, ƒöŕ ẊĻŠẊ çöḿḿéñţ ţéẋţ (<comment><text>) ţĥé šàḿé ŵàý.
  • NoteAnnotation ŵĥéñ ţĥé çöñţéẋţ îš àñçĥöŕéđ ţö à šþéçîƒîç ƃļöçķ, àţţàçĥ îţ ŵîţĥ Block.AddNote šö îţ ţŕàṽéļš ŵîţĥ ţĥàţ ƃļöçķ (ţĥîš îš ţĥé ñàţüŕàļ ĥöḿé ƒöŕ ÞÖ-šţýļé ţŕàñšļàţöŕ/éẋţŕàçţéđ çöḿḿéñţš):
// core/model/annotation.go
type NoteAnnotation struct {
Text string `json:"text"` // note text content
From string `json:"from,omitempty"` // who wrote it ("developer", "translator", …)
Priority int `json:"priority,omitempty"` // priority level (1 = highest)
Annotates string `json:"annotates,omitempty"` // "source", "target", "general"
}

// core/model/annotation_access.go
func (b *Block) AddNote(n *NoteAnnotation)

Çĥööšé Đàţà ƒöŕ đöçüḿéñţ-ļéṽéļ öŕ ƒŕéé-šţàñđîñĝ çöñţéẋţ, àñđ à NoteAnnotation ŵĥéñ ţĥé çöñţéẋţ ƃéļöñĝš ţö öñé ƃļöçķ.

Çöḿþöšîñĝ ƒöŕḿàţš: öþţ ţĥé îññéŕ ŕéàđéŕ öüţ

À ƒöŕḿàţ ţĥàţ çöḿþöšéš àñöţĥéŕ ŕéàđéŕ îñĥéŕîţš ţĥàţ ŕéàđéŕ'š šüŕƒàçîñĝ đéƒàüļţ. Ŵĥéñ ţĥé çöḿþöšéđ ŕéàđéŕ'š ñöţîöñ öƒ "ñöñ-ţŕàñšļàţàƃļé çöñţéñţ" îš ŵŕöñĝ ƒöŕ ţĥé öüţéŕ ƒöŕḿàţ, ţĥé öüţéŕ çöñƒîĝ ḿüšţ ţüŕñ ţĥé îññéŕ šüŕƒàçîñĝ öƒƒ éẋþļîçîţļý.

Đéšîĝñ Ţöķéñš îš ţĥé çàñöñîçàļ çàšé: îţ đŕîṽéš ţĥé ĝéñéŕîç ĴŠÖÑ ŕéàđéŕ, ƃüţ à ţöķéñ'š $value/$type/$extensions àŕé šţŕüçţüŕéđ ḿàçĥîñé đàţà, ñöţ þŕöšé, šö šüŕƒàçîñĝ ţĥéḿ àš çöñţéñţ ƃļöçķš ŵöüļđ ƃé ñöîšé. Ţĥé öñļý ţŕàñšļàţàƃļé šüŕƒàçé îš $description. applyToJSON ţĥéŕéƒöŕé đîšàƃļéš ţĥé îññéŕ ŕéàđéŕ'š šüŕƒàçîñĝ ţĥŕöüĝĥ ţĥé šàḿé šéţţéŕ ţĥé þàŕîţý ŕüññéŕ üšéš:

// core/formats/designtokens/config.go (applyToJSON)
func (c *Config) applyToJSON(jc *jsonfmt.Config) {
jc.Reset()
// Design-token values are structured machine data (colours, dimensions,
// numbers), not contextual prose, do not surface the excluded values as
// non-translatable content blocks. (The JSON reader's default is to surface
// them for ingestion.)
jc.SetExtractNonTranslatableContent(false)
// … ExtractAllPairs=false + $description-only extraction rule …
}

Ţĥé öüţéŕ ƒöŕḿàţ ḿàý šţîļļ öƒƒéŕ îţš öŵñ þöšîţîṽé ţöĝĝļé ţö ţĥé üšéŕ (ExtractDescriptions ĥéŕé) ŵîţĥöüţ ŕé-éẋþöšîñĝ ţĥé îññéŕ ŕéàđéŕ'š ţöĝĝļé: ţĥé ţŵö çöñçéŕñš àŕé đéçöüþļéđ, àñđ ţĥé éḿƃéđđéđ ŕéàđéŕ šţàýš ñöñ-šüŕƒàçîñĝ ŕéĝàŕđļéšš.

Þàŕîţý šàƒéţý öƒ ţĥé çàŕŕîéŕš

Ţĥé çàñöñîçàļ þàŕîţý þŕöĵéçţîöñ (cli/parity/normalize.go, CanonicalPart / Canonicalize) çöḿþàŕéš öñļý þàŕţ ţýþé, îđéñţîţý, Translatable, àñđ ŕéñđéŕéđ šöüŕçé/ţàŕĝéţ ţéẋţ. Îţ öḿîţš SemanticRole/šţŕüçţüŕé àññöţàţîöñš, Properties, ƃļöçķ àññöţàţîöñš (îñçļüđîñĝ ñöţéš), àñđ ţĥé þļàçéĥöļđéŕ Equiv/Disp çàŕŕîéŕš, šö àţţàçĥîñĝ àñý öƒ ţĥöšé ţö àñ éẋîšţîñĝ þàŕţ îš îñṽîšîƃļé ţö þàŕîţý àñđ ñééđš ñö šþéçîàļ ĥàñđļîñĝ. Ţĥé ţĥîñĝ ţĥàţ îš ñöţ ƒŕéé îš éḿîţţîñĝ à ñéŵ þàŕţ: à šüŕƒàçéđ Translatable:false Ƃļöçķ àđđš à BlockID ŕöŵ, àñđ à çöḿḿéñţ Data þàŕţ àđđš à DataID ŕöŵ, ţö ţĥé çàñöñîçàļ šţŕéàḿ àñđ ŵîļļ đîṽéŕĝé ƒŕöḿ ţĥé ƃŕîđĝé. Ţĥàţ đîṽéŕĝéñçé îš éẋàçţļý ŵĥàţ ţĥé đüçķ-ţýþéđ ƒöŕçé-öƒƒ ñéüţŕàļîžéš: ŵîţĥ šüŕƒàçîñĝ öƒƒ, ţĥé éẋţŕà þàŕţš àŕé ñöţ éḿîţţéđ àñđ ţĥé šţŕéàḿ ḿàţçĥéš ƃýţé-ƒöŕ-ƃýţé. Ţĥîš îš ŵĥý à šüŕƒàçîñĝ ƒöŕḿàţ ḿüšţ ŵîŕé ţĥé šéţţéŕ ŕàţĥéŕ ţĥàñ éḿîţţîñĝ üñçöñđîţîöñàļļý.

Çĥéçķļîšţ ƒöŕ à ñéŵ šüŕƒàçîñĝ ƒöŕḿàţ

  1. Àđđ à þŕîṽàţé îñṽéŕţéđ ƒîéļđ disableNonTranslatableContent bool; ļéàṽé îţš žéŕö ṽàļüé (šüŕƒàçîñĝ ÖÑ) àñđ þîñ îţ îñ Reset() ƒöŕ đöçüḿéñţàţîöñ.
  2. Àđđ ţĥé ExtractNonTranslatableContent() bool ĝéţţéŕ àñđ SetExtractNonTranslatableContent(bool) šéţţéŕ (ƃöţĥ àƃšöŕƃîñĝ ţĥé îñṽéŕšîöñ); ţĥé éẋàçţ šéţţéŕ šîĝñàţüŕé îš ţĥé þàŕîţý çöñţŕàçţ.
  3. Đéçöđé ţĥé þöšîţîṽé þüƃļîç ķéý extractNonTranslatableContent îñ ApplyMap.
  4. Đéçļàŕé à schema.Prop ŵîţĥ Default: true àñđ þļàçé ţĥé ƒîéļđ îñ à ParameterGroup šö îţ ŕéàçĥéš /reference/formats.
  5. Šüŕƒàçé ŕéñđéŕéđ çöñţéẋţ ṽîà çĥàññéļ 1: Block{Translatable:false} + SetSemanticRole(<closest existing role>, level) + à SkeletonRef šö ţĥé ŕöüñđ-ţŕîþ îš ƃýţé-éẋàçţ; šüŕƒàçé çöḿḿéñţš/ḿéţàđàţà ṽîà çĥàññéļ 2 (model.Data öŕ Block.AddNote(&NoteAnnotation{…})).
  6. ΃ ţĥé ƒöŕḿàţ çöḿþöšéš àñöţĥéŕ ŕéàđéŕ, çàļļ SetExtractNonTranslatableContent(false) öñ ţĥé îññéŕ çöñƒîĝ ŵĥéñ îţš šüŕƒàçîñĝ îš ŵŕöñĝ ƒöŕ ýöüŕ çöñţéñţ (çƒ. Đéšîĝñ Ţöķéñš → ĴŠÖÑ).
  7. Àđđ à ţéšţ àššéŕţîñĝ (à) šüŕƒàçéđ þàŕţš àþþéàŕ ƃý đéƒàüļţ àñđ (ƃ) SetExtractNonTranslatableContent(false) ýîéļđš ţĥé öþàǫüé, ƃŕîđĝé-îđéñţîçàļ šţŕéàḿ.

Ŕéļàţéđ