mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-14 06:45:17 +03:00
feat(meta-compile,meta-decompile): Command>Picture — структурный блок (v1.29/v0.20)
Ключ `picture` команды компилятор писал плоской строкой, склеивая содержимое
структурного блока: <Picture><xr:Ref>CommonPicture.X</xr:Ref>
<xr:LoadTransparent>false</xr:LoadTransparent></Picture> → «CommonPicture.Xfalse»
(декомпилятор брал .InnerText всего блока). Багофикс формы значения.
Зеркало form-compile/form-decompile:
• picture — строка-ref (StdPicture.X / CommonPicture.X; встроенная abs: → <xr:Abs>)
+ sibling `loadTransparent` (дефолт true, конвенция кнопки/команды — фиксируем
только false) ЛИБО объект {src, loadTransparent?, transparentPixel?}.
• Emit-CommandPicture (компилятор) + структурный захват в декомпиляторе.
Структура {Ref, LoadTransparent} стабильна на корпусе (40/40, Std/CommonPicture).
Попутно (вскрыто roundtrip-сверкой ps1↔py): в py object-form реквизита список
flags не лоуэркейзился (в отличие от строкового пути), из-за чего декомпиляторный
`indexAdditional` не матчил `indexadditional` — PS -contains регистронезависим, а
py `in` нет → py писал DontIndex вместо IndexWithAdditionalOrder. Фикс зеркалит
строковый путь.
Роундтрип 120 объектов: match 94→95, TOTAL 183→158 (−25), Command>Picture=0,
новых diff нет. Регресс 46/46 ps1+py, ps1↔py identical. spec §7.1.3, кейс
catalog-command (3 формы picture: строка/loadTransparent:false/объект+transparentPixel).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# meta-compile v1.28 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.29 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -1580,6 +1580,29 @@ function Emit-Attribute {
|
||||
X "$indent</Attribute>"
|
||||
}
|
||||
|
||||
# <Picture> команды — структурный блок (зеркало form-compile). Дефолт LoadTransparent=true (конвенция
|
||||
# кнопки/команды): фиксируем только false. Значение: строка-ref + sibling `loadTransparent` ЛИБО объект
|
||||
# {src, loadTransparent?, transparentPixel?}. src с префиксом "abs:" → <xr:Abs>, иначе <xr:Ref>. Нет → <Picture/>.
|
||||
function Emit-CommandPicture {
|
||||
param([string]$indent, $cmd)
|
||||
$pic = $cmd.picture
|
||||
if (-not $pic) { X "$indent<Picture/>"; return }
|
||||
$src = $null; $lt = $true; $tpx = $null
|
||||
if ($pic -is [string]) { $src = "$pic"; if ($cmd.loadTransparent -eq $false) { $lt = $false } }
|
||||
else {
|
||||
$src = if ($pic.src) { "$($pic.src)" } elseif ($pic.ref) { "$($pic.ref)" } else { "" }
|
||||
if ($pic.loadTransparent -eq $false) { $lt = $false }
|
||||
$tpx = $pic.transparentPixel
|
||||
}
|
||||
if (-not $src) { X "$indent<Picture/>"; return }
|
||||
X "$indent<Picture>"
|
||||
if ($src -match '^abs:(.*)$') { X "$indent`t<xr:Abs>$(Esc-Xml $matches[1])</xr:Abs>" }
|
||||
else { X "$indent`t<xr:Ref>$(Esc-Xml $src)</xr:Ref>" }
|
||||
X "$indent`t<xr:LoadTransparent>$(if ($lt) { 'true' } else { 'false' })</xr:LoadTransparent>"
|
||||
if ($tpx) { X "$indent`t<xr:TransparentPixel x=`"$($tpx.x)`" y=`"$($tpx.y)`"/>" }
|
||||
X "$indent</Picture>"
|
||||
}
|
||||
|
||||
# --- 8b. Command emitter ---
|
||||
# $cmd — объект свойств команды. Поля (omit-on-default): synonym/tooltip (ML), comment, group,
|
||||
# commandParameterType (тип), parameterUseMode (Single), modifiesData (false), representation (Auto),
|
||||
@@ -1608,7 +1631,7 @@ function Emit-Command {
|
||||
$rep = if ($cmd.representation) { "$($cmd.representation)" } else { "Auto" }
|
||||
X "$indent`t`t<Representation>$rep</Representation>"
|
||||
Emit-MLText "$indent`t`t" "ToolTip" $cmd.tooltip
|
||||
if ($cmd.picture) { X "$indent`t`t<Picture>$(Esc-Xml "$($cmd.picture)")</Picture>" } else { X "$indent`t`t<Picture/>" }
|
||||
Emit-CommandPicture "$indent`t`t" $cmd
|
||||
if ($cmd.shortcut) { X "$indent`t`t<Shortcut>$(Esc-Xml "$($cmd.shortcut)")</Shortcut>" } else { X "$indent`t`t<Shortcut/>" }
|
||||
$osu = if ($cmd.onMainServerUnavalableBehavior) { "$($cmd.onMainServerUnavalableBehavior)" } else { "Auto" }
|
||||
X "$indent`t`t<OnMainServerUnavalableBehavior>$osu</OnMainServerUnavalableBehavior>"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# meta-compile v1.28 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.29 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -832,7 +832,8 @@ def parse_attribute_shorthand(val):
|
||||
'synonym': val['synonym'] if val.get('synonym') is not None else split_camel_case(name),
|
||||
'tooltip': val.get('tooltip'),
|
||||
'comment': str(val['comment']) if val.get('comment') else '',
|
||||
'flags': list(val.get('flags', [])),
|
||||
# Лоуэркейз как в строковом пути (стр.809): проверки флагов регистронезависимы (зеркало PS -contains).
|
||||
'flags': [str(f).strip().lower() for f in val.get('flags', [])],
|
||||
'fillChecking': fc,
|
||||
'indexing': str(val['indexing']) if val.get('indexing') else '',
|
||||
'multiLine': True if val.get('multiLine') is True else False,
|
||||
@@ -1630,6 +1631,39 @@ def emit_attribute(indent, parsed, context):
|
||||
# 9. TabularSection emitter
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def emit_command_picture(indent, cmd):
|
||||
"""<Picture> команды — структурный блок (зеркало form-compile). Дефолт LoadTransparent=true (конвенция
|
||||
кнопки/команды): фиксируем только false. Значение: строка-ref + sibling loadTransparent ЛИБО объект
|
||||
{src, loadTransparent?, transparentPixel?}. src с префиксом "abs:" → <xr:Abs>, иначе <xr:Ref>. Нет → <Picture/>."""
|
||||
pic = cmd.get('picture')
|
||||
if not pic:
|
||||
X(f'{indent}<Picture/>')
|
||||
return
|
||||
lt = True
|
||||
tpx = None
|
||||
if isinstance(pic, str):
|
||||
src = pic
|
||||
if cmd.get('loadTransparent') is False:
|
||||
lt = False
|
||||
else:
|
||||
src = str(pic.get('src') or pic.get('ref') or '')
|
||||
if pic.get('loadTransparent') is False:
|
||||
lt = False
|
||||
tpx = pic.get('transparentPixel')
|
||||
if not src:
|
||||
X(f'{indent}<Picture/>')
|
||||
return
|
||||
X(f'{indent}<Picture>')
|
||||
m = re.match(r'^abs:(.*)$', src)
|
||||
if m:
|
||||
X(f'{indent}\t<xr:Abs>{esc_xml(m.group(1))}</xr:Abs>')
|
||||
else:
|
||||
X(f'{indent}\t<xr:Ref>{esc_xml(src)}</xr:Ref>')
|
||||
X(f'{indent}\t<xr:LoadTransparent>{"true" if lt else "false"}</xr:LoadTransparent>')
|
||||
if tpx:
|
||||
X(f'{indent}\t<xr:TransparentPixel x="{tpx.get("x")}" y="{tpx.get("y")}"/>')
|
||||
X(f'{indent}</Picture>')
|
||||
|
||||
def emit_command(indent, cmd_name, cmd):
|
||||
X(f'{indent}<Command uuid="{new_uuid()}">')
|
||||
X(f'{indent}\t<Properties>')
|
||||
@@ -1651,10 +1685,7 @@ def emit_command(indent, cmd_name, cmd):
|
||||
X(f'{indent}\t\t<ModifiesData>{"true" if cmd.get("modifiesData") is True else "false"}</ModifiesData>')
|
||||
X(f'{indent}\t\t<Representation>{cmd.get("representation") or "Auto"}</Representation>')
|
||||
emit_mltext(f'{indent}\t\t', 'ToolTip', cmd.get('tooltip'))
|
||||
if cmd.get('picture'):
|
||||
X(f'{indent}\t\t<Picture>{esc_xml(str(cmd["picture"]))}</Picture>')
|
||||
else:
|
||||
X(f'{indent}\t\t<Picture/>')
|
||||
emit_command_picture(f'{indent}\t\t', cmd)
|
||||
if cmd.get('shortcut'):
|
||||
X(f'{indent}\t\t<Shortcut>{esc_xml(str(cmd["shortcut"]))}</Shortcut>')
|
||||
else:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# meta-decompile v0.19 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
||||
# meta-decompile v0.20 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
#
|
||||
# Пилот: только Catalog. Инверс meta-compile (omit-on-default: ключ эмитим только
|
||||
@@ -589,7 +589,25 @@ if ($childObjs) {
|
||||
$mdN = $cp.SelectSingleNode('md:ModifiesData', $nsm); if ($mdN -and $mdN.InnerText -eq 'true') { $o['modifiesData'] = $true }
|
||||
$repN = $cp.SelectSingleNode('md:Representation', $nsm); if ($repN -and $repN.InnerText -ne 'Auto') { $o['representation'] = $repN.InnerText }
|
||||
$ctt = Get-MLValue ($cp.SelectSingleNode('md:ToolTip', $nsm)); if ($null -ne $ctt) { $o['tooltip'] = $ctt }
|
||||
$picN = $cp.SelectSingleNode('md:Picture', $nsm); if ($picN -and $picN.InnerText) { $o['picture'] = $picN.InnerText }
|
||||
# <Picture> — структурный блок (зеркало form-decompile Set-CommandPicture). Дефолт LoadTransparent=true:
|
||||
# скаляр `picture` + sibling `loadTransparent:false` при отклонении; объект {src,loadTransparent?,transparentPixel} при TransparentPixel.
|
||||
$refN = $cp.SelectSingleNode('md:Picture/xr:Ref', $nsm)
|
||||
$absN = $cp.SelectSingleNode('md:Picture/xr:Abs', $nsm)
|
||||
if ($refN -or $absN) {
|
||||
$psrc = if ($refN) { $refN.InnerText } else { "abs:$($absN.InnerText)" }
|
||||
$ltN = $cp.SelectSingleNode('md:Picture/xr:LoadTransparent', $nsm)
|
||||
$ltFalse = ($ltN -and $ltN.InnerText -eq 'false')
|
||||
$tpxN = $cp.SelectSingleNode('md:Picture/xr:TransparentPixel', $nsm)
|
||||
if ($tpxN) {
|
||||
$po = [ordered]@{ src = $psrc }
|
||||
if ($ltFalse) { $po['loadTransparent'] = $false }
|
||||
$po['transparentPixel'] = [ordered]@{ x = [int]$tpxN.GetAttribute('x'); y = [int]$tpxN.GetAttribute('y') }
|
||||
$o['picture'] = $po
|
||||
} else {
|
||||
$o['picture'] = $psrc
|
||||
if ($ltFalse) { $o['loadTransparent'] = $false }
|
||||
}
|
||||
}
|
||||
$scN = $cp.SelectSingleNode('md:Shortcut', $nsm); if ($scN -and $scN.InnerText) { $o['shortcut'] = $scN.InnerText }
|
||||
$osuN = $cp.SelectSingleNode('md:OnMainServerUnavalableBehavior', $nsm); if ($osuN -and $osuN.InnerText -ne 'Auto') { $o['onMainServerUnavalableBehavior'] = $osuN.InnerText }
|
||||
$cmdMap[$cn] = $o
|
||||
|
||||
+14
-3
@@ -444,15 +444,26 @@ JSON DSL для описания объектов метаданных конф
|
||||
| `parameterUseMode` | ParameterUseMode | `Single` (`Single`/`Multiple`) |
|
||||
| `modifiesData` | ModifiesData | `false` (bool) |
|
||||
| `representation` | Representation | `Auto` |
|
||||
| `picture` / `shortcut` | Picture / Shortcut | пусто |
|
||||
| `picture` | Picture | пусто (структурный блок, см. ниже) |
|
||||
| `loadTransparent` | Picture/LoadTransparent | `true` (bool, sibling `picture`) |
|
||||
| `shortcut` | Shortcut | пусто |
|
||||
| `onMainServerUnavalableBehavior` | OnMainServerUnavalableBehavior | `Auto` |
|
||||
|
||||
**`picture`** — картинка команды `<Picture>` (структурный блок `<xr:Ref>`+`<xr:LoadTransparent>`, зеркало form-compile).
|
||||
Значение: строка-ref (`StdPicture.X` / `CommonPicture.X`; встроенная — префикс `abs:` → `<xr:Abs>`) ЛИБО объект
|
||||
`{src, loadTransparent?, transparentPixel?}`. LoadTransparent платформа пишет всегда, **дефолт `true`** (конвенция
|
||||
кнопки/команды) — фиксируем только `false`: строкой-ref + sibling-ключ `loadTransparent: false`, либо внутри объекта.
|
||||
`transparentPixel: {x, y}` → `<xr:TransparentPixel>`. Декомпилятор: скаляр при LoadTransparent=true без пикселя,
|
||||
иначе объект.
|
||||
|
||||
```json
|
||||
"commands": {
|
||||
"ПечатьЭтикеток": {
|
||||
"synonym": "Печать этикеток", "group": "FormCommandBarImportant",
|
||||
"commandParameterType": "CatalogRef.Номенклатура", "modifiesData": true
|
||||
}
|
||||
"commandParameterType": "CatalogRef.Номенклатура", "modifiesData": true,
|
||||
"picture": "StdPicture.Print"
|
||||
},
|
||||
"ЗагрузитьИзФайла": { "picture": "CommonPicture.Загрузка", "loadTransparent": false }
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -9,7 +9,16 @@
|
||||
"commandParameterType": "CatalogRef.Номенклатура",
|
||||
"parameterUseMode": "Multiple",
|
||||
"modifiesData": true,
|
||||
"tooltip": "Печать этикеток для выбранных товаров"
|
||||
"tooltip": "Печать этикеток для выбранных товаров",
|
||||
"picture": "StdPicture.Print"
|
||||
},
|
||||
"ЗагрузитьИзФайла": {
|
||||
"synonym": "Загрузить из файла",
|
||||
"picture": "CommonPicture.Загрузка",
|
||||
"loadTransparent": false
|
||||
},
|
||||
"ОбновитьСписок": {
|
||||
"picture": { "src": "StdPicture.Refresh", "transparentPixel": { "x": 0, "y": 0 } }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+53
-1
@@ -114,7 +114,59 @@
|
||||
<v8:content>Печать этикеток для выбранных товаров</v8:content>
|
||||
</v8:item>
|
||||
</ToolTip>
|
||||
<Picture/>
|
||||
<Picture>
|
||||
<xr:Ref>StdPicture.Print</xr:Ref>
|
||||
<xr:LoadTransparent>true</xr:LoadTransparent>
|
||||
</Picture>
|
||||
<Shortcut/>
|
||||
<OnMainServerUnavalableBehavior>Auto</OnMainServerUnavalableBehavior>
|
||||
</Properties>
|
||||
</Command>
|
||||
<Command uuid="UUID-013">
|
||||
<Properties>
|
||||
<Name>ЗагрузитьИзФайла</Name>
|
||||
<Synonym>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Загрузить из файла</v8:content>
|
||||
</v8:item>
|
||||
</Synonym>
|
||||
<Comment/>
|
||||
<Group></Group>
|
||||
<CommandParameterType/>
|
||||
<ParameterUseMode>Single</ParameterUseMode>
|
||||
<ModifiesData>false</ModifiesData>
|
||||
<Representation>Auto</Representation>
|
||||
<ToolTip/>
|
||||
<Picture>
|
||||
<xr:Ref>CommonPicture.Загрузка</xr:Ref>
|
||||
<xr:LoadTransparent>false</xr:LoadTransparent>
|
||||
</Picture>
|
||||
<Shortcut/>
|
||||
<OnMainServerUnavalableBehavior>Auto</OnMainServerUnavalableBehavior>
|
||||
</Properties>
|
||||
</Command>
|
||||
<Command uuid="UUID-014">
|
||||
<Properties>
|
||||
<Name>ОбновитьСписок</Name>
|
||||
<Synonym>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Обновить список</v8:content>
|
||||
</v8:item>
|
||||
</Synonym>
|
||||
<Comment/>
|
||||
<Group></Group>
|
||||
<CommandParameterType/>
|
||||
<ParameterUseMode>Single</ParameterUseMode>
|
||||
<ModifiesData>false</ModifiesData>
|
||||
<Representation>Auto</Representation>
|
||||
<ToolTip/>
|
||||
<Picture>
|
||||
<xr:Ref>StdPicture.Refresh</xr:Ref>
|
||||
<xr:LoadTransparent>true</xr:LoadTransparent>
|
||||
<xr:TransparentPixel x="0" y="0"/>
|
||||
</Picture>
|
||||
<Shortcut/>
|
||||
<OnMainServerUnavalableBehavior>Auto</OnMainServerUnavalableBehavior>
|
||||
</Properties>
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
&НаКлиенте
|
||||
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
|
||||
|
||||
// Вставьте обработчик команды.
|
||||
|
||||
КонецПроцедуры
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
&НаКлиенте
|
||||
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
|
||||
|
||||
// Вставьте обработчик команды.
|
||||
|
||||
КонецПроцедуры
|
||||
Reference in New Issue
Block a user