diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index d52c7c2b..60d4eb95 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.ps1 +++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1 @@ -341,14 +341,14 @@ function Emit-MLItems { param([string]$indent, $val) if ($val -is [System.Collections.IDictionary]) { foreach ($k in $val.Keys) { - X "$indent"; X "$indent`t$k"; X "$indent`t$(Esc-Xml "$($val[$k])")"; X "$indent" + X "$indent"; X "$indent`t$k"; X "$indent`t$(Esc-XmlText "$($val[$k])")"; X "$indent" } } elseif ($val -is [System.Management.Automation.PSCustomObject]) { foreach ($p in $val.PSObject.Properties) { - X "$indent"; X "$indent`t$($p.Name)"; X "$indent`t$(Esc-Xml "$($p.Value)")"; X "$indent" + X "$indent"; X "$indent`t$($p.Name)"; X "$indent`t$(Esc-XmlText "$($p.Value)")"; X "$indent" } } else { - X "$indent"; X "$indent`tru"; X "$indent`t$(Esc-Xml "$val")"; X "$indent" + X "$indent"; X "$indent`tru"; X "$indent`t$(Esc-XmlText "$val")"; X "$indent" } } function Emit-MLText { @@ -885,6 +885,7 @@ function Emit-StandardAttribute { $dh = OvOr 'DataHistory' 'Use' $fts = OvOr 'FullTextSearch' 'Use' $syn = OvOr 'Synonym' '' + $tt = OvOr 'ToolTip' '' X "$indent" X "$indent`t" X "$indent`t$fc" @@ -892,7 +893,7 @@ function Emit-StandardAttribute { X "$indent`t$ffv" X "$indent`tAuto" X "$indent`t" - X "$indent`t" + Emit-MLText "$indent`t" "xr:ToolTip" $tt X "$indent`tfalse" X "$indent`t" X "$indent`t" @@ -903,16 +904,7 @@ function Emit-StandardAttribute { X "$indent`t$dh" X "$indent`tfalse" X "$indent`t" - if ($syn) { - X "$indent`t" - X "$indent`t`t" - X "$indent`t`t`tru" - X "$indent`t`t`t$(Esc-Xml $syn)" - X "$indent`t`t" - X "$indent`t" - } else { - X "$indent`t" - } + Emit-MLText "$indent`t" "xr:Synonym" $syn X "$indent`t" X "$indent`t$fts" X "$indent`t" @@ -944,7 +936,8 @@ function Emit-StandardAttributes { if ($conditional -and $sa) { $d = $sa.$a if ($d) { - if ($null -ne $d.synonym) { $ov['Synonym'] = "$($d.synonym)" } + if ($null -ne $d.synonym) { $ov['Synonym'] = $d.synonym } # строка ИЛИ {ru,en} + if ($null -ne $d.tooltip) { $ov['ToolTip'] = $d.tooltip } # строка ИЛИ {ru,en} if ($d.fillChecking) { $ov['FillChecking'] = "$($d.fillChecking)" } if ($null -ne $d.fillFromFillingValue) { $ov['FillFromFillingValue'] = if ($d.fillFromFillingValue) { 'true' } else { 'false' } } if ($d.fullTextSearch) { $ov['FullTextSearch'] = "$($d.fullTextSearch)" } diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index 651ae312..31e14afa 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.py +++ b/.claude/skills/meta-compile/scripts/meta-compile.py @@ -207,12 +207,12 @@ def emit_ml_items(indent, val): for k, v in val.items(): X(f'{indent}') X(f'{indent}\t{k}') - X(f'{indent}\t{esc_xml(str(v))}') + X(f'{indent}\t{esc_xml_text(str(v))}') X(f'{indent}') else: X(f'{indent}') X(f'{indent}\tru') - X(f'{indent}\t{esc_xml(str(val))}') + X(f'{indent}\t{esc_xml_text(str(val))}') X(f'{indent}') def emit_mltext(indent, tag, text): @@ -881,6 +881,7 @@ def emit_standard_attribute(indent, attr_name, ov=None): dh = ov.get('DataHistory', 'Use') fts = ov.get('FullTextSearch', 'Use') syn = ov.get('Synonym', '') + tt = ov.get('ToolTip', '') X(f'{indent}') X(f'{indent}\t') X(f'{indent}\t{fc}') @@ -888,7 +889,7 @@ def emit_standard_attribute(indent, attr_name, ov=None): X(f'{indent}\t{ffv}') X(f'{indent}\tAuto') X(f'{indent}\t') - X(f'{indent}\t') + emit_mltext(f'{indent}\t', 'xr:ToolTip', tt) X(f'{indent}\tfalse') X(f'{indent}\t') X(f'{indent}\t') @@ -899,15 +900,7 @@ def emit_standard_attribute(indent, attr_name, ov=None): X(f'{indent}\t{dh}') X(f'{indent}\tfalse') X(f'{indent}\t') - if syn: - X(f'{indent}\t') - X(f'{indent}\t\t') - X(f'{indent}\t\t\tru') - X(f'{indent}\t\t\t{esc_xml(syn)}') - X(f'{indent}\t\t') - X(f'{indent}\t') - else: - X(f'{indent}\t') + emit_mltext(f'{indent}\t', 'xr:Synonym', syn) X(f'{indent}\t') X(f'{indent}\t{fts}') X(f'{indent}\t') @@ -936,7 +929,9 @@ def emit_standard_attributes(indent, object_type): d = sa.get(a) if d: if d.get('synonym') is not None: - ov['Synonym'] = str(d['synonym']) + ov['Synonym'] = d['synonym'] # строка ИЛИ {ru,en} + if d.get('tooltip') is not None: + ov['ToolTip'] = d['tooltip'] # строка ИЛИ {ru,en} if d.get('fillChecking'): ov['FillChecking'] = str(d['fillChecking']) if d.get('fillFromFillingValue') is not None: diff --git a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 index af14d17d..eb739842 100644 --- a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 +++ b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 @@ -1,4 +1,4 @@ -# meta-decompile v0.8 — XML объекта метаданных 1С → JSON-черновик формата meta-compile +# meta-decompile v0.9 — XML объекта метаданных 1С → JSON-черновик формата meta-compile # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # # Пилот: только Catalog. Инверс meta-compile (omit-on-default: ключ эмитим только @@ -115,7 +115,8 @@ function Get-MLValue { if ($items.Count -eq 1) { $lang = $items[0].SelectSingleNode('v8:lang', $nsm).InnerText $content = $items[0].SelectSingleNode('v8:content', $nsm).InnerText - if ($lang -eq 'ru') { return $content } + # Единственный ru-item: пустое содержимое ≡ отсутствие значения → $null (иначе tooltip:"" ≠ self-close). + if ($lang -eq 'ru') { if ($content -eq '') { return $null } else { return $content } } } $o = [ordered]@{} foreach ($it in $items) { @@ -296,9 +297,11 @@ if ($saNode) { $ffvN = $sa.SelectSingleNode('xr:FillFromFillingValue', $nsm); $ffv = ($ffvN -and $ffvN.InnerText -eq 'true') $profFfv = ($prof['fillFromFillingValue'] -eq $true) if ($ffv -ne $profFfv) { $ov['fillFromFillingValue'] = $ffv } - # Synonym (профиль пуст) - $syn = Get-MLru ($sa.SelectSingleNode('xr:Synonym', $nsm)) - if ($syn) { $ov['synonym'] = $syn } + # Synonym / ToolTip (профиль пуст) — строка ru | {ru,en} + $syn = Get-MLValue ($sa.SelectSingleNode('xr:Synonym', $nsm)) + if ($null -ne $syn) { $ov['synonym'] = $syn } + $tt = Get-MLValue ($sa.SelectSingleNode('xr:ToolTip', $nsm)) + if ($null -ne $tt) { $ov['tooltip'] = $tt } # FullTextSearch / DataHistory (профиль = Use) $ftsN = $sa.SelectSingleNode('xr:FullTextSearch', $nsm); if ($ftsN -and $ftsN.InnerText -ne 'Use') { $ov['fullTextSearch'] = $ftsN.InnerText } $dhN = $sa.SelectSingleNode('xr:DataHistory', $nsm); if ($dhN -and $dhN.InnerText -ne 'Use') { $ov['dataHistory'] = $dhN.InnerText } diff --git a/docs/meta-dsl-spec.md b/docs/meta-dsl-spec.md index bad57c67..ce48b43a 100644 --- a/docs/meta-dsl-spec.md +++ b/docs/meta-dsl-spec.md @@ -285,7 +285,7 @@ JSON DSL для описания объектов метаданных конф Формат: `standardAttributes` — объект `{ ИмяРеквизита: { переопределения } }`. Имена реквизитов — как в XML: `PredefinedDataName`, `Predefined`, `Ref`, `DeletionMark`, `IsFolder`, `Owner`, `Parent`, `Description`, `Code`. -Переопределяемые поля реквизита: `synonym` (строка → `` ru), `fillChecking` (`DontCheck`|`ShowError`|`ShowWarning`), `fillFromFillingValue` (bool), `fullTextSearch` (`Use`|`DontUse`), `dataHistory` (`Use`|`DontUse`). +Переопределяемые поля реквизита: `synonym` (ML — строка/`{ru,en}`), `tooltip` (ML), `fillChecking` (`DontCheck`|`ShowError`|`ShowWarning`), `fillFromFillingValue` (bool), `fullTextSearch` (`Use`|`DontUse`), `dataHistory` (`Use`|`DontUse`). **Профиль материализованного блока** (значения, которые платформа заполняет автоматически — задавать их в DSL не нужно): diff --git a/tests/skills/cases/meta-compile/catalog-standard-attributes.json b/tests/skills/cases/meta-compile/catalog-standard-attributes.json index f3e10e21..00f0eb6b 100644 --- a/tests/skills/cases/meta-compile/catalog-standard-attributes.json +++ b/tests/skills/cases/meta-compile/catalog-standard-attributes.json @@ -4,8 +4,8 @@ "type": "Catalog", "name": "Контрагенты", "standardAttributes": { - "Description": { "synonym": "Наименование контрагента" }, - "Code": { "fillChecking": "ShowError" } + "Description": { "synonym": { "ru": "Наименование контрагента", "en": "Counterparty name" }, "tooltip": "Полное наименование" }, + "Code": { "fillChecking": "ShowError", "tooltip": { "ru": "Код", "en": "Code" } } } }, "validatePath": "Catalogs/Контрагенты", diff --git a/tests/skills/cases/meta-compile/snapshots/catalog-standard-attributes/Catalogs/Контрагенты.xml b/tests/skills/cases/meta-compile/snapshots/catalog-standard-attributes/Catalogs/Контрагенты.xml index 8dc5bde3..f20a7f35 100644 --- a/tests/skills/cases/meta-compile/snapshots/catalog-standard-attributes/Catalogs/Контрагенты.xml +++ b/tests/skills/cases/meta-compile/snapshots/catalog-standard-attributes/Catalogs/Контрагенты.xml @@ -238,7 +238,12 @@ false Auto - + + + ru + Полное наименование + + false @@ -254,6 +259,10 @@ ru Наименование контрагента + + en + Counterparty name + Use @@ -269,7 +278,16 @@ false Auto - + + + ru + Код + + + en + Code + + false