feat(form-decompile,form-compile): Table headerHeight/footerHeight/currentRowUse + форм. conversationsRepresentation (pass-through)

Раундтрип терял 4 свойства (категория Table-скаляры + форм-уровень):
- Table <HeaderHeight>/<FooterHeight> (высота шапки/подвала в строках; ~35/~6 форм)
- Table <CurrentRowUse> (использование текущей строки; ≠ одноимённое свойство команды,
  у которой свой путь захвата/эмиссии). Значения: DontUse/Use/SelectionPresentation/
  SelectionPresentationAndChoice/Choice
- форм-уровень <ConversationsRepresentation> (Auto/Show/DontShow; редкое)

Все три Table-свойства были явно отложены в Emit-Table (комментарий о «строгом Table-XSD»).
Корпусные данные показывают, что 1С эмитит те же теги в РАЗНЫХ позициях у разных форм →
загрузчик толерантен к порядку детей Table (как и существующий компилятор с ранним DataPath).
Размещены pass-through в Emit-Table (height-теги рядом с UseAlternationRowColor, CurrentRowUse
у блока дин-списка); форм-уровень — generic Emit-Properties (авто-PascalCase).

decompile (ps1): захват headerHeight/footerHeight/currentRowUse на Table; ConversationsRepresentation
в KNOWN_FORM_PROPS. compile (ps1+py): эмиссия в emit_table.

Верификация: таргет-раундтрип 4 форм → match (TOTAL diff lines 0); регресс form-compile 43/43
(ps1+py); 1С-cert кейса table (форма с тремя тегами грузится в платформу). spec обновлён.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-06-12 11:09:15 +03:00
co-authored by Claude Opus 4.8
parent 6e4fdb443a
commit 6377cdfba5
6 changed files with 32 additions and 7 deletions
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# form-compile v1.125 — Compile 1C managed form from JSON or object metadata
# form-compile v1.126 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import copy
@@ -4029,6 +4029,11 @@ def emit_table(lines, el, name, eid, indent):
lines.append(f'{inner}<SearchOnInput>{el["searchOnInput"]}</SearchOnInput>')
if el.get('markIncomplete') is not None:
lines.append(f'{inner}<AutoMarkIncomplete>{"true" if el["markIncomplete"] else "false"}</AutoMarkIncomplete>')
# Высота шапки/подвала в строках (pass-through; 1С толерантна к порядку детей Table)
if el.get('headerHeight') is not None:
lines.append(f'{inner}<HeaderHeight>{el["headerHeight"]}</HeaderHeight>')
if el.get('footerHeight') is not None:
lines.append(f'{inner}<FooterHeight>{el["footerHeight"]}</FooterHeight>')
if el.get('useAlternationRowColor') is True:
lines.append(f'{inner}<UseAlternationRowColor>true</UseAlternationRowColor>')
if el.get('selectionMode'):
@@ -4047,6 +4052,9 @@ def emit_table(lines, el, name, eid, indent):
lines.append(f'{inner}<RowPictureDataPath>{el["rowPictureDataPath"]}</RowPictureDataPath>')
# RowsPicture — та же конвенция, что ValuesPicture (дефолт LoadTransparent=false; abs/TransparentPixel)
emit_picture_ref(lines, el.get('rowsPicture'), 'RowsPicture', inner)
# Использование текущей строки таблицы (pass-through; в корпусе соседствует с блоком дин-списка)
if el.get('currentRowUse'):
lines.append(f'{inner}<CurrentRowUse>{el["currentRowUse"]}</CurrentRowUse>')
# Блок свойств дин-список-таблицы (помечена эвристикой)
if el.get('_dynList'):
emit_dynlist_table_block(lines, el, inner)