skills/ppt-station-skill/ppt_station/composer/layouts/image_text.py
wangyitong a65adcc2e5 Initial commit: merged, deduplicated, and vetted skill collection
Sources: extracted from two upstream archives (skill-repo, skills-main),
merged with the following policy:

- 15 broken symlinks (pointing to /Users/jameslee/.cc-switch/skills or
  ../../.agents/skills on a foreign machine) discarded
- 3 real name collisions with identical content (ai-pair, ifind-http-api,
  zhipu-websearch) kept as one copy
- Functional overlaps deduped keeping the strongest variant:
  - docx family: kept docx (official, full toolchain) + docx-cn
    (GB/T 9704 Chinese official-document constants),
    dropped docx_writer (no scripts, name collided with docx)
  - humanizer family: kept humanizer-zh (6 zh reference docs),
    dropped humanizer (en, redundant for CN workflow)
- Skills that only ran in a foreign environment removed:
  ablemind-ops, app-publish, hlb-design-system, openclaw-adj-skill,
  claude-driver
- alphapai excluded from this public repo because its SKILL.md hard-coded
  live credentials

Result: 25 skills, 572 files, ~7.5 MB.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 14:47:12 +08:00

124 lines
4.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""图片+文字布局 — 左右分栏,图片侧支持本地路径/URL/base64"""
from ..helpers import (set_slide_bg, add_text, add_rect, add_picture,
add_page_header)
def layout_image_text(slide, data, theme):
"""图片+文字(左右可切换)
data keys:
title (str): 页面标题
image_side (str): "left""right",默认 "left"
image_path (str|None): 图片来源(本地路径/URL/base64None 则用色块
image_sizing (str): "cover"/"contain"/"stretch",默认 "cover"
image_fill_color (str): image_path=None 时色块颜色变量名,默认 "bg_dark"
image_number (str|None): 大数字(如 "380亿"),可选
image_number_label (str|None): 数字标签(如 "资产规模"),可选
tag (str|None): 小标签文字(如 "团队介绍"),可选
text_title (str): 副标题
text_body (str): 正文段落
bullets (list[str]|None): 要点列表,可选
footnote (str|None): 底部小注,可选
split_ratio (float): 图片区占内容宽比例,默认 0.50
"""
m = theme["margin"]
sw = theme.get("slide_w", 13.333)
sh = theme.get("slide_h", 7.5)
cw = sw - 2 * m
# 背景 + 页面标题
set_slide_bg(slide, theme["bg_light"])
add_page_header(slide, data["title"], theme)
# 装饰线
add_rect(slide, m, 0.90, 2.0, 0.04, fill=theme["accent"])
# 左右分栏计算
ratio = data.get("split_ratio", 0.50)
inner_gap = 0.40
img_w = cw * ratio - inner_gap
txt_w = cw * (1 - ratio) - inner_gap
area_y = 1.10
area_h = sh - area_y - 0.40
img_side = data.get("image_side", "left")
if img_side == "left":
img_x = m
txt_x = m + img_w + inner_gap * 2
else:
txt_x = m
img_x = m + txt_w + inner_gap * 2
# ── 图片区 ──
if data.get("image_path"):
sizing = data.get("image_sizing", "cover")
add_picture(slide, data["image_path"],
img_x, area_y, img_w, area_h,
sizing=sizing)
else:
img_color = theme.get(
data.get("image_fill_color", "bg_dark"), theme["bg_dark"])
add_rect(slide, img_x, area_y, img_w, area_h, fill=img_color)
if data.get("image_number"):
add_text(slide, data["image_number"],
x=img_x, y=area_y + 1.50, w=img_w, h=1.50,
font_size=72, color=theme["accent"],
bold=True, align="center",
font_name=theme["header_font"])
if data.get("image_number_label"):
add_text(slide, data["image_number_label"],
x=img_x, y=area_y + 3.10, w=img_w, h=0.50,
font_size=theme["body_size"] + 2,
color=theme.get("text_light", "FFFFFF"),
align="center", font_name=theme["body_font"])
# ── 文字区 ──
ty = area_y
if data.get("tag"):
add_text(slide, data["tag"],
x=txt_x, y=ty, w=txt_w, h=0.35,
font_size=theme.get("caption_size", 10),
color=theme["accent"],
font_name=theme["body_font"])
ty += 0.40
if data.get("text_title"):
add_text(slide, data["text_title"],
x=txt_x, y=ty, w=txt_w, h=0.65,
font_size=theme["subtitle_size"],
color=theme["text_dark"],
bold=True, font_name=theme["header_font"])
ty += 0.70
add_rect(slide, txt_x, ty, 1.50, 0.04, fill=theme["accent"])
ty += 0.15
if data.get("text_body"):
add_text(slide, data["text_body"],
x=txt_x, y=ty, w=txt_w, h=2.20,
font_size=theme["body_size"],
color=theme["text_dark"],
font_name=theme["body_font"])
ty += 2.30
if data.get("bullets"):
for bullet in data["bullets"]:
add_rect(slide, txt_x, ty + 0.12, 0.08, 0.08,
fill=theme["accent"])
add_text(slide, bullet,
x=txt_x + 0.20, y=ty, w=txt_w - 0.20, h=0.45,
font_size=theme["body_size"],
color=theme["text_dark"],
font_name=theme["body_font"])
ty += 0.50
if data.get("footnote"):
add_text(slide, data["footnote"],
x=txt_x, y=area_y + area_h - 0.40, w=txt_w, h=0.40,
font_size=theme.get("caption_size", 10),
color=theme["text_muted"],
font_name=theme["body_font"])