feat(mxl-compile,mxl-decompile): многоязычный текст ячейки

Платформа хранит текст ячейки по элементу на язык. Декомпилятор брал ПЕРВЫЙ и терял
остальное, компилятор писал всегда ru захардкоженно. В корпусе ERP текст лежит и под
ru, и под en у 10 730 макетов из 10 924 — то есть терялось у 98%.

Форма взята готовая — конвенция ML-значений из docs/meta-dsl-spec.md §4.4, по которой
уже живут synonym, tooltip и title в метаданных и формах: строка означает русский
текст, объект даёт по надписи на язык в порядке ключей. Новых понятий не вводили,
ключи те же (text и template).

Документный ключ для языков НЕ заводили, и это измерение, а не экономия: блок
languageSettings мы и так эмитим байт в байт как платформа (currentLanguage ru,
defaultLanguage ru, один languageInfo). Отклонения редки — 8 макетов ERP с
currentLanguage en, 3 без него, 157 с объявленной парой ru+en, всего около 1,6%.
Заодно это снимает развилку из разбора PR #62: список языков компилятор дописывать
не должен, платформа его не дописывает.

Эффект на пилоте: категория row[].cell[].tl упала с 47 252 до 12 488 — минус 74%,
самое крупное улучшение кампании. Остаток частично классифицирован: 348 строк — ячейки
с ПУСТЫМ <tl> у оригинала, которых мы не эмитим вовсе; полностью разобрать мешает
обрезка диффа по 400 строк на объект.

Снэпшоты не дрейфанули: кейсы пишут текст строкой, и вывод для неё прежний.

Проверено: тесты 54/54 на обоих рантаймах, verify-snapshots 24/24, вывод портов
совпадает байт в байт и в компиляции, и в декомпиляции.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-08-10 20:52:03 +03:00
co-authored by Claude Opus 5
parent 572b75984a
commit 1e06e43e92
8 changed files with 228 additions and 45 deletions
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<languageSettings>
<currentLanguage>ru</currentLanguage>
<defaultLanguage>ru</defaultLanguage>
<languageInfo>
<id>ru</id>
<code>Русский</code>
<description>Русский</description>
</languageInfo>
</languageSettings>
<columns>
<size>3</size>
</columns>
<rowsItem>
<index>0</index>
<row>
<c>
<i>0</i>
<c>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Только по-русски</v8:content>
</v8:item>
</tl>
</c>
</c>
<c>
<i>1</i>
<c>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Поставщик</v8:content>
</v8:item>
<v8:item>
<v8:lang>en</v8:lang>
<v8:content>Supplier</v8:content>
</v8:item>
</tl>
</c>
</c>
<c>
<i>2</i>
<c>
<f>2</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Итого: [Сумма]</v8:content>
</v8:item>
<v8:item>
<v8:lang>en</v8:lang>
<v8:content>Total: [Сумма]</v8:content>
</v8:item>
</tl>
</c>
</c>
</row>
</rowsItem>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
<height>1</height>
<vgRows>1</vgRows>
<namedItem xsi:type="NamedItemCells">
<name>Шапка</name>
<area>
<type>Rows</type>
<beginRow>0</beginRow>
<endRow>0</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<font faceName="Arial" height="10" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
<format>
<width>10</width>
</format>
<format>
<font>0</font>
<fillType>Template</fillType>
</format>
</document>
@@ -0,0 +1,35 @@
{
"name": "Многоязычный текст ячейки: строка = ru, объект = по элементу на язык",
"input": {
"columns": 3,
"areas": [
{
"name": "Шапка",
"rows": [
{
"cells": [
{ "col": 1, "text": "Только по-русски" },
{ "col": 2, "text": { "ru": "Поставщик", "en": "Supplier" } },
{ "col": 3, "template": { "ru": "Итого: [Сумма]", "en": "Total: [Сумма]" } }
]
}
]
}
]
},
"params": {
"outputPath": "Template.xml"
},
"validatePath": "Template.xml",
"expect": {
"files": ["Template.xml"],
"fileContains": {
"file": "Template.xml",
"text": [
"<v8:lang>en</v8:lang>",
"<v8:content>Supplier</v8:content>",
"<v8:content>Поставщик</v8:content>"
]
}
}
}