205 lines
6.8 KiB
Python
205 lines
6.8 KiB
Python
|
|
#!/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()
|