[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EFSMFKTC13BRYTWMJ1FPD5":3,"skill-same:01M6EFSMFKTC13BRYTWMJ1FPD5":67},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":26,"linkOnly":27,"markdownContent":28,"markdownBody":28,"frontMatter":29,"refName":30,"commitSha":31,"skillDirectory":32,"forksCount":33,"repositoryHtmlUrl":34,"repositoryHomepageUrl":35,"ownerHtmlUrl":36,"ownerBlogUrl":6,"ownerDescription":37,"updatedAt":38,"install":39,"resources":52},"01M6EFSMFKTC13BRYTWMJ1FPD5","pdf-merge-split",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Fpdf-merge-split\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000002","文档处理","SCENARIO","使用场景",[23,24,25],"PDF","merge","pdf merge split","2026-11-10 10:12:30",false,"# PDF Merge & Split\n\n## Overview\n\nCombine multiple PDF files into a single document or split a PDF into separate files by page ranges. This skill handles merging in a specified order, splitting by page numbers, extracting specific pages, and preserving bookmarks and metadata where possible.\n\n## Instructions\n\nWhen a user asks to merge or split PDF files, follow these steps:\n\n### Step 1: Determine the operation\n\nAsk or infer what the user needs:\n- **Merge**: Combine multiple PDFs into one output file\n- **Split by pages**: Break a single PDF into multiple files by page ranges\n- **Extract pages**: Pull specific pages out into a new PDF\n- **Split by size**: Divide a PDF into chunks of N pages each\n\n### Step 2: Validate the input files\n\nCheck that all input files exist and are valid PDFs:\n\n```python\nimport os\nfrom PyPDF2 import PdfReader\n\ndef validate_pdfs(file_paths):\n    results = []\n    for path in file_paths:\n        if not os.path.exists(path):\n            results.append({\"file\": path, \"status\": \"not found\"})\n            continue\n        try:\n            reader = PdfReader(path)\n            results.append({\n                \"file\": path,\n                \"status\": \"valid\",\n                \"pages\": len(reader.pages)\n            })\n        except Exception as e:\n            results.append({\"file\": path, \"status\": f\"invalid: {e}\"})\n    return results\n```\n\n### Step 3: Perform the operation\n\n**For merging:**\n\n```python\nfrom PyPDF2 import PdfMerger\n\ndef merge_pdfs(input_paths, output_path):\n    merger = PdfMerger()\n    for path in input_paths:\n        merger.append(path)\n    merger.write(output_path)\n    merger.close()\n    return output_path\n```\n\n**For splitting by page ranges:**\n\n```python\nfrom PyPDF2 import PdfReader, PdfWriter\n\ndef split_pdf(input_path, ranges, output_dir=\".\"):\n    reader = PdfReader(input_path)\n    output_files = []\n    for i, (start, end) in enumerate(ranges):\n        writer = PdfWriter()\n        for page_num in range(start - 1, min(end, len(reader.pages))):\n            writer.add_page(reader.pages[page_num])\n        output_path = os.path.join(output_dir, f\"split_{i+1}_pages_{start}-{end}.pdf\")\n        with open(output_path, \"wb\") as f:\n            writer.write(f)\n        output_files.append(output_path)\n    return output_files\n```\n\n**For extracting specific pages:**\n\n```python\ndef extract_pages(input_path, page_numbers, output_path):\n    reader = PdfReader(input_path)\n    writer = PdfWriter()\n    for page_num in page_numbers:\n        if 1 \u003C= page_num \u003C= len(reader.pages):\n            writer.add_page(reader.pages[page_num - 1])\n    with open(output_path, \"wb\") as f:\n        writer.write(f)\n    return output_path\n```\n\n### Step 4: Verify and report results\n\nAfter the operation, verify the output:\n1. Confirm the output file exists and is a valid PDF\n2. Report the page count of each output file\n3. Show file sizes for the user\n\n## Examples\n\n### Example 1: Merge three reports into one\n\n**User request:** \"Combine report-q1.pdf, report-q2.pdf, and report-q3.pdf into annual-report.pdf\"\n\n**Actions taken:**\n1. Validate all three input files\n2. Merge in the specified order\n3. Write to annual-report.pdf\n\n**Output:**\n```\nMerged 3 PDF files into annual-report.pdf\n\nInput files:\n  1. report-q1.pdf (12 pages)\n  2. report-q2.pdf (15 pages)\n  3. report-q3.pdf (11 pages)\n\nOutput: annual-report.pdf (38 pages, 2.4 MB)\n```\n\n### Example 2: Split a PDF into chapters\n\n**User request:** \"Split textbook.pdf into separate files: pages 1-30, 31-55, 56-80\"\n\n**Actions taken:**\n1. Validate textbook.pdf (80 pages)\n2. Split into three page ranges\n3. Save each range as a separate file\n\n**Output:**\n```\nSplit textbook.pdf into 3 files:\n\n  1. split_1_pages_1-30.pdf   (30 pages, 1.1 MB)\n  2. split_2_pages_31-55.pdf  (25 pages, 0.9 MB)\n  3. split_3_pages_56-80.pdf  (25 pages, 0.8 MB)\n\nAll files saved to current directory.\n```\n\n### Example 3: Extract specific pages\n\n**User request:** \"Pull out pages 5, 12, and 18-22 from presentation.pdf\"\n\n**Actions taken:**\n1. Parse the page specification: [5, 12, 18, 19, 20, 21, 22]\n2. Extract those pages from presentation.pdf\n3. Save as extracted_pages.pdf\n\n**Output:**\n```\nExtracted 7 pages from presentation.pdf\n\nPages extracted: 5, 12, 18, 19, 20, 21, 22\nOutput: extracted_pages.pdf (7 pages, 540 KB)\n```\n\n## Guidelines\n\n- Always validate input files before processing. Report clear errors for missing or corrupt files.\n- Preserve the original files. Never modify input PDFs in place.\n- When merging, respect the order specified by the user. If no order is given, use alphabetical.\n- Use 1-based page numbering in all user-facing output to match what users see in PDF viewers.\n- For encrypted PDFs, inform the user that a password is needed before processing.\n- When splitting, create descriptive filenames that include page ranges.\n- Report file sizes alongside page counts so the user knows the output scale.\n- Install PyPDF2 with `pip install PyPDF2` if not available. For advanced features like preserving form fields, use pikepdf instead.\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002FTerminalSkills\u002Fskills\u002Fpdf-merge-split",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":40,"prompt":50,"zipAvailable":51},[41,44,47],{"tool":42,"command":43},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill pdf-merge-split",{"tool":45,"command":46},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill pdf-merge-split",{"tool":48,"command":49},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill pdf-merge-split","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Fpdf-merge-split\u002FSKILL.md",true,[53,59,63],{"path":54,"resourceType":55,"resourceTypeDesc":56,"sizeBytes":57,"sourceHtmlUrl":58},"CHECKLIST.md","REFERENCE","参考文档",19175,"https:\u002F\u002Fgithub.com\u002Fvitalikpestov\u002FSkills-Catalog\u002Fblob\u002Fmain\u002F_Mobile-Dev\u002Ffrom-article-18-ui-ux\u002Fbencium-claude-code-design-skill\u002Fhuman-architect-mindset\u002Fskills\u002Fhuman-architect-mindset\u002FCHECKLIST.md",{"path":60,"resourceType":55,"resourceTypeDesc":56,"sizeBytes":61,"sourceHtmlUrl":62},"EXAMPLES.md",23517,"https:\u002F\u002Fgithub.com\u002Fvitalikpestov\u002FSkills-Catalog\u002Fblob\u002Fmain\u002F_Mobile-Dev\u002Ffrom-article-18-ui-ux\u002Fbencium-claude-code-design-skill\u002Fhuman-architect-mindset\u002Fskills\u002Fhuman-architect-mindset\u002FEXAMPLES.md",{"path":64,"resourceType":55,"resourceTypeDesc":56,"sizeBytes":65,"sourceHtmlUrl":66},"REFERENCE.md",22666,"https:\u002F\u002Fgithub.com\u002Fvitalikpestov\u002FSkills-Catalog\u002Fblob\u002Fmain\u002F_Mobile-Dev\u002Ffrom-article-18-ui-ux\u002Fbencium-claude-code-design-skill\u002Fhuman-architect-mindset\u002Fskills\u002Fhuman-architect-mindset\u002FREFERENCE.md",[68,80,90,99,105,112],{"skillNo":69,"name":70,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":71,"categories":72,"keywords":76,"publishedAt":26},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[73],{"categoryNo":74,"categoryName":75,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[77,78,79],"model","model hierarchy","model hierarchy skill",{"skillNo":81,"name":82,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":83,"categories":84,"keywords":86,"publishedAt":26},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[85],{"categoryNo":74,"categoryName":75,"taxonomyType":20,"taxonomyTypeDesc":21},[87,88,89],"MCP","zoom","zoom mcp",{"skillNo":91,"name":92,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":95,"publishedAt":26},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[96,97,98,88],"sdk","zoom apps sdk","apps",{"skillNo":100,"name":101,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":102,"categories":103,"keywords":104,"publishedAt":26},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[101],{"skillNo":106,"name":107,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":111,"publishedAt":26},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[110],{"categoryNo":74,"categoryName":75,"taxonomyType":20,"taxonomyTypeDesc":21},[107],{"skillNo":113,"name":114,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":115,"categories":116,"keywords":117,"publishedAt":26},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[114]]