205 lines
6.8 KiB
Python
Executable File
205 lines
6.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
||
"""
|
||
章节生成器
|
||
根据模板生成标准化的章节结构
|
||
"""
|
||
|
||
import os
|
||
import re
|
||
from datetime import datetime
|
||
|
||
class ChapterGenerator:
|
||
def __init__(self, template_path=None):
|
||
"""初始化生成器"""
|
||
self.template = self.load_template(template_path) or self.default_template()
|
||
|
||
def load_template(self, template_path):
|
||
"""加载模板文件"""
|
||
if template_path and os.path.exists(template_path):
|
||
with open(template_path, 'r', encoding='utf-8') as f:
|
||
return f.read()
|
||
return None
|
||
|
||
def default_template(self):
|
||
"""默认模板(番茄黄金三章模板)"""
|
||
return """# 第{chapter_number}章:{chapter_title}
|
||
|
||
## 承接(100-300字)
|
||
{setup}
|
||
|
||
## 推进(800-2000字)
|
||
{development}
|
||
|
||
## 高潮(500-1000字)
|
||
{climax}
|
||
|
||
## 钩子(100-300字)
|
||
{hook}
|
||
|
||
---
|
||
|
||
**字数统计**: {word_count}字
|
||
**更新时间**: {update_time}
|
||
**作者备注**: {note}
|
||
"""
|
||
|
||
def generate(self, chapter_number, chapter_title, setup, development, climax, hook, note=""):
|
||
"""生成章节内容"""
|
||
# 计算字数
|
||
word_count = len(setup + development + climax + hook)
|
||
|
||
# 填充模板
|
||
content = self.template.format(
|
||
chapter_number=chapter_number,
|
||
chapter_title=chapter_title,
|
||
setup=setup,
|
||
development=development,
|
||
climax=climax,
|
||
hook=hook,
|
||
word_count=word_count,
|
||
update_time=datetime.now().strftime('%Y-%m-%d %H:%M'),
|
||
note=note or "正常更新"
|
||
)
|
||
|
||
return content
|
||
|
||
def save_chapter(self, project_path, chapter_number, chapter_title, content, **kwargs):
|
||
"""保存章节文件"""
|
||
# 创建章节目录
|
||
chapters_dir = os.path.join(project_path, "chapters")
|
||
os.makedirs(chapters_dir, exist_ok=True)
|
||
|
||
# 生成文件名
|
||
filename = f"ch{chapter_number:02d}-{chapter_title}.md"
|
||
filepath = os.path.join(chapters_dir, filename)
|
||
|
||
# 保存文件
|
||
with open(filepath, 'w', encoding='utf-8') as f:
|
||
f.write(content)
|
||
|
||
print(f"章节已保存: {filepath}")
|
||
return filepath
|
||
|
||
def generate_from_outline(self, project_path, outline_file):
|
||
"""根据大纲文件生成章节"""
|
||
if not os.path.exists(outline_file):
|
||
print(f"大纲文件不存在: {outline_file}")
|
||
return []
|
||
|
||
# 读取大纲
|
||
with open(outline_file, 'r', encoding='utf-8') as f:
|
||
outline_content = f.read()
|
||
|
||
# 解析大纲中的章节信息
|
||
# 这里假设大纲有特定的格式
|
||
chapters = []
|
||
|
||
# 简单示例:解析 ## 第X章:标题 格式
|
||
chapter_pattern = r'##\s*第(\d+)章[::]\s*(.+?)\n(.*?)(?=##\s*第|\Z)'
|
||
matches = re.findall(chapter_pattern, outline_content, re.DOTALL)
|
||
|
||
for match in matches:
|
||
chapter_num = int(match[0])
|
||
chapter_title = match[1].strip()
|
||
chapter_content = match[2].strip()
|
||
|
||
# 从内容中提取各个部分(简单实现)
|
||
sections = self.parse_chapter_content(chapter_content)
|
||
|
||
# 生成章节
|
||
content = self.generate(
|
||
chapter_number=chapter_num,
|
||
chapter_title=chapter_title,
|
||
setup=sections.get('承接', ''),
|
||
development=sections.get('推进', ''),
|
||
climax=sections.get('高潮', ''),
|
||
hook=sections.get('钩子', ''),
|
||
note="从大纲生成"
|
||
)
|
||
|
||
# 保存章节
|
||
filepath = self.save_chapter(project_path, chapter_num, chapter_title, content)
|
||
chapters.append(filepath)
|
||
|
||
return chapters
|
||
|
||
def parse_chapter_content(self, content):
|
||
"""解析章节内容为各个部分"""
|
||
sections = {}
|
||
|
||
# 简单按行分割
|
||
current_section = None
|
||
section_content = []
|
||
|
||
for line in content.split('\n'):
|
||
line = line.strip()
|
||
|
||
# 检查是否是新的章节部分
|
||
if line.startswith('###'):
|
||
if current_section and section_content:
|
||
sections[current_section] = '\n'.join(section_content).strip()
|
||
|
||
# 提取章节标题
|
||
section_title = line.replace('###', '').strip()
|
||
if '承接' in section_title:
|
||
current_section = '承接'
|
||
elif '推进' in section_title:
|
||
current_section = '推进'
|
||
elif '高潮' in section_title:
|
||
current_section = '高潮'
|
||
elif '钩子' in section_title:
|
||
current_section = '钩子'
|
||
else:
|
||
current_section = None
|
||
|
||
section_content = []
|
||
elif current_section and line:
|
||
section_content.append(line)
|
||
|
||
# 处理最后一个部分
|
||
if current_section and section_content:
|
||
sections[current_section] = '\n'.join(section_content).strip()
|
||
|
||
return sections
|
||
|
||
def main():
|
||
"""主函数"""
|
||
import argparse
|
||
|
||
parser = argparse.ArgumentParser(description="章节生成器")
|
||
parser.add_argument("--project", help="项目路径", default=".")
|
||
parser.add_argument("--number", type=int, help="章节编号", required=True)
|
||
parser.add_argument("--title", help="章节标题", required=True)
|
||
parser.add_argument("--setup", help="承接部分", default="")
|
||
parser.add_argument("--development", help="推进部分", default="")
|
||
parser.add_argument("--climax", help="高潮部分", default="")
|
||
parser.add_argument("--hook", help="钩子部分", default="")
|
||
parser.add_argument("--note", help="作者备注", default="")
|
||
parser.add_argument("--outline", help="从大纲文件生成")
|
||
|
||
args = parser.parse_args()
|
||
|
||
generator = ChapterGenerator()
|
||
|
||
if args.outline:
|
||
# 从大纲生成
|
||
chapters = generator.generate_from_outline(args.project, args.outline)
|
||
print(f"从大纲生成了 {len(chapters)} 个章节")
|
||
else:
|
||
# 直接生成
|
||
content = generator.generate(
|
||
chapter_number=args.number,
|
||
chapter_title=args.title,
|
||
setup=args.setup or "承接内容待补充",
|
||
development=args.development or "推进内容待补充",
|
||
climax=args.climax or "高潮内容待补充",
|
||
hook=args.hook or "钩子内容待补充",
|
||
note=args.note
|
||
)
|
||
|
||
generator.save_chapter(args.project, args.number, args.title, content)
|
||
print("章节生成完成")
|
||
|
||
if __name__ == "__main__":
|
||
main()
|