fix(mxl-compile,mxl-decompile): пустой текст ячейки и расхождение портов на нём

Пустой текст платформа хранит только самозакрывающимся тегом: в корпусе ERP
таких 1 224 460, а из 780 934 непустых блоков нет ни одного, где пусты все
языки. Компилятор же на `text: ""` писал блок с пустым элементом языка —
запись, которой в выгрузках не существует. Теперь любая пустая форма
(строка, пустой объект, все языки пустыми) даёт один и тот же тег, а
декомпилятор возвращает её канонической пустой строкой.

Отсюда же росло расхождение портов. Свёртка текста на пустой карте языков
возвращала null, если ДРУГОГО текста в макете нет вовсе: набор языков
документа при этом пуст. Дальше py писал пропуск колонки, а ps1 наступал
на разворачивание одноэлементного массива — список из одного $null
превращался в $null, и строка целиком уходила в пустые.

Проверено на 12 корпусных макетах: 1411 пустых текстов из 1411 вернулись
на место, JSON портов совпадает.
This commit is contained in:
Nick Shirokov
2026-08-16 12:30:19 +03:00
parent fef55043cf
commit e048fcff70
9 changed files with 186 additions and 14 deletions
@@ -0,0 +1,16 @@
{
"name": "Пустой текст ячейки: строка, объект и все языки пустые",
"input": {
"columns": 2,
"textLanguages": ["ru", "en"],
"areas": [{
"rows": [
{ "cells": [{ "col": 1, "text": "" }] },
{ "cells": [{ "col": 1, "text": {} }] },
{ "cells": [{ "col": 1, "text": { "ru": "", "en": "" } }] },
{ "cells": [{ "col": 1, "text": { "ru": "А", "en": "" } }] }
]
}]
},
"params": { "outputPath": "Template.xml" }
}
@@ -0,0 +1,75 @@
<?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>2</size>
</columns>
<rowsItem>
<index>0</index>
<row>
<c>
<c>
<f>0</f>
<tl/>
</c>
</c>
</row>
</rowsItem>
<rowsItem>
<index>1</index>
<row>
<c>
<c>
<f>0</f>
<tl/>
</c>
</c>
</row>
</rowsItem>
<rowsItem>
<index>2</index>
<row>
<c>
<c>
<f>0</f>
<tl/>
</c>
</c>
</row>
</rowsItem>
<rowsItem>
<index>3</index>
<row>
<c>
<c>
<f>0</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>А</v8:content>
</v8:item>
<v8:item>
<v8:lang>en</v8:lang>
<v8:content></v8:content>
</v8:item>
</tl>
</c>
</c>
</row>
</rowsItem>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
<height>4</height>
<vgRows>4</vgRows>
<format>
<width>10</width>
</format>
</document>
@@ -0,0 +1,18 @@
{
"name": "Roundtrip — пустой текст ячейки возвращается как \"\"",
"preRun": [
{ "script": "mxl-compile/scripts/mxl-compile",
"input": {
"columns": 2,
"areas": [{ "rows": [
{ "cells": [{ "col": 1, "text": "" }] },
{ "cells": [{ "col": 1, "text": "Текст" }] }
]}]
},
"args": { "-JsonPath": "{inputFile}", "-OutputPath": "Template.xml" },
"cwd": "{workDir}" }
],
"params": { "templatePath": "Template.xml" },
"args_extra": ["-OutputPath", "{workDir}/back.json"],
"expect": { "files": ["back.json"], "stdoutContains": "[OK] Decompiled:" }
}
@@ -0,0 +1,49 @@
<?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>2</size>
</columns>
<rowsItem>
<index>0</index>
<row>
<c>
<c>
<f>0</f>
<tl/>
</c>
</c>
</row>
</rowsItem>
<rowsItem>
<index>1</index>
<row>
<c>
<c>
<f>0</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Текст</v8:content>
</v8:item>
</tl>
</c>
</c>
</row>
</rowsItem>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
<height>2</height>
<vgRows>2</vgRows>
<format>
<width>10</width>
</format>
</document>
@@ -0,0 +1 @@
{ "columns": 2, "defaultWidth": 10, "fonts": {}, "styles": {}, "areas": [{ "rows": [[""], ["Текст"]] }] }