feat(mxl-compile,mxl-decompile): пустой тег текста ячейки

У текста ячейки три состояния, а выражались два: тега нет вовсе, тег с пустым
текстом на каждый язык — и третье, <tl/>, которое мы теряли. Это не редкость:
38 075 ячеек на 1200 макетов, встречается в 57% макетов корпуса.

Выражается пустым объектом: "text": {}. Не новый ключ и не новое понятие, а
вырожденный случай уже принятой записи «язык → текст» — языков нет вовсе.
В позиционной строке двусмысленности не создаёт: {} не несёт ключей ячейки,
значит по общему правилу читается как текст, а null там по-прежнему «пропустить
колонку».

В описании DSL записи нет намеренно. Для авторинга она бесполезна — визуально
это тот же пустой текст, что и "", — а документировать две пустые формы рядом
значило бы завести развилку, у которой нет правильного ответа.

Платформа пишет такой тег самозакрывающимся, поэтому эмиссия отдельной веткой.

На пилоте потери в категории row[].cell[].tl упали с 12 488 до 2, заодно
row[].cell[].fmt с 41 645 до 30 088; совпадение строк документа 17.6% → 18.5%.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-08-12 12:21:02 +03:00
co-authored by Claude Opus 5
parent 6619a4e7ad
commit 0a8671a166
4 changed files with 31 additions and 6 deletions
@@ -1,4 +1,4 @@
# mxl-compile v1.38 — Compile 1C spreadsheet from JSON
# mxl-compile v1.39 — Compile 1C spreadsheet from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -800,6 +800,13 @@ function Emit-CellText {
} else {
foreach ($l in $textLanguages) { $pairs += @{ Lang = $l; Text = "$value" } }
}
# Пустой объект — отдельное состояние: тег текста есть, языков в нём нет. Платформа
# пишет его самозакрывающимся. Для авторинга бесполезно (визуально это тот же пустой
# текст, что и ""), поэтому в описании DSL записи нет — она нужна раундтрипу.
if ($pairs.Count -eq 0) {
X "`t`t`t`t`t<tl/>"
return
}
X "`t`t`t`t`t<tl>"
foreach ($p in $pairs) {
X "`t`t`t`t`t`t<v8:item>"