From 1c7ceebb78f632fe3060cc21be24b0f95b96f03d Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Wed, 17 Dec 2025 04:03:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=BD=AF=E8=91=97=E7=94=B3?= =?UTF-8?q?=E8=AF=B7=E6=96=87=E6=A1=A3=E7=94=9F=E6=88=90=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- powerbell/build_copyright_pdf.sh | 279 +++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 powerbell/build_copyright_pdf.sh diff --git a/powerbell/build_copyright_pdf.sh b/powerbell/build_copyright_pdf.sh new file mode 100644 index 0000000..3c3125b --- /dev/null +++ b/powerbell/build_copyright_pdf.sh @@ -0,0 +1,279 @@ +#!/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"
\{file_header}
" + code_part = block.split("\\n")[1:] if "\\n" in block else [] + block = "\\n".join(code_part) + code_lines = block.split("\\n") + for line in code_lines: + if line.strip() or line_count > 0: + line_count += 1 + html_content += f"
\{line}
" + if line_count >= LINES_PER_PAGE: + html_content += "
" + line_count = 0 + html_content += "" + with open(HTML_FILE, "w", encoding="utf-8") as f: + f.write(html_content) + print(f"HTML文件路径:\{os.path.abspath(HTML_FILE)}") + +if __name__ == "__main__": + txt_to_html() +TXT_EOF + +python3 txt2html.py +if [ ! -f "PowerBell_Source.html" ]; then + red_echo "HTML文件生成失败!" + exit 1 +fi + +# 步骤4:生成完整PDF +blue_echo -e "\n==== 4/7 生成完整PDF(版本:${NEW_VERSION}) ====" +wkhtmltopdf --page-size A4 \ + --margin-top 15mm --margin-bottom 15mm --margin-left 5mm --margin-right 5mm \ + --encoding utf-8 \ + --no-images --disable-javascript \ + --enable-local-file-access \ + --no-stop-slow-scripts \ + PowerBell_Source.html PowerBell_soft_full.pdf + +if [ ! -f "PowerBell_soft_full.pdf" ]; then + red_echo "完整PDF生成失败!" + exit 1 +fi + +# 步骤5:截取60页 +blue_echo -e "\n==== 5/7 截取前30+后30页 ====" +TOTAL_PAGES=\$(pdfinfo PowerBell_soft_full.pdf | grep "Pages" | awk '{print \$2}') +green_echo "源码完整PDF总页数:\$TOTAL_PAGES 页" + +if [ "\$TOTAL_PAGES" -le 60 ]; then + cp PowerBell_soft_full.pdf PowerBell_软著源码_${NEW_VERSION}_60页.pdf + green_echo "源码不足60页,直接使用完整PDF" +else + pdftk PowerBell_soft_full.pdf cat 1-30 output PowerBell_前30页.pdf + START_PAGE=\$((TOTAL_PAGES - 29)) + pdftk PowerBell_soft_full.pdf cat \$START_PAGE-\$TOTAL_PAGES output PowerBell_后30页.pdf + pdftk PowerBell_前30页.pdf PowerBell_后30页.pdf cat output PowerBell_软著源码_${NEW_VERSION}_60页.pdf + rm -f PowerBell_前30页.pdf PowerBell_后30页.pdf + green_echo "源码超过60页,已截取前30页+后30页合并为60页" +fi + +# 步骤6:验证规范 +blue_echo -e "\n==== 6/7 验证${NEW_VERSION}版本PDF规范 ====" +FINAL_PAGES=\$(pdfinfo PowerBell_软著源码_${NEW_VERSION}_60页.pdf | grep "Pages" | awk '{print \$2}') +green_echo "最终PDF页数:\$FINAL_PAGES 页" +green_echo "每页代码行数:\$LINES_PER_PAGE 行(≥50行)" +green_echo "页眉信息:$SOFTWARE_NAME $NEW_VERSION - 源代码(著作权人:$COPYRIGHT_OWNER)" + +# 步骤7:清理临时文件 +blue_echo -e "\n==== 7/7 清理临时文件 ====" +rm -f generate_source.py txt2html.py PowerBell_Core_Source.txt PowerBell_Source.html PowerBell_soft_full.pdf +green_echo "临时文件清理完成!" + +# 输出结果 +green_echo -e "\n=====================================" +green_echo "✅ $SOFTWARE_NAME $NEW_VERSION 软著PDF生成成功!🎉" +green_echo "📄 最终文件:\$(pwd)/PowerBell_软著源码_${NEW_VERSION}_60页.pdf" +green_echo "💡 可直接提交软著登记,无需手动修改!" +green_echo "=====================================" +EOF + +# 4. 赋予执行权限并运行 +chmod +x build_copyright_pdf_temp.sh +blue_echo -e "\n==== 开始生成${NEW_VERSION}版本PDF ====" +./build_copyright_pdf_temp.sh + +# 5. 删除临时主脚本(可选,保留则注释此行) +rm -f build_copyright_pdf_temp.sh + +green_echo -e "\n==== 操作完成!${NEW_VERSION}版本PDF已生成 ===="