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>
150 lines
3.6 KiB
Python
150 lines
3.6 KiB
Python
"""
|
||
Chart Builder - 可扩展的图表构建系统
|
||
|
||
这是一个分层的图表构建包,用于解决 P(n,2) 组合爆炸问题。
|
||
|
||
架构:
|
||
- oxml/: 底层 XML 操作(纯 lxml)
|
||
- builder.py: 中层构建器(有状态的编排器)
|
||
- parser.py: 反向解析器(从 PPTX 提取配置)
|
||
- styles.py: 样式配置(颜色、线型、标记点)
|
||
- api.py: 高层公共接口(简洁的 API)
|
||
|
||
正向工程(构建图表):
|
||
from ppt_station.chart_builder import create_combo_chart
|
||
|
||
chart = create_combo_chart(
|
||
slide=slide,
|
||
df=df,
|
||
categories_col="日期",
|
||
series_config=[
|
||
{"key": "销售额", "name": "销售额", "type": "bar", "axis": "primary"},
|
||
{"key": "增长率", "name": "增长率", "type": "line", "axis": "secondary"},
|
||
]
|
||
)
|
||
|
||
反向工程(解析图表):
|
||
from ppt_station.chart_builder import parse_chart_from_pptx
|
||
|
||
series_config, df, categories_col = parse_chart_from_pptx("template.pptx")
|
||
# 现在可以用这些配置来复现图表
|
||
|
||
样式配置:
|
||
from ppt_station.chart_builder import StyleConfig, create_combo_chart
|
||
|
||
# 自定义样式:无标记点、1.5pt 线宽、深色系
|
||
custom_style = StyleConfig(
|
||
color_scheme="dark_only",
|
||
line_width_pt=1.5,
|
||
marker_style="none",
|
||
)
|
||
|
||
chart = create_combo_chart(
|
||
slide=slide,
|
||
df=df,
|
||
categories_col="日期",
|
||
series_config=[...],
|
||
style_config=custom_style
|
||
)
|
||
"""
|
||
|
||
from .api import create_combo_chart
|
||
from .cleaner import ChartJunkCleaner, clean_chart
|
||
from .parser import (
|
||
ChartParser,
|
||
parse_chart_from_pptx,
|
||
parse_all_charts_from_pptx
|
||
)
|
||
|
||
# 导出样式配置(如果可用)
|
||
try:
|
||
from .styles import (
|
||
StyleConfig,
|
||
DEFAULT_STYLE_CONFIG,
|
||
COLOR_SCHEMES,
|
||
# 颜色常量
|
||
DARK_RED,
|
||
DARK_GRAY,
|
||
DARK_BLUE,
|
||
DARK_ORANGE,
|
||
LIGHT_RED,
|
||
LIGHT_GRAY,
|
||
LIGHT_BLUE,
|
||
LIGHT_ORANGE,
|
||
)
|
||
_HAS_STYLES = True
|
||
except ImportError:
|
||
_HAS_STYLES = False
|
||
|
||
# 导出布局配置(如果可用)
|
||
try:
|
||
from .layout import (
|
||
ChartLayoutConfig,
|
||
LegendConfig,
|
||
CategoryAxisConfig,
|
||
ValueAxisConfig,
|
||
DEFAULT_LEGEND_CONFIG,
|
||
DEFAULT_CATEGORY_AXIS_CONFIG,
|
||
DEFAULT_VALUE_AXIS_CONFIG,
|
||
)
|
||
_HAS_LAYOUT = True
|
||
except ImportError:
|
||
_HAS_LAYOUT = False
|
||
|
||
# 导出日期轴配置(如果可用)
|
||
try:
|
||
from .date_axis import (
|
||
DateAxisConfig,
|
||
DAILY_TICKS,
|
||
WEEKLY_TICKS,
|
||
BIWEEKLY_TICKS,
|
||
MONTHLY_TICKS,
|
||
QUARTERLY_TICKS,
|
||
YEARLY_TICKS,
|
||
)
|
||
_HAS_DATE_AXIS = True
|
||
except ImportError:
|
||
_HAS_DATE_AXIS = False
|
||
|
||
# 构建 __all__
|
||
__all__ = [
|
||
'create_combo_chart',
|
||
'ChartParser',
|
||
'parse_chart_from_pptx',
|
||
'parse_all_charts_from_pptx',
|
||
'ChartJunkCleaner',
|
||
'clean_chart',
|
||
]
|
||
|
||
if _HAS_STYLES:
|
||
__all__.extend([
|
||
'StyleConfig',
|
||
'DEFAULT_STYLE_CONFIG',
|
||
'COLOR_SCHEMES',
|
||
'DARK_RED', 'DARK_GRAY', 'DARK_BLUE', 'DARK_ORANGE',
|
||
'LIGHT_RED', 'LIGHT_GRAY', 'LIGHT_BLUE', 'LIGHT_ORANGE',
|
||
])
|
||
|
||
if _HAS_LAYOUT:
|
||
__all__.extend([
|
||
'ChartLayoutConfig',
|
||
'LegendConfig',
|
||
'CategoryAxisConfig',
|
||
'ValueAxisConfig',
|
||
'DEFAULT_LEGEND_CONFIG',
|
||
'DEFAULT_CATEGORY_AXIS_CONFIG',
|
||
'DEFAULT_VALUE_AXIS_CONFIG',
|
||
])
|
||
|
||
if _HAS_DATE_AXIS:
|
||
__all__.extend([
|
||
'DateAxisConfig',
|
||
'DAILY_TICKS',
|
||
'WEEKLY_TICKS',
|
||
'BIWEEKLY_TICKS',
|
||
'MONTHLY_TICKS',
|
||
'QUARTERLY_TICKS',
|
||
'YEARLY_TICKS',
|
||
])
|
||
|