#!/bin/bash # PowerBell软著版本号快速修改+生成脚本 # 无需手动改主脚本,输入版本号直接运行 # 颜色输出函数 red_echo() { echo -e "\033[31m$1\033[0m"; } green_echo() { echo -e "\033[32m$1\033[0m"; } blue_echo() { echo -e "\033[34m$1\033[0m"; } # 1. 提示用户输入新版本号 blue_echo "==== 请输入软著版本号(格式示例:V15、V15.0.1) ====" read -p "输入版本号:" NEW_VERSION # 校验版本号格式(避免特殊符号) if [[ ! $NEW_VERSION =~ ^V[0-9]+(\.[0-9]+)*$ ]]; then red_echo "错误:版本号格式无效!请遵循「V+数字」格式(如V15、V15.0.1),不含特殊符号" exit 1 fi # 2. 定义固定配置(仅需修改这里的著作权人,其他无需动) SOFTWARE_NAME="PowerBell" COPYRIGHT_OWNER="张绍建陆丰东海镇云宝软件开发工作室" LINES_PER_PAGE=55 # 3. 生成主脚本(自动替换新版本号) blue_echo -e "\n==== 生成${NEW_VERSION}版本主脚本 ====" cat > build_copyright_pdf_temp.sh << EOF #!/bin/bash # PowerBell软著PDF生成脚本(版本:$NEW_VERSION) red_echo() { echo -e "\033[31m\$1\033[0m"; } green_echo() { echo -e "\033[32m\$1\033[0m"; } blue_echo() { echo -e "\033[34m\$1\033[0m"; } # 配置项(已自动替换为${NEW_VERSION}) SOFTWARE_NAME="$SOFTWARE_NAME" SOFTWARE_VERSION="$NEW_VERSION" COPYRIGHT_OWNER="$COPYRIGHT_OWNER" LINES_PER_PAGE=$LINES_PER_PAGE # 步骤1:检查依赖 blue_echo "==== 1/7 检查并安装依赖 ====" sudo apt update > /dev/null 2>&1 REQUIRED_PKGS=("python3" "wkhtmltopdf" "fonts-wqy-microhei" "pdftk" "poppler-utils") for pkg in "\${REQUIRED_PKGS[@]}"; do if ! dpkg -s "\$pkg" > /dev/null 2>&1; then green_echo "安装依赖:\$pkg" sudo apt install -y "\$pkg" > /dev/null 2>&1 fi done # 步骤2:生成纯文本源码 blue_echo -e "\n==== 2/7 生成纯文本核心源码 ====" cat > generate_source.py << GEN_EOF import os PROJECT_PATH = "./" OUTPUT_TXT = "PowerBell_Core_Source.txt" INCLUDE_EXT = [".java", ".kt"] EXCLUDE_DIRS = ["build", "libs", "test", "androidTest", ".git", ".idea", "gradle", "unittest"] MIN_LINE_COUNT = 3 SOFTWARE_NAME = "$SOFTWARE_NAME" SOFTWARE_VERSION = "$NEW_VERSION" COPYRIGHT_OWNER = "$COPYRIGHT_OWNER" def clean_text(text): return ''.join(c for c in text if c.isprintable() or c in "\\n\\r\\t") def generate_source_txt(): valid_files = [] main_dir = os.path.join(PROJECT_PATH, "src", "main") if not os.path.exists(main_dir): print("Error: src/main directory not found!") return for root, dirs, files in os.walk(main_dir): dirs[:] = [d for d in dirs if d not in EXCLUDE_DIRS] for file in files: if os.path.splitext(file)[1] in INCLUDE_EXT: file_path = os.path.join(root, file) try: with open(file_path, "r", encoding="utf-8", errors="ignore") as f: lines = f.readlines() code_lines = [l for l in lines if l.strip() and not l.strip().startswith("//")] if len(code_lines) >= MIN_LINE_COUNT: valid_files.append(file_path) except: continue valid_files.sort(key=lambda x: os.path.getsize(x), reverse=True) with open(OUTPUT_TXT, "w", encoding="utf-8-sig") as f: f.write(f"\{SOFTWARE_NAME} \{SOFTWARE_VERSION} 核心源码 - 著作权人:\{COPYRIGHT_OWNER}\\n\\n") for idx, file_path in enumerate(valid_files, 1): f.write(f"\\n{'='*60}\\n") f.write(f"文件 \{idx}:\{file_path.replace(PROJECT_PATH, '')}\\n") f.write(f"{'='*60}\\n\\n") try: try: with open(file_path, "r", encoding="utf-8") as src_f: content = clean_text(src_f.read()) except UnicodeDecodeError: with open(file_path, "r", encoding="gbk") as src_f: content = clean_text(src_f.read()) f.write(content) f.write("\\n\\n") except Exception as e: f.write(f"文件读取失败:\{str(e)}\\n\\n") continue print(f"有效源码文件数:\{len(valid_files)}") print(f"纯文本文件路径:\{os.path.abspath(OUTPUT_TXT)}") if __name__ == "__main__": generate_source_txt() GEN_EOF python3 generate_source.py if [ ! -f "PowerBell_Core_Source.txt" ]; then red_echo "纯文本源码生成失败!" exit 1 fi # 步骤3:生成带版本号页眉的HTML blue_echo -e "\n==== 3/7 生成带${NEW_VERSION}页眉的HTML ====" cat > txt2html.py << TXT_EOF import os TXT_FILE = "PowerBell_Core_Source.txt" HTML_FILE = "PowerBell_Source.html" SOFTWARE_NAME = "$SOFTWARE_NAME" SOFTWARE_VERSION = "$NEW_VERSION" COPYRIGHT_OWNER = "$COPYRIGHT_OWNER" LINES_PER_PAGE = $LINES_PER_PAGE CSS_STYLE = """ """.format(SOFTWARE_NAME, SOFTWARE_VERSION, COPYRIGHT_OWNER) def txt_to_html(): with open(TXT_FILE, "r", encoding="utf-8") as f: content = f.read() html_content = "
" + CSS_STYLE + "" content_lines = content.split("\\n")[2:] content_clean = "\\n".join(content_lines) blocks = content_clean.split("====") line_count = 0 for block in blocks: if not block.strip(): continue if "文件 " in block and ":" in block: file_header = block.split("\\n")[0].strip() if "\\n" in block else block.strip() html_content += f"