mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-06 10:10:52 +03:00
feat(mxl-compile,mxl-decompile): textLanguages — текст строкой на всех языках макета
Строка в 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) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4cceb03269
commit
683ed8e08d
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user