novel-tools/generators/chapter_generator.py

205 lines
6.8 KiB
Python
Raw Permalink Normal View History

#!/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()