From 683ed8e08db51a2d581c94d70c377dafee78ac66 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Tue, 11 Aug 2026 12:00:20 +0300 Subject: [PATCH] =?UTF-8?q?feat(mxl-compile,mxl-decompile):=20textLanguage?= =?UTF-8?q?s=20=E2=80=94=20=D1=82=D0=B5=D0=BA=D1=81=D1=82=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=BA=D0=BE=D0=B9=20=D0=BD=D0=B0=20=D0=B2=D1=81?= =?UTF-8?q?=D0=B5=D1=85=20=D1=8F=D0=B7=D1=8B=D0=BA=D0=B0=D1=85=20=D0=BC?= =?UTF-8?q?=D0=B0=D0=BA=D0=B5=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Строка в text/template разворачивается по одному элементу на каждый язык из документного ключа textLanguages (по умолчанию только ru). Декомпилятор собирает набор языков по всем текстам макета и пишет строкой текст, одинаковый на всём наборе; различающийся остаётся объектом. Языки текстов и языки, объявленные в конфигурации, — разные вещи: типовые ERP объявляют один ru, а тексты хранят под ru и en. Набор постоянен внутри конфигурации, поэтому он документный, а не вычисляемый: к моменту компиляции тексты уже свёрнуты в строки. Заодно: эмиссия tl проверяет НАЛИЧИЕ ключа text/template, а не истинность — пустая строка это текст, платформа такие ячейки пишет с пустым tl, а по истинности он терялся. Проверено на пилоте (40 макетов ERP): скомпилированный XML совпадает с прошлым прогоном байт в байт обоими рантаймами, объём JSON −47%. Co-Authored-By: Claude Opus 5 (1M context) --- .../skills/mxl-compile/reference/dsl-spec.md | 17 ++++- .../mxl-compile/scripts/mxl-compile.ps1 | 20 ++++-- .../skills/mxl-compile/scripts/mxl-compile.py | 19 +++-- .../mxl-decompile/scripts/mxl-decompile.ps1 | 47 ++++++++++--- .../mxl-decompile/scripts/mxl-decompile.py | 51 +++++++++++--- docs/mxl-dsl-spec.md | 17 ++++- .../snapshots/text-languages/Template.xml | 70 +++++++++++++++++++ .../cases/mxl-compile/text-languages.json | 36 ++++++++++ .../roundtrip-text-languages.json | 29 ++++++++ .../roundtrip-text-languages/Template.xml | 70 +++++++++++++++++++ 10 files changed, 340 insertions(+), 36 deletions(-) create mode 100644 tests/skills/cases/mxl-compile/snapshots/text-languages/Template.xml create mode 100644 tests/skills/cases/mxl-compile/text-languages.json create mode 100644 tests/skills/cases/mxl-decompile/roundtrip-text-languages.json create mode 100644 tests/skills/cases/mxl-decompile/snapshots/roundtrip-text-languages/Template.xml diff --git a/.claude/skills/mxl-compile/reference/dsl-spec.md b/.claude/skills/mxl-compile/reference/dsl-spec.md index 80055230..2e895b8a 100644 --- a/.claude/skills/mxl-compile/reference/dsl-spec.md +++ b/.claude/skills/mxl-compile/reference/dsl-spec.md @@ -77,6 +77,7 @@ | `page` | нет | — | Формат страницы: `"A4-landscape"` (780), `"A4-portrait"` (540) или число. Автоматически вычисляет `defaultWidth` из суммы пропорций `"Nx"` | | `defaultWidth` | нет | 10 | Ширина колонок по умолчанию. Игнорируется если задан `page` и все колонки используют `"Nx"` | | `columnWidths` | нет | `{}` | Ширины колонок. Ключи 1-based: `"1"`, `"3-14"`, `"5,7,9"`. Значения: число (абсолют) или `"Nx"` (множитель от defaultWidth, напр. `"2x"`, `"0.5x"`) | +| `textLanguages` | нет | `["ru"]` | Языки, на которых пишется текст, заданный строкой (см. ниже) | | `fonts` | нет | — | Именованные шрифты (если не задано, создаётся Arial 10) | | `styles` | нет | `{}` | Именованные стили | | `areas` | да | — | Массив областей — диапазонов подряд идущих строк (порядок = порядок в документе); имя необязательно | @@ -227,14 +228,26 @@ ### Текст на нескольких языках -`text` и `template` принимают строку или объект «язык → текст». Строка означает русский; объект даёт по надписи на каждый язык, в порядке ключей. +`text` и `template` принимают строку или объект «язык → текст». Объект даёт по надписи на каждый язык, в порядке ключей. Строка означает один и тот же текст на всех языках макета — по умолчанию только русский. ```json { "col": 1, "text": "Наименование" } { "col": 2, "text": { "ru": "Поставщик", "en": "Supplier" } } ``` -Языки макета объявляются отдельно (`languageSettings` в XML) и по умолчанию ограничены русским; писать текст на языке, которого нет в объявленных, допустимо — так устроено большинство типовых макетов. +Набор языков задаётся документным ключом `textLanguages`: + +```json +{ "columns": 3, "textLanguages": ["ru", "en"], "areas": [] } +``` + +С таким объявлением `"Наименование"` из примера выше даст надпись и под `ru`, и под `en`. + +**Языки текстов и языки, объявленные в конфигурации, — разные вещи**, и у типовых они не совпадают: почти все макеты ERP объявляют один русский, а тексты хранят под `ru` и `en`. Писать текст на языке, которого нет среди объявленных в конфигурации, платформа позволяет. + +Набор постоянен внутри конфигурации, а не подбирается под макет: в ERP это `ru` и `en` у всех макетов с текстом, в БП, УТ и УНФ — только `ru`. Поэтому `textLanguages` объявляется один раз на макет и обычно повторяет соседние. Вывести его из самих текстов компилятор не может: к моменту компиляции они уже свёрнуты в строки. + +Пустая строка — это текст: ячейка с `"text": ""` даёт пустую надпись, а не ячейку без текста. ## `rowStyle` — автозаполнение diff --git a/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 b/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 index bac1708d..e7f1c461 100644 --- a/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 +++ b/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 @@ -1,4 +1,4 @@ -# mxl-compile v1.25 — Compile 1C spreadsheet from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) +# mxl-compile v1.26 — Compile 1C spreadsheet from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -559,8 +559,14 @@ function Esc-XmlText { } # Текст ячейки платформа хранит по элементу на язык. Конвенция ML-значений (та же, что у -# synonym/tooltip/title в метаданных и формах): строка — русский текст, объект — по элементу -# на язык В ПОРЯДКЕ КЛЮЧЕЙ. +# synonym/tooltip/title в метаданных и формах): объект — по элементу на язык В ПОРЯДКЕ КЛЮЧЕЙ, +# строка — один и тот же текст на всех языках макета (textLanguages, по умолчанию только ru). +$textLanguages = @('ru') +if ($def.textLanguages) { + $declared = @($def.textLanguages | ForEach-Object { "$_" } | Where-Object { $_ }) + if ($declared.Count -gt 0) { $textLanguages = $declared } +} + function Emit-CellText { param($value) $pairs = @() @@ -569,7 +575,7 @@ function Emit-CellText { } elseif ($value -is [System.Management.Automation.PSCustomObject]) { foreach ($p in $value.PSObject.Properties) { $pairs += @{ Lang = $p.Name; Text = "$($p.Value)" } } } else { - $pairs += @{ Lang = 'ru'; Text = "$value" } + foreach ($l in $textLanguages) { $pairs += @{ Lang = $l; Text = "$value" } } } X "`t`t`t`t`t" foreach ($p in $pairs) { @@ -1094,9 +1100,11 @@ foreach ($area in $def.areas) { } } - if ($cellInfo.Text) { Emit-CellText $cellInfo.Text } + # Проверяем НАЛИЧИЕ ключа, а не истинность: пустая строка — это текст, платформа + # такие ячейки пишет с пустым , и по истинности он терялся. + if ($null -ne $cellInfo.Text) { Emit-CellText $cellInfo.Text } - if ($cellInfo.Template) { Emit-CellText $cellInfo.Template } + if ($null -ne $cellInfo.Template) { Emit-CellText $cellInfo.Template } X "`t`t`t`t" X "`t`t`t" diff --git a/.claude/skills/mxl-compile/scripts/mxl-compile.py b/.claude/skills/mxl-compile/scripts/mxl-compile.py index 42e85e4f..1328071f 100644 --- a/.claude/skills/mxl-compile/scripts/mxl-compile.py +++ b/.claude/skills/mxl-compile/scripts/mxl-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# mxl-compile v1.25 — Compile 1C spreadsheet from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) +# mxl-compile v1.26 — Compile 1C spreadsheet from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import hashlib @@ -607,13 +607,18 @@ def main(): # 6c. Helper: determine fillType from cell content # Текст ячейки платформа хранит по элементу на язык. Конвенция ML-значений (та же, что у - # synonym/tooltip/title в метаданных и формах): строка — русский текст, объект — по элементу - # на язык В ПОРЯДКЕ КЛЮЧЕЙ. + # synonym/tooltip/title в метаданных и формах): объект — по элементу на язык В ПОРЯДКЕ + # КЛЮЧЕЙ, строка — один и тот же текст на всех языках макета (textLanguages, по умолчанию + # только ru). + text_languages = [str(x) for x in (defn.get('textLanguages') or []) if str(x)] + if not text_languages: + text_languages = ['ru'] + def emit_cell_text(lines, value): if isinstance(value, dict): pairs = [(str(k), str(v)) for k, v in value.items()] else: - pairs = [('ru', str(value))] + pairs = [(lang, str(value)) for lang in text_languages] lines.append('\t\t\t\t\t') for lang, content in pairs: lines.append('\t\t\t\t\t\t') @@ -1072,10 +1077,12 @@ def main(): if cell_info['Detail']: lines.append(f'\t\t\t\t\t{cell_info["Detail"]}') - if cell_info['Text']: + # Проверяем НАЛИЧИЕ ключа, а не истинность: пустая строка — это текст, + # платформа такие ячейки пишет с пустым , и по истинности он терялся. + if cell_info['Text'] is not None: emit_cell_text(lines, cell_info['Text']) - if cell_info['Template']: + if cell_info['Template'] is not None: emit_cell_text(lines, cell_info['Template']) lines.append('\t\t\t\t') diff --git a/.claude/skills/mxl-decompile/scripts/mxl-decompile.ps1 b/.claude/skills/mxl-decompile/scripts/mxl-decompile.ps1 index dd38e0fb..e71b80f3 100644 --- a/.claude/skills/mxl-decompile/scripts/mxl-decompile.ps1 +++ b/.claude/skills/mxl-decompile/scripts/mxl-decompile.ps1 @@ -1,4 +1,4 @@ -# mxl-decompile v1.8 — Decompile 1C spreadsheet to JSON +# mxl-decompile v1.9 — Decompile 1C spreadsheet to JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -209,6 +209,8 @@ foreach ($niNode in $root.SelectNodes("d:namedItem", $ns)) { # --- 8. Extract rows --- $rowData = @{} +# Языки, на которых в макете вообще есть текст. Порядок — первого появления. +$docLangs = [ordered]@{} foreach ($riNode in $root.SelectNodes("d:rowsItem", $ns)) { $rowIdx = [int]$riNode.SelectSingleNode("d:index", $ns).InnerText $rowNode = $riNode.SelectSingleNode("d:row", $ns) @@ -250,8 +252,10 @@ foreach ($riNode in $root.SelectNodes("d:rowsItem", $ns)) { # Текст ячейки платформа хранит по элементу на язык. Раньше брался ПЕРВЫЙ, и всё # остальное терялось — в корпусе ERP 98% макетов держат текст и под ru, и под en. - # Конвенция ML-значений: только ru → строка, иначе объект «язык → текст». + # Здесь собираем «язык → текст» как есть; свернётся в строку позже, когда станет + # известен набор языков всего макета (Get-DslText). $text = $null + $hasText = $false $items = $cContent.SelectNodes("d:tl/v8:item", $ns) if ($items -and $items.Count -gt 0) { $byLang = [ordered]@{} @@ -260,9 +264,12 @@ foreach ($riNode in $root.SelectNodes("d:rowsItem", $ns)) { $contentNode = $it.SelectSingleNode("v8:content", $ns) $lang = if ($langNode) { $langNode.InnerText } else { '' } $byLang[$lang] = if ($contentNode) { $contentNode.InnerText } else { '' } + $docLangs[$lang] = $true } - if ($byLang.Count -eq 1 -and $byLang.Contains('ru')) { $text = $byLang['ru'] } - else { $text = $byLang } + $text = $byLang + # Единственный пустой русский текст содержимым не считается — такая ячейка + # уходит в заполнители строки. + $hasText = -not ($byLang.Count -eq 1 -and $byLang.Contains('ru') -and "$($byLang['ru'])" -eq '') } $cells += @{ @@ -271,6 +278,7 @@ foreach ($riNode in $root.SelectNodes("d:rowsItem", $ns)) { Param = $param Detail = $detail Text = $text + HasText = $hasText } } } @@ -290,6 +298,23 @@ foreach ($riNode in $root.SelectNodes("d:rowsItem", $ns)) { } } +# Языки текстов макета и языки, объявленные в конфигурации, — разные вещи: у типовых они не +# совпадают. Строкой пишем текст, одинаковый на ВСЁМ наборе языков макета; остальное — объектом. +$textLanguages = @($docLangs.Keys) + +function Get-DslText { + param($byLang) + if ($byLang -isnot [System.Collections.IDictionary]) { return $byLang } + if ($byLang.Count -ne $textLanguages.Count) { return $byLang } + $common = $null + foreach ($l in $textLanguages) { + if (-not $byLang.Contains($l)) { return $byLang } + if ($null -eq $common) { $common = "$($byLang[$l])" } + elseif ("$($byLang[$l])" -cne $common) { return $byLang } + } + return $common +} + # --- 9. Build style key (ignoring fillType) --- function Get-BorderDesc { @@ -634,7 +659,7 @@ foreach ($area in $blocks) { $gapCells = @() foreach ($cell in $rd.Cells) { - $hasContent = $cell.Param -or $cell.Text + $hasContent = $cell.Param -or $cell.HasText $hasMerge = $mergeMap.ContainsKey("$globalRow,$($cell.Col)") if ($hasContent -or $hasMerge) { @@ -703,10 +728,10 @@ foreach ($area in $blocks) { if ($cell.Param) { $dslCell["param"] = $cell.Param if ($cell.Detail) { $dslCell["detail"] = $cell.Detail } - } elseif ($fillType -eq "Template" -and $cell.Text) { - $dslCell["template"] = $cell.Text - } elseif ($cell.Text) { - $dslCell["text"] = $cell.Text + } elseif ($fillType -eq "Template" -and $cell.HasText) { + $dslCell["template"] = Get-DslText $cell.Text + } elseif ($cell.HasText) { + $dslCell["text"] = Get-DslText $cell.Text } $dslCells += $dslCell @@ -801,6 +826,10 @@ $result = [ordered]@{ defaultWidth = $defaultWidth } if ($compressedWidths.Count -gt 0) { $result["columnWidths"] = $compressedWidths } +# Набор языков объявляем, только если он отличается от умолчания компилятора (один ru). +if ($textLanguages.Count -gt 0 -and -not ($textLanguages.Count -eq 1 -and $textLanguages[0] -ceq 'ru')) { + $result["textLanguages"] = [array]$textLanguages +} # Remove empty "default" style if ($styleDefs.Contains("default") -and $styleDefs["default"].Count -eq 0) { $styleDefs.Remove("default") diff --git a/.claude/skills/mxl-decompile/scripts/mxl-decompile.py b/.claude/skills/mxl-decompile/scripts/mxl-decompile.py index 1b7c536c..1055b516 100644 --- a/.claude/skills/mxl-decompile/scripts/mxl-decompile.py +++ b/.claude/skills/mxl-decompile/scripts/mxl-decompile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# mxl-decompile v1.8 — Decompile 1C spreadsheet to JSON +# mxl-decompile v1.9 — Decompile 1C spreadsheet to JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -380,6 +380,8 @@ def main(): # --- 8. Extract rows --- row_data = {} + # Языки, на которых в макете вообще есть текст. Порядок — первого появления. + doc_langs = OrderedDict() for ri_node in findall(root, "d:rowsItem"): row_idx = int_of(find(ri_node, "d:index")) row_node = find(ri_node, "d:row") @@ -430,8 +432,10 @@ def main(): # Текст ячейки платформа хранит по элементу на язык. Раньше брался ПЕРВЫЙ, и всё # остальное терялось — в корпусе ERP 98% макетов держат текст и под ru, и под en. - # Конвенция ML-значений: только ru → строка, иначе объект «язык → текст». + # Здесь собираем «язык → текст» как есть; свернётся в строку позже, когда станет + # известен набор языков всего макета (get_dsl_text). text = None + has_text = False items = findall(c_content, "d:tl/v8:item") if items: by_lang = OrderedDict() @@ -440,10 +444,11 @@ def main(): content_node = find(it, "v8:content") lang = (text_of(lang_node) or '') if lang_node is not None else '' by_lang[lang] = (text_of(content_node) or '') if content_node is not None else '' - if len(by_lang) == 1 and 'ru' in by_lang: - text = by_lang['ru'] - else: - text = by_lang + doc_langs[lang] = True + text = by_lang + # Единственный пустой русский текст содержимым не считается — такая ячейка + # уходит в заполнители строки. + has_text = not (len(by_lang) == 1 and by_lang.get('ru') == '') cells.append({ "Col": col, @@ -451,6 +456,7 @@ def main(): "Param": param, "Detail": detail, "Text": text, + "HasText": has_text, }) # Ссылка строки на колоночную раскладку; пусто = раскладка по умолчанию. @@ -465,6 +471,26 @@ def main(): "ColumnsId": row_columns_id, } + # Языки текстов макета и языки, объявленные в конфигурации, — разные вещи: у типовых они + # не совпадают. Строкой пишем текст, одинаковый на ВСЁМ наборе языков макета; остальное — + # объектом. + text_languages = list(doc_langs.keys()) + + def get_dsl_text(by_lang): + if not isinstance(by_lang, dict): + return by_lang + if len(by_lang) != len(text_languages): + return by_lang + common = None + for lang in text_languages: + if lang not in by_lang: + return by_lang + if common is None: + common = by_lang[lang] + elif by_lang[lang] != common: + return by_lang + return common + # --- 9. Build style key (ignoring fillType) --- def get_border_desc(fmt): @@ -791,7 +817,7 @@ def main(): gap_cells = [] for cell in rd["Cells"]: - has_content = cell["Param"] or cell["Text"] + has_content = cell["Param"] or cell["HasText"] has_merge = f"{global_row},{cell['Col']}" in merge_map if has_content or has_merge: @@ -856,10 +882,10 @@ def main(): dsl_cell["param"] = cell["Param"] if cell["Detail"]: dsl_cell["detail"] = cell["Detail"] - elif fill_type == "Template" and cell["Text"]: - dsl_cell["template"] = cell["Text"] - elif cell["Text"]: - dsl_cell["text"] = cell["Text"] + elif fill_type == "Template" and cell["HasText"]: + dsl_cell["template"] = get_dsl_text(cell["Text"]) + elif cell["HasText"]: + dsl_cell["text"] = get_dsl_text(cell["Text"]) dsl_cells.append(dsl_cell) @@ -963,6 +989,9 @@ def main(): result["defaultWidth"] = default_width if len(compressed_widths) > 0: result["columnWidths"] = compressed_widths + # Набор языков объявляем, только если он отличается от умолчания компилятора (один ru). + if text_languages and text_languages != ['ru']: + result["textLanguages"] = text_languages # Remove empty "default" style if "default" in style_defs and len(style_defs["default"]) == 0: diff --git a/docs/mxl-dsl-spec.md b/docs/mxl-dsl-spec.md index 037ded82..8927c046 100644 --- a/docs/mxl-dsl-spec.md +++ b/docs/mxl-dsl-spec.md @@ -77,6 +77,7 @@ | `page` | нет | — | Формат страницы: `"A4-landscape"` (780), `"A4-portrait"` (540) или число. Автоматически вычисляет `defaultWidth` из суммы пропорций `"Nx"` | | `defaultWidth` | нет | 10 | Ширина колонок по умолчанию. Игнорируется если задан `page` и все колонки используют `"Nx"` | | `columnWidths` | нет | `{}` | Ширины колонок. Ключи 1-based: `"1"`, `"3-14"`, `"5,7,9"`. Значения: число (абсолют) или `"Nx"` (множитель от defaultWidth, напр. `"2x"`, `"0.5x"`) | +| `textLanguages` | нет | `["ru"]` | Языки, на которых пишется текст, заданный строкой (см. ниже) | | `fonts` | нет | — | Именованные шрифты (если не задано, создаётся Arial 10) | | `styles` | нет | `{}` | Именованные стили | | `areas` | да | — | Массив областей — диапазонов подряд идущих строк (порядок = порядок в документе); имя необязательно | @@ -227,14 +228,26 @@ ### Текст на нескольких языках -`text` и `template` принимают строку или объект «язык → текст». Строка означает русский; объект даёт по надписи на каждый язык, в порядке ключей. +`text` и `template` принимают строку или объект «язык → текст». Объект даёт по надписи на каждый язык, в порядке ключей. Строка означает один и тот же текст на всех языках макета — по умолчанию только русский. ```json { "col": 1, "text": "Наименование" } { "col": 2, "text": { "ru": "Поставщик", "en": "Supplier" } } ``` -Языки макета объявляются отдельно (`languageSettings` в XML) и по умолчанию ограничены русским; писать текст на языке, которого нет в объявленных, допустимо — так устроено большинство типовых макетов. +Набор языков задаётся документным ключом `textLanguages`: + +```json +{ "columns": 3, "textLanguages": ["ru", "en"], "areas": [] } +``` + +С таким объявлением `"Наименование"` из примера выше даст надпись и под `ru`, и под `en`. + +**Языки текстов и языки, объявленные в конфигурации, — разные вещи**, и у типовых они не совпадают: почти все макеты ERP объявляют один русский, а тексты хранят под `ru` и `en`. Писать текст на языке, которого нет среди объявленных в конфигурации, платформа позволяет. + +Набор постоянен внутри конфигурации, а не подбирается под макет: в ERP это `ru` и `en` у всех макетов с текстом, в БП, УТ и УНФ — только `ru`. Поэтому `textLanguages` объявляется один раз на макет и обычно повторяет соседние. Вывести его из самих текстов компилятор не может: к моменту компиляции они уже свёрнуты в строки. + +Пустая строка — это текст: ячейка с `"text": ""` даёт пустую надпись, а не ячейку без текста. ## `rowStyle` — автозаполнение diff --git a/tests/skills/cases/mxl-compile/snapshots/text-languages/Template.xml b/tests/skills/cases/mxl-compile/snapshots/text-languages/Template.xml new file mode 100644 index 00000000..da2fb112 --- /dev/null +++ b/tests/skills/cases/mxl-compile/snapshots/text-languages/Template.xml @@ -0,0 +1,70 @@ + + + + ru + ru + + ru + Русский + Русский + + + + 2 + + + 0 + + + 0 + + 1 + + + ru + Итого + + + en + Итого + + + + + + 1 + + 1 + + + ru + Поставщик + + + en + Supplier + + + + + + + true + 1 + 1 + 1 + + Шапка + + Rows + 0 + 0 + -1 + -1 + + + + + 10 + + \ No newline at end of file diff --git a/tests/skills/cases/mxl-compile/text-languages.json b/tests/skills/cases/mxl-compile/text-languages.json new file mode 100644 index 00000000..a81a278d --- /dev/null +++ b/tests/skills/cases/mxl-compile/text-languages.json @@ -0,0 +1,36 @@ +{ + "name": "textLanguages: строка = текст на всех объявленных языках", + "input": { + "columns": 2, + "textLanguages": ["ru", "en"], + "areas": [ + { + "name": "Шапка", + "rows": [ + { + "cells": [ + { "col": 1, "text": "Итого" }, + { "col": 2, "text": { "ru": "Поставщик", "en": "Supplier" } } + ] + } + ] + } + ] + }, + "params": { + "outputPath": "Template.xml" + }, + "validatePath": "Template.xml", + "expect": { + "files": ["Template.xml"], + "fileContains": { + "file": "Template.xml", + "text": [ + "ru", + "en", + "Итого", + "Supplier" + ] + } + } +} diff --git a/tests/skills/cases/mxl-decompile/roundtrip-text-languages.json b/tests/skills/cases/mxl-decompile/roundtrip-text-languages.json new file mode 100644 index 00000000..acbc1c17 --- /dev/null +++ b/tests/skills/cases/mxl-decompile/roundtrip-text-languages.json @@ -0,0 +1,29 @@ +{ + "name": "Декомпиляция макета с текстом на нескольких языках", + "preRun": [ + { + "script": "mxl-compile/scripts/mxl-compile", + "input": { + "columns": 2, + "textLanguages": ["ru", "en"], + "areas": [ + { + "name": "Test", + "rows": [ + { + "cells": [ + { "col": 1, "text": "Итого" }, + { "col": 2, "text": { "ru": "Поставщик", "en": "Supplier" } } + ] + } + ] + } + ] + }, + "args": { "-JsonPath": "{inputFile}", "-OutputPath": "Template.xml" }, + "cwd": "{workDir}" + } + ], + "params": { "templatePath": "Template.xml" }, + "expect": { "stdoutContains": "textLanguages" } +} diff --git a/tests/skills/cases/mxl-decompile/snapshots/roundtrip-text-languages/Template.xml b/tests/skills/cases/mxl-decompile/snapshots/roundtrip-text-languages/Template.xml new file mode 100644 index 00000000..52efe22a --- /dev/null +++ b/tests/skills/cases/mxl-decompile/snapshots/roundtrip-text-languages/Template.xml @@ -0,0 +1,70 @@ + + + + ru + ru + + ru + Русский + Русский + + + + 2 + + + 0 + + + 0 + + 1 + + + ru + Итого + + + en + Итого + + + + + + 1 + + 1 + + + ru + Поставщик + + + en + Supplier + + + + + + + true + 1 + 1 + 1 + + Test + + Rows + 0 + 0 + -1 + -1 + + + + + 10 + + \ No newline at end of file