Sync third-party and MCP marketplace plugins
Constraint: Public skills are published only by explicit administrator action unless they are tracked third-party market sources. Confidence: high Scope-risk: narrow Directive: Keep private/internal skills out of the public marketplace and preserve normal incremental market Git history. Tested: Marketplace validation passed.
This commit is contained in:
@@ -281,22 +281,22 @@
|
|||||||
"category": "文档处理"
|
"category": "文档处理"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ppt-master",
|
"name": "ui-ux-pro-max",
|
||||||
"source": {
|
"source": {
|
||||||
"source": "local",
|
"source": "local",
|
||||||
"path": "./plugins/codex/plugins/ppt-master"
|
"path": "./plugins/codex/plugins/ui-ux-pro-max"
|
||||||
},
|
},
|
||||||
"policy": {
|
"policy": {
|
||||||
"installation": "AVAILABLE",
|
"installation": "AVAILABLE",
|
||||||
"authentication": "ON_INSTALL"
|
"authentication": "ON_INSTALL"
|
||||||
},
|
},
|
||||||
"category": "文档处理"
|
"category": "设计"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ui-ux-pro-max",
|
"name": "taste-skill",
|
||||||
"source": {
|
"source": {
|
||||||
"source": "local",
|
"source": "local",
|
||||||
"path": "./plugins/codex/plugins/ui-ux-pro-max"
|
"path": "./plugins/codex/plugins/taste-skill"
|
||||||
},
|
},
|
||||||
"policy": {
|
"policy": {
|
||||||
"installation": "AVAILABLE",
|
"installation": "AVAILABLE",
|
||||||
@@ -316,6 +316,18 @@
|
|||||||
},
|
},
|
||||||
"category": "开发工具"
|
"category": "开发工具"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "ppt-master",
|
||||||
|
"source": {
|
||||||
|
"source": "local",
|
||||||
|
"path": "./plugins/codex/plugins/ppt-master"
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
"installation": "AVAILABLE",
|
||||||
|
"authentication": "ON_INSTALL"
|
||||||
|
},
|
||||||
|
"category": "文档处理"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "next-skills",
|
"name": "next-skills",
|
||||||
"source": {
|
"source": {
|
||||||
@@ -339,18 +351,6 @@
|
|||||||
"authentication": "ON_INSTALL"
|
"authentication": "ON_INSTALL"
|
||||||
},
|
},
|
||||||
"category": "MCP"
|
"category": "MCP"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "taste-skill",
|
|
||||||
"source": {
|
|
||||||
"source": "local",
|
|
||||||
"path": "./plugins/codex/plugins/taste-skill"
|
|
||||||
},
|
|
||||||
"policy": {
|
|
||||||
"installation": "AVAILABLE",
|
|
||||||
"authentication": "ON_INSTALL"
|
|
||||||
},
|
|
||||||
"category": "设计"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,14 +36,23 @@
|
|||||||
"commit": "0d95a81d35a9f2d123a5e9430d1cfc43d55f1bb0",
|
"commit": "0d95a81d35a9f2d123a5e9430d1cfc43d55f1bb0",
|
||||||
"syncedAt": "2026-07-06T02:08:42Z"
|
"syncedAt": "2026-07-06T02:08:42Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "taste-skill",
|
||||||
|
"pluginName": "taste-skill",
|
||||||
|
"repo": "https://github.com/Leonxlnx/taste-skill.git",
|
||||||
|
"ref": "main",
|
||||||
|
"adapter": "skill-collection",
|
||||||
|
"commit": "b17742737e796305d829b3ad39eda3add0d79060",
|
||||||
|
"syncedAt": "2026-07-07T02:43:19Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "shadcn",
|
"id": "shadcn",
|
||||||
"pluginName": "shadcn",
|
"pluginName": "shadcn",
|
||||||
"repo": "https://github.com/shadcn-ui/ui.git",
|
"repo": "https://github.com/shadcn-ui/ui.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"adapter": "claude-skill",
|
"adapter": "claude-skill",
|
||||||
"commit": "d8ace420baa5c8a1abccd75e52570f2a232f193d",
|
"commit": "68e1f171aa8c6ce2e38cb9a7d1463d6bcf357e91",
|
||||||
"syncedAt": "2026-07-06T16:00:00Z"
|
"syncedAt": "2026-07-07T16:00:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "frontend-slides",
|
"id": "frontend-slides",
|
||||||
@@ -78,8 +87,8 @@
|
|||||||
"repo": "https://github.com/hugohe3/ppt-master.git",
|
"repo": "https://github.com/hugohe3/ppt-master.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"adapter": "claude-skill",
|
"adapter": "claude-skill",
|
||||||
"commit": "eb9243be673d0019dc1c7998262214a9a977a7d4",
|
"commit": "0b3f73e5f0868171eef82baef44be660888f6c71",
|
||||||
"syncedAt": "2026-07-05T16:00:01Z"
|
"syncedAt": "2026-07-07T16:00:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "next-skills",
|
"id": "next-skills",
|
||||||
@@ -87,17 +96,8 @@
|
|||||||
"repo": "https://github.com/vercel/next.js.git",
|
"repo": "https://github.com/vercel/next.js.git",
|
||||||
"ref": "canary",
|
"ref": "canary",
|
||||||
"adapter": "skill-collection",
|
"adapter": "skill-collection",
|
||||||
"commit": "6065bf6fcfc48484634dc3708c080a27c5684e5d",
|
"commit": "8b5df172e4908b68f7ef88e8ad2b98070baf9ced",
|
||||||
"syncedAt": "2026-07-06T16:00:00Z"
|
"syncedAt": "2026-07-07T16:00:00Z"
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "taste-skill",
|
|
||||||
"pluginName": "taste-skill",
|
|
||||||
"repo": "https://github.com/Leonxlnx/taste-skill.git",
|
|
||||||
"ref": "main",
|
|
||||||
"adapter": "skill-collection",
|
|
||||||
"commit": "b17742737e796305d829b3ad39eda3add0d79060",
|
|
||||||
"syncedAt": "2026-07-07T02:43:19Z"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,22 +281,22 @@
|
|||||||
"category": "文档处理"
|
"category": "文档处理"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ppt-master",
|
"name": "ui-ux-pro-max",
|
||||||
"source": {
|
"source": {
|
||||||
"source": "local",
|
"source": "local",
|
||||||
"path": "./plugins/ppt-master"
|
"path": "./plugins/ui-ux-pro-max"
|
||||||
},
|
},
|
||||||
"policy": {
|
"policy": {
|
||||||
"installation": "AVAILABLE",
|
"installation": "AVAILABLE",
|
||||||
"authentication": "ON_INSTALL"
|
"authentication": "ON_INSTALL"
|
||||||
},
|
},
|
||||||
"category": "文档处理"
|
"category": "设计"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ui-ux-pro-max",
|
"name": "taste-skill",
|
||||||
"source": {
|
"source": {
|
||||||
"source": "local",
|
"source": "local",
|
||||||
"path": "./plugins/ui-ux-pro-max"
|
"path": "./plugins/taste-skill"
|
||||||
},
|
},
|
||||||
"policy": {
|
"policy": {
|
||||||
"installation": "AVAILABLE",
|
"installation": "AVAILABLE",
|
||||||
@@ -316,6 +316,18 @@
|
|||||||
},
|
},
|
||||||
"category": "开发工具"
|
"category": "开发工具"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "ppt-master",
|
||||||
|
"source": {
|
||||||
|
"source": "local",
|
||||||
|
"path": "./plugins/ppt-master"
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
"installation": "AVAILABLE",
|
||||||
|
"authentication": "ON_INSTALL"
|
||||||
|
},
|
||||||
|
"category": "文档处理"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "next-skills",
|
"name": "next-skills",
|
||||||
"source": {
|
"source": {
|
||||||
@@ -339,18 +351,6 @@
|
|||||||
"authentication": "ON_INSTALL"
|
"authentication": "ON_INSTALL"
|
||||||
},
|
},
|
||||||
"category": "MCP"
|
"category": "MCP"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "taste-skill",
|
|
||||||
"source": {
|
|
||||||
"source": "local",
|
|
||||||
"path": "./plugins/taste-skill"
|
|
||||||
},
|
|
||||||
"policy": {
|
|
||||||
"installation": "AVAILABLE",
|
|
||||||
"authentication": "ON_INSTALL"
|
|
||||||
},
|
|
||||||
"category": "设计"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,5 +3,5 @@
|
|||||||
"name": "playwright浏览器自动化操作",
|
"name": "playwright浏览器自动化操作",
|
||||||
"version": "20260605",
|
"version": "20260605",
|
||||||
"keySource": "none",
|
"keySource": "none",
|
||||||
"syncedAt": "2026-07-06T16:01:31Z"
|
"syncedAt": "2026-07-07T16:01:24Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"sourceId": "next-skills",
|
"sourceId": "next-skills",
|
||||||
"repo": "https://github.com/vercel/next.js.git",
|
"repo": "https://github.com/vercel/next.js.git",
|
||||||
"ref": "canary",
|
"ref": "canary",
|
||||||
"commit": "6065bf6fcfc48484634dc3708c080a27c5684e5d",
|
"commit": "8b5df172e4908b68f7ef88e8ad2b98070baf9ced",
|
||||||
"adapter": "skill-collection",
|
"adapter": "skill-collection",
|
||||||
"sourcePath": "skills",
|
"sourcePath": "skills",
|
||||||
"syncedAt": "2026-07-06T16:00:00Z"
|
"syncedAt": "2026-07-07T16:00:00Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,47 @@ Knowing how to use Python and AI agents will matter more and more, and this proj
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## You Might Also Like
|
||||||
|
|
||||||
|
### <a href="https://github.com/microsoft/ResearchStudio">ResearchStudio-<img src="https://raw.githubusercontent.com/ai-nuts/Storage/main/ResearchStudio/ResearchStudio-Reel/docs/figures/reel-wordmark.png" alt="Reel" height="16"></a>
|
||||||
|
|
||||||
|
> A Microsoft open-source project I recently joined — from **paper** to **talk video**, **poster**, and **blog**, automating the **last mile** of research dissemination.
|
||||||
|
>
|
||||||
|
> 📦 **Repo:** [microsoft/ResearchStudio](https://github.com/microsoft/ResearchStudio) · 📄 **Paper:** [arXiv:2607.04438](https://arxiv.org/abs/2607.04438)
|
||||||
|
|
||||||
|
<table align="center">
|
||||||
|
<tr>
|
||||||
|
<td align="center" valign="middle" width="53%">
|
||||||
|
<a href="https://aka.ms/ResearchStudio">
|
||||||
|
<img src="https://raw.githubusercontent.com/ai-nuts/Storage/main/ResearchStudio/ResearchStudio-Reel/docs/figures/reel_demo.gif" width="100%"
|
||||||
|
alt="ResearchStudio-Reel demo" />
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center" valign="middle" width="47%">
|
||||||
|
<a href="https://aka.ms/ResearchStudio">
|
||||||
|
<img src="https://raw.githubusercontent.com/ai-nuts/Storage/main/ResearchStudio/ResearchStudio-Reel/docs/examples/latent_diffusion_landscape/poster.png" width="100%" alt="ResearchStudio-Reel generated poster" />
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><strong>BibTeX</strong> — if you use ResearchStudio-Reel in your research</summary>
|
||||||
|
|
||||||
|
```bibtex
|
||||||
|
@article{xiao2026researchstudioreel,
|
||||||
|
title = {ResearchStudio-Reel: Automate the Last Mile of Research from Paper to Poster, Video, and Blog},
|
||||||
|
author = {Lingao Xiao and Yalun Dai and Yangyu Huang and Qihao Zhao and Wenshan Wu and Hugo He and Ruishuo Chen and Jin Jiang and Qianli Ma and Jiahuan Zhang and Xin Zhang and Ying Xin and Yang Ou and Yan Xia and Scarlett Li and Longbo Huang and Zhipeng Zhang and Yang He and Yap Kim Hui and Yan Lu},
|
||||||
|
journal = {arXiv preprint arXiv:2607.04438},
|
||||||
|
year = {2026},
|
||||||
|
url = {https://arxiv.org/abs/2607.04438}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
### 1. Prerequisites
|
### 1. Prerequisites
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"sourceId": "ppt-master",
|
"sourceId": "ppt-master",
|
||||||
"repo": "https://github.com/hugohe3/ppt-master.git",
|
"repo": "https://github.com/hugohe3/ppt-master.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"commit": "eb9243be673d0019dc1c7998262214a9a977a7d4",
|
"commit": "0b3f73e5f0868171eef82baef44be660888f6c71",
|
||||||
"adapter": "claude-skill",
|
"adapter": "claude-skill",
|
||||||
"sourcePath": "skills/ppt-master",
|
"sourcePath": "skills/ppt-master",
|
||||||
"syncedAt": "2026-07-05T16:00:01Z"
|
"syncedAt": "2026-07-07T16:00:00Z"
|
||||||
}
|
}
|
||||||
|
|||||||
+133
-3
@@ -13,10 +13,12 @@ from resource_paths import icon_search_dirs_for_svg
|
|||||||
from .context import ConvertContext, ShapeResult
|
from .context import ConvertContext, ShapeResult
|
||||||
from .utils import (
|
from .utils import (
|
||||||
SVG_NS, EMU_PER_PX,
|
SVG_NS, EMU_PER_PX,
|
||||||
_extract_inheritable_styles, parse_transform_matrix, resolve_url_id,
|
_extract_inheritable_styles, _f, _get_attr, parse_transform_matrix, resolve_url_id,
|
||||||
parse_svg_length,
|
parse_svg_length,
|
||||||
)
|
)
|
||||||
from .styles import build_effect_xml
|
from .styles import (
|
||||||
|
build_effect_xml, build_fill_xml, get_fill_opacity, get_stroke_opacity,
|
||||||
|
)
|
||||||
from .elements import (
|
from .elements import (
|
||||||
convert_rect, convert_circle, convert_ellipse,
|
convert_rect, convert_circle, convert_ellipse,
|
||||||
convert_line, convert_path,
|
convert_line, convert_path,
|
||||||
@@ -361,6 +363,118 @@ _CONVERTERS = {
|
|||||||
_SUPPORTED_VISUAL_CHILD_TAGS = frozenset(('tspan',))
|
_SUPPORTED_VISUAL_CHILD_TAGS = frozenset(('tspan',))
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_svg_canvas(root: ET.Element) -> tuple[float, float, float, float]:
|
||||||
|
"""Return the SVG canvas as (x, y, width, height) in SVG units."""
|
||||||
|
view_box = root.get('viewBox', '')
|
||||||
|
parts = re.split(r'[\s,]+', view_box.strip()) if view_box else []
|
||||||
|
if len(parts) == 4:
|
||||||
|
try:
|
||||||
|
x, y, w, h = (float(part) for part in parts)
|
||||||
|
if w > 0 and h > 0:
|
||||||
|
return x, y, w, h
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
return 0.0, 0.0, _f(root.get('width')), _f(root.get('height'))
|
||||||
|
|
||||||
|
|
||||||
|
def _is_full_canvas_rect(
|
||||||
|
elem: ET.Element,
|
||||||
|
ctx: ConvertContext,
|
||||||
|
canvas: tuple[float, float, float, float],
|
||||||
|
) -> bool:
|
||||||
|
"""Return whether a rect is a safe candidate for native slide background."""
|
||||||
|
if elem.get('transform') or elem.get('filter') or elem.get('clip-path'):
|
||||||
|
return False
|
||||||
|
if _f(elem.get('rx')) > 0 or _f(elem.get('ry')) > 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
canvas_x, canvas_y, canvas_w, canvas_h = canvas
|
||||||
|
if canvas_w <= 0 or canvas_h <= 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
tolerance = 0.5
|
||||||
|
if abs(_f(elem.get('x')) - canvas_x) > tolerance:
|
||||||
|
return False
|
||||||
|
if abs(_f(elem.get('y')) - canvas_y) > tolerance:
|
||||||
|
return False
|
||||||
|
if abs(_f(elem.get('width')) - canvas_w) > tolerance:
|
||||||
|
return False
|
||||||
|
if abs(_f(elem.get('height')) - canvas_h) > tolerance:
|
||||||
|
return False
|
||||||
|
|
||||||
|
fill = _get_attr(elem, 'fill', ctx)
|
||||||
|
if fill == 'none':
|
||||||
|
return False
|
||||||
|
|
||||||
|
stroke = _get_attr(elem, 'stroke', ctx)
|
||||||
|
stroke_width = _f(_get_attr(elem, 'stroke-width', ctx), 1.0)
|
||||||
|
stroke_opacity = get_stroke_opacity(elem, ctx)
|
||||||
|
if stroke and stroke != 'none' and stroke_width > 0 and stroke_opacity != 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _background_xml_from_rect(
|
||||||
|
elem: ET.Element,
|
||||||
|
ctx: ConvertContext,
|
||||||
|
) -> str:
|
||||||
|
"""Build native ``p:bg`` XML from a full-slide SVG background rect."""
|
||||||
|
fill_xml = build_fill_xml(elem, ctx, get_fill_opacity(elem, ctx))
|
||||||
|
if not fill_xml or '<a:noFill' in fill_xml:
|
||||||
|
return ''
|
||||||
|
return f'<p:bg><p:bgPr>{fill_xml}<a:effectLst/></p:bgPr></p:bg>'
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_background_candidate(
|
||||||
|
root: ET.Element,
|
||||||
|
ctx: ConvertContext,
|
||||||
|
) -> tuple[str, int | None]:
|
||||||
|
"""Promote a first-layer SVG background rect to native PowerPoint bgPr.
|
||||||
|
|
||||||
|
PowerPoint stores page background fills under ``p:cSld/p:bg/p:bgPr``.
|
||||||
|
Keeping the full-canvas SVG rect in ``p:spTree`` makes it an ordinary
|
||||||
|
selectable shape, so users hit it during bulk element selection. Only the
|
||||||
|
first visual layer is considered, matching pptx_to_svg's round-trip output
|
||||||
|
and avoiding accidental promotion of content panels.
|
||||||
|
"""
|
||||||
|
canvas = _parse_svg_canvas(root)
|
||||||
|
for child in root:
|
||||||
|
tag = child.tag.replace(f'{{{SVG_NS}}}', '')
|
||||||
|
if tag in _NON_VISUAL_TAGS:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if tag == 'rect' and _is_full_canvas_rect(child, ctx, canvas):
|
||||||
|
bg_xml = _background_xml_from_rect(child, ctx)
|
||||||
|
if bg_xml:
|
||||||
|
return bg_xml, id(child)
|
||||||
|
return '', None
|
||||||
|
|
||||||
|
if tag != 'g':
|
||||||
|
return '', None
|
||||||
|
if child.get('transform') or child.get('filter') or child.get('clip-path'):
|
||||||
|
return '', None
|
||||||
|
style_overrides = _extract_inheritable_styles(child)
|
||||||
|
child_ctx = ctx.child(style_overrides=style_overrides)
|
||||||
|
visual_children = [
|
||||||
|
grandchild for grandchild in child
|
||||||
|
if grandchild.tag.replace(f'{{{SVG_NS}}}', '') not in _NON_VISUAL_TAGS
|
||||||
|
]
|
||||||
|
if len(visual_children) != 1:
|
||||||
|
return '', None
|
||||||
|
only_child = visual_children[0]
|
||||||
|
only_tag = only_child.tag.replace(f'{{{SVG_NS}}}', '')
|
||||||
|
if only_tag == 'rect' and _is_full_canvas_rect(only_child, child_ctx, canvas):
|
||||||
|
bg_xml = _background_xml_from_rect(only_child, child_ctx)
|
||||||
|
if bg_xml:
|
||||||
|
ctx.sync_from_child(child_ctx)
|
||||||
|
return bg_xml, id(child)
|
||||||
|
return '', None
|
||||||
|
return '', None
|
||||||
|
|
||||||
|
return '', None
|
||||||
|
|
||||||
|
|
||||||
def collect_defs(root: ET.Element) -> dict[str, ET.Element]:
|
def collect_defs(root: ET.Element) -> dict[str, ET.Element]:
|
||||||
"""Collect all <defs> children into an {id: element} dictionary."""
|
"""Collect all <defs> children into an {id: element} dictionary."""
|
||||||
defs: dict[str, ET.Element] = {}
|
defs: dict[str, ET.Element] = {}
|
||||||
@@ -568,6 +682,14 @@ def convert_svg_to_slide_shapes(
|
|||||||
shapes: list[str] = []
|
shapes: list[str] = []
|
||||||
converted = 0
|
converted = 0
|
||||||
skipped = 0
|
skipped = 0
|
||||||
|
background_xml, background_skip_id = _extract_background_candidate(root, ctx)
|
||||||
|
promoted_backgrounds = 1 if background_xml else 0
|
||||||
|
if background_xml and trace_events is not None:
|
||||||
|
trace_events.append({
|
||||||
|
'tag': 'rect',
|
||||||
|
'decision': 'native-background',
|
||||||
|
'reason': 'promoted-full-canvas-rect-to-bgPr',
|
||||||
|
})
|
||||||
# Per-element shape ids of every top-level child, used as an animation
|
# Per-element shape ids of every top-level child, used as an animation
|
||||||
# fallback when no <g id="..."> groups are present at the root.
|
# fallback when no <g id="..."> groups are present at the root.
|
||||||
fallback_targets: list = []
|
fallback_targets: list = []
|
||||||
@@ -576,6 +698,8 @@ def convert_svg_to_slide_shapes(
|
|||||||
tag = child.tag.replace(f'{{{SVG_NS}}}', '')
|
tag = child.tag.replace(f'{{{SVG_NS}}}', '')
|
||||||
if tag == 'defs':
|
if tag == 'defs':
|
||||||
continue
|
continue
|
||||||
|
if id(child) == background_skip_id:
|
||||||
|
continue
|
||||||
result = convert_element(child, ctx)
|
result = convert_element(child, ctx)
|
||||||
if result:
|
if result:
|
||||||
shapes.append(result.xml)
|
shapes.append(result.xml)
|
||||||
@@ -598,7 +722,11 @@ def convert_svg_to_slide_shapes(
|
|||||||
ctx.anim_targets = fallback_targets
|
ctx.anim_targets = fallback_targets
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print(f' Converted {converted} elements, skipped {skipped}')
|
promoted = (
|
||||||
|
f', promoted {promoted_backgrounds} background'
|
||||||
|
if promoted_backgrounds else ''
|
||||||
|
)
|
||||||
|
print(f' Converted {converted} elements, skipped {skipped}{promoted}')
|
||||||
|
|
||||||
if trace_out is not None:
|
if trace_out is not None:
|
||||||
trace_out.append({
|
trace_out.append({
|
||||||
@@ -607,6 +735,7 @@ def convert_svg_to_slide_shapes(
|
|||||||
'summary': {
|
'summary': {
|
||||||
'converted': converted,
|
'converted': converted,
|
||||||
'skipped': skipped,
|
'skipped': skipped,
|
||||||
|
'promoted_backgrounds': promoted_backgrounds,
|
||||||
'media_files': len(ctx.media_files),
|
'media_files': len(ctx.media_files),
|
||||||
'package_files': len(ctx.package_files),
|
'package_files': len(ctx.package_files),
|
||||||
'relationships': len(ctx.rel_entries),
|
'relationships': len(ctx.rel_entries),
|
||||||
@@ -623,6 +752,7 @@ def convert_svg_to_slide_shapes(
|
|||||||
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||||
xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
|
xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
|
||||||
<p:cSld>
|
<p:cSld>
|
||||||
|
{background_xml}
|
||||||
<p:spTree>
|
<p:spTree>
|
||||||
<p:nvGrpSpPr>
|
<p:nvGrpSpPr>
|
||||||
<p:cNvPr id="1" name=""/>
|
<p:cNvPr id="1" name=""/>
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"sourceId": "shadcn",
|
"sourceId": "shadcn",
|
||||||
"repo": "https://github.com/shadcn-ui/ui.git",
|
"repo": "https://github.com/shadcn-ui/ui.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"commit": "d8ace420baa5c8a1abccd75e52570f2a232f193d",
|
"commit": "68e1f171aa8c6ce2e38cb9a7d1463d6bcf357e91",
|
||||||
"adapter": "claude-skill",
|
"adapter": "claude-skill",
|
||||||
"sourcePath": "skills/shadcn",
|
"sourcePath": "skills/shadcn",
|
||||||
"syncedAt": "2026-07-06T16:00:00Z"
|
"syncedAt": "2026-07-07T16:00:00Z"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user