@ww_nero/skills 2.2.0 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -317,6 +317,15 @@ def add_gradient_rectangle(slide, x, y, width, height, color1, alpha1, color2, a
317
317
  shape.line.fill.background()
318
318
  return shape
319
319
 
320
+ def remove_autoshape_shadow(shape):
321
+ """移除自动形状阴影效果"""
322
+ spPr = shape._sp.spPr
323
+ effectLst = spPr.find(qn('a:effectLst'))
324
+ if effectLst is not None:
325
+ spPr.remove(effectLst)
326
+ effectLst = OxmlElement('a:effectLst')
327
+ spPr.append(effectLst)
328
+
320
329
  def add_circle(slide, cx, cy, r, fill_color=None, stroke_color=None, stroke_width=1, opacity=1.0, stroke_opacity=None):
321
330
  """添加圆形"""
322
331
  shape = slide.shapes.add_shape(MSO_SHAPE.OVAL, px(cx-r), px(cy-r), px(r*2), px(r*2))
@@ -331,13 +340,16 @@ def add_circle(slide, cx, cy, r, fill_color=None, stroke_color=None, stroke_widt
331
340
 
332
341
  if stroke_color:
333
342
  shape.line.color.rgb = hex_to_rgb(stroke_color)
334
- shape.line.width = Pt(stroke_width)
335
- # 设置边框透明度
343
+ shape.line.width = int(stroke_width * 9525)
336
344
  if stroke_opacity is not None and stroke_opacity < 1.0:
337
345
  set_line_stroke_transparency(shape, stroke_opacity)
338
346
  else:
339
347
  shape.line.fill.background()
340
348
 
349
+ # 如果只有stroke没有fill,移除阴影
350
+ if not fill_color and stroke_color:
351
+ remove_autoshape_shadow(shape)
352
+
341
353
  return shape
342
354
 
343
355
  def add_ellipse(slide, cx, cy, rx, ry, fill_color=None, stroke_color=None, stroke_width=1, opacity=1.0, rotation=0, stroke_opacity=None):
@@ -366,15 +378,27 @@ def add_ellipse(slide, cx, cy, rx, ry, fill_color=None, stroke_color=None, strok
366
378
 
367
379
  return shape
368
380
 
381
+ def remove_shape_shadow(shape):
382
+ """移除形状阴影效果"""
383
+ spPr = shape._element.find(qn('p:spPr'))
384
+ if spPr is None:
385
+ return
386
+ effectLst = spPr.find(qn('a:effectLst'))
387
+ if effectLst is not None:
388
+ spPr.remove(effectLst)
389
+ effectLst = OxmlElement('a:effectLst')
390
+ spPr.append(effectLst)
391
+
369
392
  def add_line(slide, x1, y1, x2, y2, color, width=1, opacity=1.0, dash=False):
370
393
  """添加线条"""
371
394
  connector = slide.shapes.add_connector(MSO_CONNECTOR.STRAIGHT, px(x1), px(y1), px(x2), px(y2))
372
395
  connector.line.color.rgb = hex_to_rgb(color)
373
- connector.line.width = Pt(width)
396
+ connector.line.width = int(width * 9525)
374
397
  if dash:
375
398
  connector.line.dash_style = 2
376
399
  if opacity < 1.0:
377
400
  set_line_transparency(connector, opacity)
401
+ remove_shape_shadow(connector)
378
402
  return connector
379
403
 
380
404
  def add_triangle(slide, cx, cy, size, fill_color, opacity=1.0, rotation=0, stroke_color=None, stroke_width=0, stroke_opacity=None):
@@ -418,6 +442,15 @@ def add_spline(slide, points, color, width=2, opacity=1.0, smooth=True):
418
442
  set_line_transparency(shape, opacity)
419
443
  return shape
420
444
 
445
+ def remove_freeform_shadow(shape):
446
+ """移除自由形状阴影效果"""
447
+ spPr = shape._sp.spPr
448
+ effectLst = spPr.find(qn('a:effectLst'))
449
+ if effectLst is not None:
450
+ spPr.remove(effectLst)
451
+ effectLst = OxmlElement('a:effectLst')
452
+ spPr.append(effectLst)
453
+
421
454
  def add_freeform_path(slide, points, fill_color=None, stroke_color=None, stroke_width=1, opacity=1.0, closed=False, stroke_opacity=None):
422
455
  """添加自由形状路径"""
423
456
  if len(points) < 2:
@@ -439,14 +472,17 @@ def add_freeform_path(slide, points, fill_color=None, stroke_color=None, stroke_
439
472
 
440
473
  if stroke_color:
441
474
  shape.line.color.rgb = hex_to_rgb(stroke_color)
442
- shape.line.width = Pt(stroke_width)
443
- # 设置边框透明度
475
+ shape.line.width = int(stroke_width * 9525)
444
476
  actual_stroke_opacity = stroke_opacity if stroke_opacity is not None else opacity
445
477
  if actual_stroke_opacity < 1.0:
446
478
  set_line_transparency(shape, actual_stroke_opacity)
447
479
  else:
448
480
  shape.line.fill.background()
449
481
 
482
+ # 对于非封闭路径(线条类型),移除阴影
483
+ if not closed:
484
+ remove_freeform_shadow(shape)
485
+
450
486
  return shape
451
487
 
452
488
  def add_polyline(slide, points, color, width=1, opacity=1.0, dash=False):
package/index.js CHANGED
@@ -68,7 +68,9 @@ const SNIPPETS = {
68
68
  '【中文字体回退】仅设置 run.font.name 对中文无效,需额外通过 XML 插入 a:ea 元素并指定 typeface="Microsoft YaHei",且 a:ea 要插入到 rPr 开头防止被后续元素覆盖。',
69
69
  '【形状渐变填充】设置形状渐变时,必须先移除 spPr 下已有的 a:solidFill/a:gradFill/a:noFill,否则渐变不生效。渐变位置 pos 使用 0-100000 范围(百分比*1000),角度 ang 使用度数*60000。',
70
70
  '【渐变透明度】每个渐变停止点的透明度需在对应 srgbClr 下追加 a:alpha 元素,val 值为透明度*100000(如 0.5 透明度对应 50000)。',
71
- '【曲线绘制】使用 build_freeform 绘制曲线时,起点坐标在构造器中指定,后续点通过 add_line_segments 添加。若需平滑曲线,可用 Catmull-Rom 样条插值生成中间点。'
71
+ '【曲线绘制】使用 build_freeform 绘制曲线时,起点坐标在构造器中指定,后续点通过 add_line_segments 添加。若需平滑曲线,可用 Catmull-Rom 样条插值生成中间点。',
72
+ '【线宽单位换算】线条宽度不能使用 Pt,应使用 EMU 单位:width * 9525(1px 约等于 9525 EMU)。',
73
+ '【移除阴影效果】对于线条、非封闭的 freeform path、以及只有 stroke 没有 fill 的 circle,需要移除默认阴影效果,方法是在 spPr 下添加空的 a:effectLst 元素。'
72
74
  ]
73
75
  }
74
76
  };
@@ -80,10 +82,11 @@ const GUIDES = {
80
82
 
81
83
  1. **规划PPT内容**,存储到markdown文件中:
82
84
  - 每页Slide的规划需要包含:内容、布局方式、插图(如果需要)
83
- - 如果用户未明确声明,则**默认比例为宽1280px、高720px,默认背景为深色、科技感、弱渐变、简约风格**
85
+ - 如果用户未明确声明,则**默认比例为宽1280px、高720px,默认背景为深邃蓝色、科技感、弱渐变、简约风格**
84
86
  - 不同页面应尽可能使用不同的布局方式,避免过于单调,可适当使用图表来呈现信息,例如折线图、柱状图、饼状图等,但背景颜色保持一致
85
87
  - 如果需要插入图片,则按照以下方式:
86
- - 收集全部图片素材,优先使用用户提供的;若未提供,则使用网络搜索合适的图片并保存到本地;如果仍未找到合适的,则调用图像生成工具生成图片
88
+ - 收集全部图片素材,优先使用用户提供的图片;若未提供,则使用网络搜索合适的图片或图标并保存到本地;仍无合适的,则使用图像生成工具生成图片
89
+ - 将图片素材保存到\`images\`文件夹中,并使用临时python脚本获取每个图片的宽高比例
87
90
  - 对图片素材进行重命名来编号,通过名称标识每个图片用于哪个slide及其宽高比例,例如\`slide01_1_1920X1080.png\`表示该图片用于第一张幻灯片,并且是该幻灯片中的第一张图,宽高为1920*1080
88
91
 
89
92
  2. **逐页生成SVG代码**:
@@ -193,7 +196,7 @@ const listTools = () => ({
193
196
  ]
194
197
  });
195
198
 
196
- const server = new Server({ name: 'skills', version: '2.2.0' }, { capabilities: { tools: {} } });
199
+ const server = new Server({ name: 'skills', version: '2.2.2' }, { capabilities: { tools: {} } });
197
200
 
198
201
  server.setRequestHandler(ListToolsRequestSchema, async () => listTools());
199
202
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ww_nero/skills",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
4
4
  "description": "MCP server that returns Python reference snippets and skill guides",
5
5
  "main": "index.js",
6
6
  "bin": {