From 9bfc431a6aaa0fd2648f91f96f65a2026f19c9ee Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Mon, 6 Apr 2026 19:23:18 +0300 Subject: [PATCH] feat(skd): @name= in set-structure, Folder in selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - skd-edit: set-structure supports @name= for naming groupings (e.g. "Поле @name=ДанныеОтчета > details") - skd-edit: add-selection supports Folder(Title: field1, field2) syntax for SelectedItemFolder - skd-compile: selection supports {"folder": "Title", "items": [...]} for SelectedItemFolder - Both generate lwsTitle, nested SelectedItemField items, and placement=Auto Co-Authored-By: Claude Opus 4.6 (1M context) --- .../skd-compile/scripts/skd-compile.ps1 | 16 +++++++++ .../skills/skd-compile/scripts/skd-compile.py | 15 ++++++++ .claude/skills/skd-edit/scripts/skd-edit.ps1 | 36 +++++++++++++++++++ .claude/skills/skd-edit/scripts/skd-edit.py | 33 +++++++++++++++++ 4 files changed, 100 insertions(+) diff --git a/.claude/skills/skd-compile/scripts/skd-compile.ps1 b/.claude/skills/skd-compile/scripts/skd-compile.ps1 index a23ac423..bd1eb8b1 100644 --- a/.claude/skills/skd-compile/scripts/skd-compile.ps1 +++ b/.claude/skills/skd-compile/scripts/skd-compile.ps1 @@ -1367,6 +1367,22 @@ function Emit-Selection { X "$indent`t`t$(Esc-Xml $item)" X "$indent`t" } + } elseif ($item.folder) { + X "$indent`t" + X "$indent`t`t" + X "$indent`t`t`t" + X "$indent`t`t`t`tru" + X "$indent`t`t`t`t$(Esc-Xml "$($item.folder)")" + X "$indent`t`t`t" + X "$indent`t`t" + foreach ($sub in $item.items) { + $subName = if ($sub -is [string]) { $sub } else { "$($sub.field)" } + X "$indent`t`t" + X "$indent`t`t`t$(Esc-Xml $subName)" + X "$indent`t`t" + } + X "$indent`t`tAuto" + X "$indent`t" } else { X "$indent`t" X "$indent`t`t$(Esc-Xml "$($item.field)")" diff --git a/.claude/skills/skd-compile/scripts/skd-compile.py b/.claude/skills/skd-compile/scripts/skd-compile.py index cf7e3441..0fb0ebb4 100644 --- a/.claude/skills/skd-compile/scripts/skd-compile.py +++ b/.claude/skills/skd-compile/scripts/skd-compile.py @@ -1154,6 +1154,21 @@ def emit_selection(lines, items, indent, skip_auto=False): lines.append(f'{indent}\t') lines.append(f'{indent}\t\t{esc_xml(item)}') lines.append(f'{indent}\t') + elif item.get('folder'): + lines.append(f'{indent}\t') + lines.append(f'{indent}\t\t') + lines.append(f'{indent}\t\t\t') + lines.append(f'{indent}\t\t\t\tru') + lines.append(f'{indent}\t\t\t\t{esc_xml(str(item["folder"]))}') + lines.append(f'{indent}\t\t\t') + lines.append(f'{indent}\t\t') + for sub in (item.get('items') or []): + sub_name = str(sub.get('field', sub)) if isinstance(sub, dict) else str(sub) + lines.append(f'{indent}\t\t') + lines.append(f'{indent}\t\t\t{esc_xml(sub_name)}') + lines.append(f'{indent}\t\t') + lines.append(f'{indent}\t\tAuto') + lines.append(f'{indent}\t') else: lines.append(f'{indent}\t') lines.append(f'{indent}\t\t{esc_xml(str(item["field"]))}') diff --git a/.claude/skills/skd-edit/scripts/skd-edit.ps1 b/.claude/skills/skd-edit/scripts/skd-edit.ps1 index abc9c1ca..0214e0ad 100644 --- a/.claude/skills/skd-edit/scripts/skd-edit.ps1 +++ b/.claude/skills/skd-edit/scripts/skd-edit.ps1 @@ -543,6 +543,11 @@ function Parse-StructureShorthand { $seg = $segments[$i].Trim() $group = @{ type = "group" } + if ($seg -match '@name=(.+)') { + $group["name"] = $Matches[1].Trim() + $seg = ($seg -replace '\s*@name=.+', '').Trim() + } + if ($seg -match '^(?i)(details|детали)$') { $group["groupBy"] = @() } else { @@ -861,6 +866,32 @@ function Build-SelectionItemFragment { $lines = @() if ($fieldName -eq "Auto") { $lines += "$i" + } elseif ($fieldName -match '^Folder\((.+)\)$') { + $inner = $Matches[1] + $colonIdx = $inner.IndexOf(':') + if ($colonIdx -gt 0) { + $title = $inner.Substring(0, $colonIdx).Trim() + $items = $inner.Substring($colonIdx + 1) -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ } + } else { + $title = "" + $items = $inner -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ } + } + $lines += "$i" + if ($title) { + $lines += "$i`t" + $lines += "$i`t`t" + $lines += "$i`t`t`tru" + $lines += "$i`t`t`t$(Esc-Xml $title)" + $lines += "$i`t`t" + $lines += "$i`t" + } + foreach ($item in $items) { + $lines += "$i`t" + $lines += "$i`t`t$(Esc-Xml $item)" + $lines += "$i`t" + } + $lines += "$i`tAuto" + $lines += "$i" } else { $lines += "$i" $lines += "$i`t$(Esc-Xml $fieldName)" @@ -1070,6 +1101,11 @@ function Build-StructureItemFragment { $lines = @() $lines += "$i" + # name + if ($item["name"]) { + $lines += "$i`t$(Esc-Xml $item["name"])" + } + # groupItems $groupBy = $item["groupBy"] if (-not $groupBy -or $groupBy.Count -eq 0) { diff --git a/.claude/skills/skd-edit/scripts/skd-edit.py b/.claude/skills/skd-edit/scripts/skd-edit.py index 27123fac..dfdb3a30 100644 --- a/.claude/skills/skd-edit/scripts/skd-edit.py +++ b/.claude/skills/skd-edit/scripts/skd-edit.py @@ -509,6 +509,11 @@ def parse_structure_shorthand(s): seg = segments[i].strip() group = {"type": "group"} + name_m = re.search(r'\s*@name=(.+)', seg) + if name_m: + group["name"] = name_m.group(1).strip() + seg = re.sub(r'\s*@name=.+', '', seg).strip() + if re.match(r'^(?i)(details|\u0434\u0435\u0442\u0430\u043b\u0438)$', seg): group["groupBy"] = [] else: @@ -767,6 +772,31 @@ def build_selection_item_fragment(field_name, indent): i = indent if field_name == "Auto": return f'{i}' + m = re.match(r'^Folder\((.+)\)$', field_name) + if m: + inner = m.group(1) + colon_idx = inner.find(':') + if colon_idx > 0: + title = inner[:colon_idx].strip() + items = [x.strip() for x in inner[colon_idx + 1:].split(',') if x.strip()] + else: + title = "" + items = [x.strip() for x in inner.split(',') if x.strip()] + lines = [f'{i}'] + if title: + lines.append(f"{i}\t") + lines.append(f"{i}\t\t") + lines.append(f"{i}\t\t\tru") + lines.append(f"{i}\t\t\t{esc_xml(title)}") + lines.append(f"{i}\t\t") + lines.append(f"{i}\t") + for item in items: + lines.append(f'{i}\t') + lines.append(f"{i}\t\t{esc_xml(item)}") + lines.append(f"{i}\t") + lines.append(f"{i}\tAuto") + lines.append(f"{i}") + return "\r\n".join(lines) lines = [ f'{i}', f"{i}\t{esc_xml(field_name)}", @@ -944,6 +974,9 @@ def build_structure_item_fragment(item, indent): i = indent lines = [f'{i}'] + if item.get("name"): + lines.append(f"{i}\t{esc_xml(item['name'])}") + group_by = item.get("groupBy", []) if not group_by: lines.append(f"{i}\t")