#!/usr/bin/env python3 """ 生成律师业务操作指引PDF - 分批生成 """ import os import re import subprocess import sys # PDF生成器 - 使用weasyprint from weasyprint import HTML, CSS BASE_DIR = '/root/.openclaw/workspace/知识库/律师业务操作指引' SHANGHAI_DIR = f'{BASE_DIR}/上海律协' QUANGUO_DIR = f'{BASE_DIR}/全国律协' PDF_DIR = f'{BASE_DIR}/PDF' os.makedirs(PDF_DIR, exist_ok=True) # CSS样式 PDF_CSS = """ @page { size: A4; margin: 2.5cm 2cm 2cm 2.5cm; @bottom-center { content: counter(page); font-family: 'AR PL UMing CN'; font-size: 9pt; color: #666; } } body { font-family: 'AR PL UMing CN', 'Noto Serif CJK SC', 'SimSun', serif; font-size: 10.5pt; line-height: 1.8; text-indent: 2em; margin: 0; padding: 0; } h1 { font-size: 14pt; font-weight: bold; text-align: center; margin: 0 0 0.5em 0; text-indent: 0; page-break-after: avoid; } h2, h3 { font-size: 12pt; font-weight: bold; text-indent: 0; page-break-after: avoid; } p { font-size: 10.5pt; line-height: 1.8; margin: 0.3em 0; text-indent: 2em; } .meta { font-size: 9pt; color: #555; margin-bottom: 1em; text-indent: 0; } hr { border: none; border-top: 1px solid #ccc; margin: 0.8em 0; } """ def markdown_to_html(md_content): """将Markdown转换为HTML""" import markdown md = markdown.Markdown(extensions=['tables', 'fenced_code']) html_body = md.convert(md_content) html = f""" {html_body} """ return html def md_to_pdf(md_path, pdf_path, title_override=''): """将Markdown文件转换为PDF""" try: with open(md_path, 'r', encoding='utf-8') as f: content = f.read() # 解析标题和正文 lines = content.split('\n') title = title_override meta_lines = [] body_start = 0 for i, line in enumerate(lines): if line.startswith('# '): title = line[2:].strip() body_start = i + 1 elif line.startswith('**') and i < 5: meta_lines.append(line) elif line == '---' and i < 10: body_start = i + 1 break body = '\n'.join(lines[body_start:]).strip() # 转换为HTML import markdown md = markdown.Markdown(extensions=['tables']) body_html = md.convert(body) meta_html = '
' + '
'.join(meta_lines) + '
' if meta_lines else '' html_content = f"""

{title}

{meta_html}
{body_html} """ # 生成PDF HTML(string=html_content).write_pdf(pdf_path) return True except Exception as e: print(f' PDF失败: {md_path}: {e}') return False def generate_batch_pdf(md_files, output_pdf, batch_name): """将多个MD文件合并为一个PDF""" print(f"\n生成批次PDF: {output_pdf}") all_html = [] for md_path in md_files: try: with open(md_path, 'r', encoding='utf-8') as f: content = f.read() lines = content.split('\n') title = '' meta_lines = [] body_start = 0 for i, line in enumerate(lines): if line.startswith('# '): title = line[2:].strip() body_start = i + 1 elif line.startswith('**') and i < 5: meta_lines.append(line) elif line == '---' and i < 10: body_start = i + 1 break body = '\n'.join(lines[body_start:]).strip() import markdown md = markdown.Markdown(extensions=['tables']) body_html = md.convert(body) meta_html = '
' + '
'.join(meta_lines) + '
' if meta_lines else '' page_html = f"""

{title}

{meta_html}
{body_html}
""" all_html.append(page_html) except Exception as e: print(f' 跳过: {md_path}: {e}') if not all_html: print(f' 无内容可生成') return False combined_html = f""" {''.join(all_html)} """ try: HTML(string=combined_html).write_pdf(output_pdf) size = os.path.getsize(output_pdf) print(f' 生成成功: {output_pdf} ({size/1024/1024:.1f} MB)') return True except Exception as e: print(f' PDF生成失败: {e}') return False def main(): print("="*60) print("律师业务操作指引PDF生成器") print("="*60) # 上海律协 shanghai_files = sorted([f for f in os.listdir(SHANGHAI_DIR) if f.endswith('.md')]) shanghai_paths = [os.path.join(SHANGHAI_DIR, f) for f in shanghai_files] print(f"\n上海律协: {len(shanghai_paths)} 个文件") # 分批生成PDF (每批20个文件) batch_size = 20 batch_num = 0 for i in range(0, len(shanghai_paths), batch_size): batch = shanghai_paths[i:i+batch_size] batch_num += 1 batch_name = f"上海律协_批次{batch_num}" pdf_path = os.path.join(PDF_DIR, f'{batch_name}.pdf') result = generate_batch_pdf(batch, pdf_path, batch_name) # 生成完整汇总PDF if shanghai_paths: full_pdf = os.path.join(PDF_DIR, '上海律协_全部指引汇总.pdf') print(f"\n生成上海律协完整汇总PDF...") # 分批以避免PDF过大 for start in range(0, len(shanghai_paths), 30): batch = shanghai_paths[start:start+30] bname = f"上海律协_汇总_{start//30+1}" pdf_path = os.path.join(PDF_DIR, f'{bname}.pdf') generate_batch_pdf(batch, pdf_path, bname) # 全国律协 quanguo_files = sorted([f for f in os.listdir(QUANGUO_DIR) if f.endswith('.md')]) quanguo_paths = [os.path.join(QUANGUO_DIR, f) for f in quanguo_files] print(f"\n全国律协: {len(quanguo_paths)} 个文件") if quanguo_paths: full_pdf = os.path.join(PDF_DIR, '全国律协_全部指引汇总.pdf') generate_batch_pdf(quanguo_paths, full_pdf, '全国律协全部指引') # 列出生成的PDF pdf_files = sorted([f for f in os.listdir(PDF_DIR) if f.endswith('.pdf')]) print(f"\n\n共生成 {len(pdf_files)} 个PDF文件:") for f in pdf_files: sz = os.path.getsize(os.path.join(PDF_DIR, f)) print(f" {f} ({sz/1024/1024:.1f} MB)") if __name__ == '__main__': main()