novel-tools/generators/chapter_generator.py
唐天洛 5ae289decb 项目初始化:小说创作工具集
- 创建飞书同步工具 (Python版)
- 创建字数统计工具
- 创建章节生成器
- 创建番茄黄金三章模板
- 完善项目文档和结构
- 配置完整的工具链
2026-03-30 12:32:57 +08:00

205 lines
6.8 KiB
Python
Executable File
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.

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