diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 756feff8..9a53169b 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.44 — Compile 1C managed form from JSON or object metadata +# form-compile v1.45 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -2950,23 +2950,31 @@ function Emit-Radio { X "$indent" } +# Заголовок декорации (Label/Picture): formatted-aware через единую ML-text форму +# (reuse Resolve-MLFormatted, как у extendedTooltip). Атрибут formatted эмитится ВСЕГДА +# (специфика декораций). Sibling-ключ `formatted` — back-compat override авто-детекта. +function Emit-DecorationTitle { + param($el, [string]$name, [string]$indent, [switch]$auto) + $hasKey = $null -ne $el.PSObject.Properties['title'] + $titleVal = if ($hasKey) { $el.title } elseif ($auto -and $name) { Title-FromName -name $name } else { $null } + if ($titleVal) { + $r = Resolve-MLFormatted $titleVal + $fmt = if ($null -ne $el.PSObject.Properties['formatted']) { [bool]$el.formatted } else { $r.formatted } + X "$indent<Title formatted=`"$(if ($fmt) { 'true' } else { 'false' })`">" + Emit-MLItems -val $r.text -indent "$indent`t" + X "$indent" + } + if ($el.tooltip) { Emit-MLText -tag "ToolTip" -text $el.tooltip -indent $indent } + if ($el.tooltipRepresentation) { X "$indent$($el.tooltipRepresentation)" } +} + function Emit-Label { param($el, [string]$name, [int]$id, [string]$indent) X "$indent" $inner = "$indent`t" - $hasTitleKey = $null -ne $el.PSObject.Properties['title'] - $labelTitle = if ($hasTitleKey) { $el.title } else { Title-FromName -name $name } - if ($labelTitle) { - # formatted — независимое свойство (НЕ выводится из hyperlink): ссылка может быть не-форматированной и наоборот. - $formatted = if ($el.formatted -eq $true) { "true" } else { "false" } - X "$inner" - Emit-MLItems -val $labelTitle -indent "$inner`t" - X "$inner" - } - if ($el.tooltip) { Emit-MLText -tag "ToolTip" -text $el.tooltip -indent $inner } - if ($el.tooltipRepresentation) { X "$inner$($el.tooltipRepresentation)" } + Emit-DecorationTitle -el $el -name $name -indent $inner -auto Emit-CommonFlags -el $el -indent $inner @@ -3297,7 +3305,7 @@ function Emit-PictureDecoration { X "$indent" $inner = "$indent`t" - Emit-Title -el $el -name $name -indent $inner + Emit-DecorationTitle -el $el -name $name -indent $inner Emit-CommonFlags -el $el -indent $inner if ($el.picture -or $el.src) { diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 4e991026..cc8c9bf2 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.44 — Compile 1C managed form from JSON or object metadata +# form-compile v1.45 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -2639,21 +2639,29 @@ def emit_radio_button_field(lines, el, name, eid, indent): lines.append(f'{indent}') +# Заголовок декорации (Label/Picture): formatted-aware через единую ML-text форму +# (reuse resolve_ml_formatted, как у extendedTooltip). Sibling-ключ formatted — back-compat override. +def emit_decoration_title(lines, el, name, indent, auto=False): + has_key = 'title' in el + title_val = el['title'] if has_key else (title_from_name(name) if (auto and name) else None) + if title_val: + text, fmt = resolve_ml_formatted(title_val) + if 'formatted' in el: + fmt = bool(el['formatted']) + lines.append(f'{indent}<Title formatted="{"true" if fmt else "false"}">') + emit_ml_items(lines, f'{indent}\t', text) + lines.append(f'{indent}') + if el.get('tooltip'): + emit_mltext(lines, indent, 'ToolTip', el['tooltip']) + if el.get('tooltipRepresentation'): + lines.append(f'{indent}{el["tooltipRepresentation"]}') + + def emit_label(lines, el, name, eid, indent): lines.append(f'{indent}') inner = f'{indent}\t' - label_title = el['title'] if 'title' in el else title_from_name(name) - if label_title: - # formatted — независимое свойство (НЕ выводится из hyperlink). - formatted = 'true' if el.get('formatted') is True else 'false' - lines.append(f'{inner}') - emit_ml_items(lines, f'{inner}\t', label_title) - lines.append(f'{inner}') - if el.get('tooltip'): - emit_mltext(lines, inner, 'ToolTip', el['tooltip']) - if el.get('tooltipRepresentation'): - lines.append(f'{inner}{el["tooltipRepresentation"]}') + emit_decoration_title(lines, el, name, inner, auto=True) emit_common_flags(lines, el, inner) @@ -2971,7 +2979,7 @@ def emit_picture_decoration(lines, el, name, eid, indent): lines.append(f'{indent}') inner = f'{indent}\t' - emit_title(lines, el, name, inner) + emit_decoration_title(lines, el, name, inner) emit_common_flags(lines, el, inner) if el.get('picture') or el.get('src'): diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1 index 74595cb6..2f14b3b7 100644 --- a/.claude/skills/form-decompile/scripts/form-decompile.ps1 +++ b/.claude/skills/form-decompile/scripts/form-decompile.ps1 @@ -1,4 +1,4 @@ -# form-decompile v0.26 — Decompile 1C managed Form.xml to JSON DSL (draft) +# form-decompile v0.27 — Decompile 1C managed Form.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью. param( @@ -951,9 +951,9 @@ function Decompile-Element { $obj[$key] = $name Add-CommonProps $obj $node $name if ((Get-Child $node 'Hyperlink') -eq 'true') { $obj['hyperlink'] = $true } - # formatted — атрибут , НЕЗАВИСИМ от hyperlink (true → ключ, false → опускаем) + # title декорации — единая ML-text форма с авто-детектом formatted (как extendedTooltip) $tiNode = $node.SelectSingleNode("lf:Title", $ns) - if ($tiNode -and $tiNode.GetAttribute('formatted') -eq 'true') { $obj['formatted'] = $true } + if ($tiNode) { $tv = Get-MLFormattedValue $tiNode; if ($null -ne $tv) { $obj['title'] = $tv } } } 'LabelField' { $obj[$key] = $name @@ -967,6 +967,9 @@ function Decompile-Element { 'PictureDecoration' { $obj[$key] = $name Add-CommonProps $obj $node $name + # title декорации — единая ML-text форма с formatted (атрибут <Title formatted> у PictureDecoration) + $tiNode = $node.SelectSingleNode("lf:Title", $ns) + if ($tiNode) { $tv = Get-MLFormattedValue $tiNode; if ($null -ne $tv) { $obj['title'] = $tv } } $ref = $node.SelectSingleNode("lf:Picture/xr:Ref", $ns); if ($ref) { $obj['src'] = $ref.InnerText } $lt = $node.SelectSingleNode("lf:Picture/xr:LoadTransparent", $ns); if ($lt -and $lt.InnerText -eq 'true') { $obj['loadTransparent'] = $true } if ((Get-Child $node 'Hyperlink') -eq 'true') { $obj['hyperlink'] = $true } diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md index bd800883..daa92667 100644 --- a/docs/form-dsl-spec.md +++ b/docs/form-dsl-spec.md @@ -291,9 +291,9 @@ | Свойство | Тип | Описание | |----------|-----|----------| -| `title` | string | Текст надписи | +| `title` | string/object | Текст надписи. Единая ML-text форма (см. §4.1): строка / `{ru,en}` / `{text, formatted}`. У декораций `<Title>` всегда несёт атрибут `formatted` (авто-детект по разметке) | | `hyperlink` | bool | Режим гиперссылки | -| `formatted` | bool | Форматированный текст (`<Title formatted="true">`). **Независим от `hyperlink`** — выводится только при `true` | +| `formatted` | bool | **Back-compat**: явный override авто-детекта formatted (раньше — отдельный ключ). Предпочтительно — форма `title: {text, formatted}` | | `width` | int | Ширина | | `height` | int | Высота | | `autoMaxWidth` | bool | Автомаксимальная ширина |