TxT2Docx/style_manager.py

822 lines
31 KiB
Python
Raw 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.

"""
文章排版样式管理模块
负责管理文档的排版样式,包括内置样式和自定义样式。
支持样式的创建、编辑、删除、导入和导出等功能。
"""
import os
import json
from typing import Dict, Any, List, Optional, Union
from dataclasses import dataclass, asdict, field
from copy import deepcopy
@dataclass
class FontStyle:
"""字体样式配置"""
name: str = "宋体"
size: int = 12
bold: bool = False
italic: bool = False
color: str = "#000000" # RGB颜色值
@dataclass
class ParagraphStyle:
"""段落样式配置"""
line_spacing: float = 1.5
space_before: int = 0 # 段前间距(磅)
space_after: int = 0 # 段后间距(磅)
first_line_indent: float = 0.0 # 首行缩进(字符)
alignment: str = "left" # left, center, right, justify
keep_with_next: bool = False # 与下段同页
@dataclass
class HeadingStyle:
"""标题样式配置"""
font: FontStyle
paragraph: ParagraphStyle
numbering: bool = False # 是否自动编号
outline_level: int = 0 # 大纲级别
@dataclass
class ListStyle:
"""列表样式配置"""
font: FontStyle
paragraph: ParagraphStyle
bullet_symbol: str = "" # 无序列表符号
number_format: str = "1." # 有序列表格式
@dataclass
class SpecialStyle:
"""特殊元素样式配置"""
font: FontStyle
paragraph: ParagraphStyle
background_color: str = "#F5F5F5" # 背景色
border: bool = False # 是否有边框
@dataclass
class DocumentStyle:
"""文档排版样式配置"""
# 基础信息
name: str = "默认样式"
description: str = "标准文档样式"
author: str = "系统"
version: str = "1.0"
# 页面设置
page_margin_top: float = 2.54 # 页边距(cm)
page_margin_bottom: float = 2.54
page_margin_left: float = 3.17
page_margin_right: float = 3.17
# 基础字体和段落
body_font: Optional[FontStyle] = None
body_paragraph: Optional[ParagraphStyle] = None
# 标题样式 (1-6级)
heading_styles: Optional[Dict[int, HeadingStyle]] = None
# 列表样式
unordered_list: Optional[ListStyle] = None
ordered_list: Optional[ListStyle] = None
# 特殊元素样式
code_block: Optional[SpecialStyle] = None
quote_block: Optional[SpecialStyle] = None
table_style: Optional[SpecialStyle] = None
def __post_init__(self):
"""初始化默认值"""
if self.body_font is None:
self.body_font = FontStyle()
if self.body_paragraph is None:
self.body_paragraph = ParagraphStyle()
if self.heading_styles is None:
self.heading_styles = self._create_default_headings()
if self.unordered_list is None:
self.unordered_list = ListStyle(
font=FontStyle(),
paragraph=ParagraphStyle(space_after=6)
)
if self.ordered_list is None:
self.ordered_list = ListStyle(
font=FontStyle(),
paragraph=ParagraphStyle(space_after=6)
)
if self.code_block is None:
self.code_block = SpecialStyle(
font=FontStyle(name="Courier New", size=10),
paragraph=ParagraphStyle(space_before=6, space_after=6),
background_color="#F5F5F5"
)
if self.quote_block is None:
self.quote_block = SpecialStyle(
font=FontStyle(italic=True),
paragraph=ParagraphStyle(first_line_indent=2.0, space_before=6, space_after=6),
background_color="#F9F9F9"
)
if self.table_style is None:
self.table_style = SpecialStyle(
font=FontStyle(size=11),
paragraph=ParagraphStyle(space_before=6, space_after=6),
border=True
)
def _create_default_headings(self) -> Dict[int, HeadingStyle]:
"""创建默认标题样式"""
headings = {}
base_sizes = [18, 16, 14, 13, 12, 11] # 各级标题字号
for level in range(1, 7):
font_size = base_sizes[level - 1] if level <= len(base_sizes) else 11
headings[level] = HeadingStyle(
font=FontStyle(
name="微软雅黑",
size=font_size,
bold=True,
color="#1F497D"
),
paragraph=ParagraphStyle(
line_spacing=1.3,
space_before=12 if level <= 2 else 6,
space_after=6,
keep_with_next=True
),
outline_level=level
)
return headings
class StyleManager:
"""排版样式管理器"""
def __init__(self, styles_dir: str = "data/styles"):
"""
初始化样式管理器
Args:
styles_dir: 样式文件存储目录
"""
self.styles_dir = styles_dir
self.builtin_styles = self._create_builtin_styles()
self.custom_styles = {}
self._load_custom_styles()
def _create_builtin_styles(self) -> Dict[str, DocumentStyle]:
"""创建内置样式(专业版)"""
styles = {}
# 1. 爆款文章风格 - 参考知乎、头条等平台
styles["爆款文章风格"] = self._create_viral_style()
# 2. 微信公众号风格 - 专业的新媒体排版
styles["微信公众号风格"] = self._create_wechat_style()
# 3. 知乎高赞回答风格 - 逻辑清晰,层次分明
styles["知乎高赞回答风格"] = self._create_zhihu_style()
# 4. 小红书笔记风格 - 清新文艺,少女心
styles["小红书笔记风格"] = self._create_xiaohongshu_style()
# 5. 今日头条新闻风格 - 信息量大,节奏紧凑
styles["今日头条新闻风格"] = self._create_toutiao_style()
# 6. B站UP主视频脚本风格 - 轻松活泼,年轻化
styles["B站UP主视频脚本风格"] = self._create_bilibili_style()
# 7. 企业微信群通知风格 - 正式严肃
styles["企业微信群通知风格"] = self._create_enterprise_style()
# 8. 情感鸡汤文风格 - 温暖治愈
styles["情感鸡汤文风格"] = self._create_emotional_style()
return styles
def _create_viral_style(self) -> DocumentStyle:
"""创建爆款文章风格"""
viral_style = DocumentStyle(
name="爆款文章风格",
description="高阅读量爆款文章风格,层次分明,吸引眼球",
author="系统内置",
body_font=FontStyle(name="微软雅黑", size=14, color="#333333"),
body_paragraph=ParagraphStyle(
line_spacing=1.8,
first_line_indent=0.0, # 爆款文章不缩进
space_after=12,
space_before=0
)
)
# 设置爆款文章的标题样式
if viral_style.heading_styles:
# 主标题:大胆吸引眼球
viral_style.heading_styles[1].font = FontStyle(name="黑体", size=22, bold=True, color="#FF4500")
viral_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=20, space_after=20, alignment="center"
)
# 二级标题:强烈对比
viral_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=18, bold=True, color="#FF6B35")
viral_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.4, space_before=16, space_after=12, alignment="left"
)
# 三级标题:精彩分段
viral_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#4CAF50")
viral_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.4, space_before=12, space_after=8
)
# 四级及以下:细分点
for level in range(4, 7):
viral_style.heading_styles[level].font = FontStyle(name="微软雅黑", size=15, bold=True, color="#2196F3")
viral_style.heading_styles[level].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=8, space_after=6
)
# 设置特殊元素样式
viral_style.quote_block = SpecialStyle(
font=FontStyle(name="楷体", size=13, italic=True, color="#666666"),
paragraph=ParagraphStyle(
line_spacing=1.6, space_before=10, space_after=10,
first_line_indent=0, alignment="center"
),
background_color="#F8F9FA"
)
return viral_style
def _create_wechat_style(self) -> DocumentStyle:
"""创建微信公众号风格"""
wechat_style = DocumentStyle(
name="微信公众号风格",
description="专业的微信公众号排版,阅读体验佳",
author="系统内置",
body_font=FontStyle(name="微软雅黑", size=14, color="#3C4043"),
body_paragraph=ParagraphStyle(
line_spacing=1.75,
first_line_indent=0.0,
space_after=14,
space_before=0
)
)
if wechat_style.heading_styles:
# 公众号标题的精心设计
wechat_style.heading_styles[1].font = FontStyle(name="黑体", size=20, bold=True, color="#1AAD19")
wechat_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.2, space_before=18, space_after=16, alignment="center"
)
wechat_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=17, bold=True, color="#576B95")
wechat_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=14, space_after=10
)
wechat_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=15, bold=True, color="#FA5151")
wechat_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=10, space_after=8
)
# 微信公众号的引用样式
wechat_style.quote_block = SpecialStyle(
font=FontStyle(name="微软雅黑", size=13, italic=True, color="#888888"),
paragraph=ParagraphStyle(
line_spacing=1.5, space_before=12, space_after=12,
first_line_indent=1.0, alignment="left"
),
background_color="#F7F7F7",
border=True
)
return wechat_style
def _create_zhihu_style(self) -> DocumentStyle:
"""创建知乎高赞回答风格"""
zhihu_style = DocumentStyle(
name="知乎高赞回答风格",
description="逻辑清晰,层次分明,专业权威",
author="系统内置",
body_font=FontStyle(name="微软雅黑", size=15, color="#1A1A1A"),
body_paragraph=ParagraphStyle(
line_spacing=1.6,
first_line_indent=0.0,
space_after=10,
space_before=0
)
)
if zhihu_style.heading_styles:
# 知乎风格的标题设计
zhihu_style.heading_styles[1].font = FontStyle(name="黑体", size=20, bold=True, color="#0084FF")
zhihu_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=16, space_after=14
)
zhihu_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=17, bold=True, color="#00A6FB")
zhihu_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=12, space_after=10
)
zhihu_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#FF6B6B")
zhihu_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=10, space_after=8
)
return zhihu_style
def _create_xiaohongshu_style(self) -> DocumentStyle:
"""创建小红书笔记风格"""
xiaohongshu_style = DocumentStyle(
name="小红书笔记风格",
description="清新文艺,适合生活方式类内容",
author="系统内置",
body_font=FontStyle(name="华文细黑", size=14, color="#333333"),
body_paragraph=ParagraphStyle(
line_spacing=1.8,
first_line_indent=0.0,
space_after=12,
space_before=0
)
)
if xiaohongshu_style.heading_styles:
xiaohongshu_style.heading_styles[1].font = FontStyle(name="华文细黑", size=18, bold=True, color="#FF69B4")
xiaohongshu_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.2, space_before=15, space_after=12, alignment="center"
)
xiaohongshu_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#FF6EB4")
xiaohongshu_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=12, space_after=8
)
xiaohongshu_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=15, bold=True, color="#FFB6C1")
xiaohongshu_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=8, space_after=6
)
return xiaohongshu_style
def _create_toutiao_style(self) -> DocumentStyle:
"""创建今日头条新闻风格"""
toutiao_style = DocumentStyle(
name="今日头条新闻风格",
description="信息密度高,节奏紧凑,突出重点",
author="系统内置",
body_font=FontStyle(name="微软雅黑", size=14, color="#222222"),
body_paragraph=ParagraphStyle(
line_spacing=1.5,
first_line_indent=0.0,
space_after=8,
space_before=0
)
)
if toutiao_style.heading_styles:
toutiao_style.heading_styles[1].font = FontStyle(name="黑体", size=19, bold=True, color="#D43F3A")
toutiao_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.2, space_before=12, space_after=12
)
toutiao_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#D9534F")
toutiao_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=10, space_after=8
)
toutiao_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=15, bold=True, color="#F0AD4E")
toutiao_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=8, space_after=6
)
return toutiao_style
def _create_bilibili_style(self) -> DocumentStyle:
"""创建B站UP主视频脚本风格"""
bilibili_style = DocumentStyle(
name="B站UP主视频脚本风格",
description="轻松活泼,适合年轻受众,有趣有料",
author="系统内置",
body_font=FontStyle(name="微软雅黑", size=14, color="#222222"),
body_paragraph=ParagraphStyle(
line_spacing=1.6,
first_line_indent=0.0,
space_after=10,
space_before=0
)
)
if bilibili_style.heading_styles:
bilibili_style.heading_styles[1].font = FontStyle(name="黑体", size=18, bold=True, color="#00A1D6")
bilibili_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=14, space_after=12
)
bilibili_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#FB7299")
bilibili_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=10, space_after=8
)
bilibili_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=15, bold=True, color="#9C88FF")
bilibili_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=8, space_after=6
)
return bilibili_style
def _create_enterprise_style(self) -> DocumentStyle:
"""创建企业微信群通知风格"""
enterprise_style = DocumentStyle(
name="企业微信群通知风格",
description="正式严肃,信息传达清晰,商务风格",
author="系统内置",
body_font=FontStyle(name="宋体", size=14, color="#2C2C2C"),
body_paragraph=ParagraphStyle(
line_spacing=1.5,
first_line_indent=2.0,
space_after=10,
space_before=0
)
)
if enterprise_style.heading_styles:
enterprise_style.heading_styles[1].font = FontStyle(name="黑体", size=18, bold=True, color="#1F4E79")
enterprise_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.2, space_before=16, space_after=12, alignment="center"
)
enterprise_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#2F5597")
enterprise_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=12, space_after=8
)
return enterprise_style
def _create_emotional_style(self) -> DocumentStyle:
"""创建情感鸡汤文风格"""
emotional_style = DocumentStyle(
name="情感鸡汤文风格",
description="温暖治愈,情感丰富,適合心灵鸡汤类内容",
author="系统内置",
body_font=FontStyle(name="楷体", size=14, color="#444444"),
body_paragraph=ParagraphStyle(
line_spacing=1.8,
first_line_indent=1.5,
space_after=12,
space_before=0
)
)
if emotional_style.heading_styles:
emotional_style.heading_styles[1].font = FontStyle(name="华文行楷", size=18, bold=True, color="#E91E63")
emotional_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.2, space_before=16, space_after=14, alignment="center"
)
emotional_style.heading_styles[2].font = FontStyle(name="楷体", size=16, bold=True, color="#FF5722")
emotional_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=12, space_after=10
)
# 情感鸡汤文的引用样式
emotional_style.quote_block = SpecialStyle(
font=FontStyle(name="华文行楷", size=13, italic=True, color="#795548"),
paragraph=ParagraphStyle(
line_spacing=1.6, space_before=10, space_after=10,
alignment="center"
),
background_color="#FFF3E0"
)
return emotional_style
def _load_custom_styles(self) -> None:
"""加载自定义样式"""
if not os.path.exists(self.styles_dir):
os.makedirs(self.styles_dir, exist_ok=True)
return
try:
for filename in os.listdir(self.styles_dir):
if filename.endswith('.json'):
filepath = os.path.join(self.styles_dir, filename)
style = self.load_style_from_file(filepath)
if style:
self.custom_styles[style.name] = style
except Exception as e:
print(f"加载自定义样式失败: {e}")
def get_all_styles(self) -> Dict[str, DocumentStyle]:
"""获取所有样式(内置+自定义)"""
all_styles = deepcopy(self.builtin_styles)
all_styles.update(self.custom_styles)
return all_styles
def get_style_names(self) -> List[str]:
"""获取所有样式名称"""
return list(self.get_all_styles().keys())
def get_style(self, name: str) -> Optional[DocumentStyle]:
"""
获取指定样式
Args:
name: 样式名称
Returns:
DocumentStyle: 样式对象如果不存在返回None
"""
if name in self.builtin_styles:
return deepcopy(self.builtin_styles[name])
elif name in self.custom_styles:
return deepcopy(self.custom_styles[name])
return None
def create_custom_style(self, style: DocumentStyle) -> bool:
"""
创建自定义样式
Args:
style: 样式对象
Returns:
bool: 是否创建成功
"""
try:
print(f"尝试创建自定义样式: {style.name}") # 调试信息
if style.name in self.builtin_styles:
print(f"错误: {style.name} 是内置样式,不能覆盖")
return False # 不能覆盖内置样式
# 检查样式对象的完整性
if not style.body_font:
print("错误: 样式缺少body_font")
return False
if not style.body_paragraph:
print("错误: 样式缺少body_paragraph")
return False
print("样式对象检查通过")
# 保存到内存
self.custom_styles[style.name] = style
print(f"样式已保存到内存: {style.name}")
# 保存到文件
file_result = self.save_style_to_file(style)
print(f"文件保存结果: {file_result}")
if not file_result:
# 如果文件保存失败,从内存中移除
del self.custom_styles[style.name]
print("文件保存失败,已从内存中移除")
return False
print(f"样式 '{style.name}' 创建成功")
return True
except Exception as e:
print(f"创建自定义样式异常: {e}")
import traceback
traceback.print_exc()
return False
def update_custom_style(self, style: DocumentStyle) -> bool:
"""
更新自定义样式
Args:
style: 样式对象
Returns:
bool: 是否更新成功
"""
try:
if style.name in self.builtin_styles:
return False # 不能修改内置样式
self.custom_styles[style.name] = style
self.save_style_to_file(style)
return True
except Exception as e:
print(f"更新自定义样式失败: {e}")
return False
def delete_custom_style(self, name: str) -> bool:
"""
删除自定义样式
Args:
name: 样式名称
Returns:
bool: 是否删除成功
"""
try:
if name in self.builtin_styles:
return False # 不能删除内置样式
if name in self.custom_styles:
del self.custom_styles[name]
# 删除文件
filepath = os.path.join(self.styles_dir, f"{name}.json")
if os.path.exists(filepath):
os.remove(filepath)
return True
return False
except Exception as e:
print(f"删除自定义样式失败: {e}")
return False
def save_style_to_file(self, style: DocumentStyle, filepath: Optional[str] = None) -> bool:
"""
保存样式到文件
Args:
style: 样式对象
filepath: 文件路径如果为None则使用默认路径
Returns:
bool: 是否保存成功
"""
try:
if filepath is None:
os.makedirs(self.styles_dir, exist_ok=True)
filepath = os.path.join(self.styles_dir, f"{style.name}.json")
print(f"保存样式到文件: {filepath}") # 调试信息
# 检查目录权限
if not os.access(self.styles_dir, os.W_OK):
print(f"错误: 没有写入权限 - {self.styles_dir}")
return False
# 尝试序列化样式对象
style_dict = asdict(style)
print("样式对象序列化成功")
# 尝试写入文件
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(style_dict, f, ensure_ascii=False, indent=2)
print(f"样式文件保存成功: {filepath}")
# 验证文件是否存在且可读
if os.path.exists(filepath) and os.path.getsize(filepath) > 0:
print("文件存在性验证通过")
return True
else:
print("错误: 文件保存后验证失败")
return False
except Exception as e:
print(f"保存样式文件异常: {e}")
import traceback
traceback.print_exc()
return False
def load_style_from_file(self, filepath: str) -> Optional[DocumentStyle]:
"""
从文件加载样式
Args:
filepath: 文件路径
Returns:
DocumentStyle: 样式对象加载失败返回None
"""
try:
with open(filepath, 'r', encoding='utf-8') as f:
style_dict = json.load(f)
# 递归转换字典为dataclass
style = self._dict_to_style(style_dict)
return style
except Exception as e:
print(f"加载样式文件失败: {e}")
return None
def _dict_to_style(self, data: Dict[str, Any]) -> DocumentStyle:
"""将字典转换为DocumentStyle对象"""
# 转换嵌套的字体样式
if 'body_font' in data and data['body_font']:
data['body_font'] = FontStyle(**data['body_font'])
# 转换段落样式
if 'body_paragraph' in data and data['body_paragraph']:
data['body_paragraph'] = ParagraphStyle(**data['body_paragraph'])
# 转换标题样式
if 'heading_styles' in data and data['heading_styles']:
heading_styles = {}
for level, heading_data in data['heading_styles'].items():
if isinstance(heading_data, dict):
font_data = heading_data.get('font', {})
para_data = heading_data.get('paragraph', {})
heading_styles[int(level)] = HeadingStyle(
font=FontStyle(**font_data) if font_data else FontStyle(),
paragraph=ParagraphStyle(**para_data) if para_data else ParagraphStyle(),
numbering=heading_data.get('numbering', False),
outline_level=heading_data.get('outline_level', int(level))
)
data['heading_styles'] = heading_styles
# 转换列表样式
for list_type in ['unordered_list', 'ordered_list']:
if list_type in data and data[list_type]:
list_data = data[list_type]
font_data = list_data.get('font', {})
para_data = list_data.get('paragraph', {})
data[list_type] = ListStyle(
font=FontStyle(**font_data) if font_data else FontStyle(),
paragraph=ParagraphStyle(**para_data) if para_data else ParagraphStyle(),
bullet_symbol=list_data.get('bullet_symbol', ''),
number_format=list_data.get('number_format', '1.')
)
# 转换特殊样式
for special_type in ['code_block', 'quote_block', 'table_style']:
if special_type in data and data[special_type]:
special_data = data[special_type]
font_data = special_data.get('font', {})
para_data = special_data.get('paragraph', {})
data[special_type] = SpecialStyle(
font=FontStyle(**font_data) if font_data else FontStyle(),
paragraph=ParagraphStyle(**para_data) if para_data else ParagraphStyle(),
background_color=special_data.get('background_color', '#F5F5F5'),
border=special_data.get('border', False)
)
return DocumentStyle(**data)
def export_style(self, name: str, export_path: str) -> bool:
"""
导出样式到指定路径
Args:
name: 样式名称
export_path: 导出路径
Returns:
bool: 是否导出成功
"""
style = self.get_style(name)
if style:
return self.save_style_to_file(style, export_path)
return False
def import_style(self, import_path: str) -> Optional[str]:
"""
从指定路径导入样式
Args:
import_path: 导入路径
Returns:
Optional[str]: 导入的样式名称失败返回None
"""
style = self.load_style_from_file(import_path)
if style:
if self.create_custom_style(style):
return style.name
return None
def duplicate_style(self, source_name: str, new_name: str) -> bool:
"""
复制样式
Args:
source_name: 源样式名称
new_name: 新样式名称
Returns:
bool: 是否复制成功
"""
source_style = self.get_style(source_name)
if source_style and new_name not in self.get_all_styles():
source_style.name = new_name
source_style.description = f"基于 {source_name} 复制"
return self.create_custom_style(source_style)
return False
# 创建全局样式管理器实例
style_manager = StyleManager()
# 兼容性函数
def get_all_styles() -> Dict[str, DocumentStyle]:
"""获取所有样式(兼容旧接口)"""
return style_manager.get_all_styles()
def get_style(name: str) -> Optional[DocumentStyle]:
"""获取指定样式(兼容旧接口)"""
return style_manager.get_style(name)