[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6KVX2WJ32NKDSX1BYVCFKDB":3,"skill-same:01M6KVX2WJ32NKDSX1BYVCFKDB":130},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":15,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":48,"linkOnly":49,"markdownContent":50,"markdownBody":51,"frontMatter":52,"refName":59,"commitSha":60,"skillDirectory":61,"forksCount":62,"repositoryHtmlUrl":63,"repositoryHomepageUrl":64,"ownerHtmlUrl":65,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":66,"install":67,"resources":80},"01M6KVX2WJ32NKDSX1BYVCFKDB","pdf",null,"Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text\u002Ftables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting\u002Fdecrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.","mateaix\u002Fmateclaw","mateaix","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F57164338?v=4","01M6KVQ3JXJP7M6D3BKS2BAMFF","01M6KVQ3Q8YG7DT57AY22TBXGG",1196,"LicenseRef-Proprietary","https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000002","文档处理","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47],"PDF","images","new","to do","tables","reading","extracting","make","pages","forms","do","files","use","user","python3","text","ocr","file","windows","linux","macos","2026-11-09 23:53:37",false,"---\nname: pdf\ndescription: \"Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text\u002Ftables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting\u002Fdecrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.\"\ndependencies:\n  commands:\n    - python3\n  tools:\n    - skillScriptTool\n    - skillFileTool\nplatforms:\n  - macos\n  - linux\n  - windows\n---\n\n> **Important:** All `scripts\u002F` paths are relative to this skill directory.\n> Use `run_skill_script` tool to execute scripts, or run with: `cd {this_skill_dir} && python scripts\u002F...`\n\n# PDF Processing Guide\n\n## Prerequisites\n\n- **pypdf**: core PDF reading and writing\n- **pdfplumber**: text and table extraction\n- **reportlab**: PDF creation\n- **pdftotext** (poppler-utils): command-line text extraction\n- **pdftoppm** (poppler-utils): PDF-to-image conversion\n- **qpdf**: PDF manipulation (merge, split, rotate, decrypt)\n\n## Tool Selection Decision Table\n\nChoose the right approach before starting:\n\n| Input | Condition | Recommended Tool |\n|-------|-----------|-----------------|\n| URL | PDF accessible via URL | `web_extract(url)` — fastest, no download needed |\n| Local file | Text-native PDF (generated by software) | `pymupdf` — ~25 MB install, instant extraction |\n| Local file | Scanned\u002Fimage-only PDF (no selectable text) | `marker-pdf` — OCR with layout preservation (~5 GB, needs GPU or CPU) |\n| Local file | Form filling or page manipulation | `pypdf` \u002F `pdfplumber` + form scripts |\n| Local file | NLP editing or semantic search | `nano-pdf` — sentence-level operations |\n\n**URL-first rule**: If the user provides a URL, always try URL extraction first before downloading.\n\n## Overview\n\nThis guide covers essential PDF processing operations using Python libraries and command-line tools.\n\n## URL-First Extraction\n\nIf the user provides a URL pointing to a PDF, extract it without downloading:\n\n```\nweb_extract(url=\"https:\u002F\u002Fexample.com\u002Freport.pdf\")\n```\n\nFall back to download + local processing only if `web_extract` returns empty or errors.\n\n---\n\n## Fast Extraction: pymupdf (fitz)\n\n**Best for**: Text-native PDFs (digital, not scanned). Install: `pip install pymupdf` (~25 MB).\n\n```python\nimport fitz  # pymupdf\n\ndoc = fitz.open(\"document.pdf\")\nprint(f\"Pages: {doc.page_count}\")\n\n# Extract all text (fast)\nfull_text = \"\\n\".join(page.get_text() for page in doc)\n\n# Extract with layout blocks (tables, columns)\nfor page in doc:\n    blocks = page.get_text(\"blocks\")  # (x0,y0,x1,y1,text,block_no,block_type)\n    for block in blocks:\n        print(block[4])  # text content\n\n# Extract images\nfor page in doc:\n    for img in page.get_images():\n        xref = img[0]\n        base = doc.extract_image(xref)\n        with open(f\"img_{xref}.{base['ext']}\", \"wb\") as f:\n            f.write(base[\"image\"])\n```\n\npymupdf is 5-10× faster than pypdf for text extraction and preserves layout better.\n\n---\n\n## OCR Extraction: marker-pdf\n\n**Best for**: Scanned PDFs, image-only PDFs, or documents where `pymupdf` returns garbled text.\nInstall: `pip install marker-pdf` (~5 GB with models).\n\n```bash\n# Single file\nmarker_single document.pdf output_dir\u002F --batch_multiplier 2\n\n# Batch\nmarker input_dir\u002F output_dir\u002F --workers 4\n```\n\nOutputs Markdown with preserved headings, tables, and code blocks.\n\n**Decision signal**: Run `pymupdf` first. If extracted text has \u003C50% printable characters or looks like garbage, switch to `marker-pdf`.\n\n---\n\n## NLP Editing: nano-pdf\n\n**Best for**: Semantic search, sentence-level edits, keyword replacement in text-native PDFs.\nInstall: `pip install nano-pdf`.\n\n```python\nfrom nano_pdf import NanoPDF\n\ndoc = NanoPDF(\"document.pdf\")\n\n# Search sentences\nresults = doc.search(\"termination clause\", top_k=5)\nfor r in results:\n    print(r.page, r.text, r.score)\n\n# Replace text (produces new PDF)\ndoc.replace(\"old phrase\", \"new phrase\", output=\"modified.pdf\")\n```\n\n---\n\n## Python Libraries\n\n### pypdf - Basic Operations\n\n#### Merge PDFs\n```python\nfrom pypdf import PdfWriter, PdfReader\n\nwriter = PdfWriter()\nfor pdf_file in [\"doc1.pdf\", \"doc2.pdf\", \"doc3.pdf\"]:\n    reader = PdfReader(pdf_file)\n    for page in reader.pages:\n        writer.add_page(page)\n\nwith open(\"merged.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n#### Split PDF\n```python\nreader = PdfReader(\"input.pdf\")\nfor i, page in enumerate(reader.pages):\n    writer = PdfWriter()\n    writer.add_page(page)\n    with open(f\"page_{i+1}.pdf\", \"wb\") as output:\n        writer.write(output)\n```\n\n#### Extract Metadata\n```python\nreader = PdfReader(\"document.pdf\")\nmeta = reader.metadata\nprint(f\"Title: {meta.title}\")\nprint(f\"Author: {meta.author}\")\n```\n\n#### Rotate Pages\n```python\nreader = PdfReader(\"input.pdf\")\nwriter = PdfWriter()\npage = reader.pages[0]\npage.rotate(90)  # Rotate 90 degrees clockwise\nwriter.add_page(page)\nwith open(\"rotated.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n### pdfplumber - Text and Table Extraction\n\n#### Extract Text with Layout\n```python\nimport pdfplumber\n\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    for page in pdf.pages:\n        text = page.extract_text()\n        print(text)\n```\n\n#### Extract Tables\n```python\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    for i, page in enumerate(pdf.pages):\n        tables = page.extract_tables()\n        for j, table in enumerate(tables):\n            print(f\"Table {j+1} on page {i+1}:\")\n            for row in table:\n                print(row)\n```\n\n#### Advanced Table Extraction\n```python\nimport pandas as pd\n\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    all_tables = []\n    for page in pdf.pages:\n        tables = page.extract_tables()\n        for table in tables:\n            if table:\n                df = pd.DataFrame(table[1:], columns=table[0])\n                all_tables.append(df)\n\nif all_tables:\n    combined_df = pd.concat(all_tables, ignore_index=True)\n    combined_df.to_excel(\"extracted_tables.xlsx\", index=False)\n```\n\n### reportlab - Create PDFs\n\n#### Basic PDF Creation\n```python\nfrom reportlab.lib.pagesizes import letter\nfrom reportlab.pdfgen import canvas\n\nc = canvas.Canvas(\"hello.pdf\", pagesize=letter)\nwidth, height = letter\nc.drawString(100, height - 100, \"Hello World!\")\nc.line(100, height - 140, 400, height - 140)\nc.save()\n```\n\n#### Subscripts and Superscripts\n\n**IMPORTANT**: Never use Unicode subscript\u002Fsuperscript characters in ReportLab PDFs. The built-in fonts do not include these glyphs, causing them to render as solid black boxes.\n\nUse ReportLab's XML markup tags instead:\n```python\nfrom reportlab.platypus import Paragraph\nfrom reportlab.lib.styles import getSampleStyleSheet\nstyles = getSampleStyleSheet()\nchemical = Paragraph(\"H\u003Csub>2\u003C\u002Fsub>O\", styles['Normal'])\nsquared = Paragraph(\"x\u003Csuper>2\u003C\u002Fsuper> + y\u003Csuper>2\u003C\u002Fsuper>\", styles['Normal'])\n```\n\n## PDF Form Processing\n\n### Check if PDF has fillable fields\n```bash\npython scripts\u002Fcheck_fillable_fields.py document.pdf\n```\n\n### Extract form field info\n```bash\npython scripts\u002Fextract_form_field_info.py document.pdf\n```\n\n### Extract form structure (non-fillable PDFs)\n```bash\npython scripts\u002Fextract_form_structure.py document.pdf\n```\n\n### Fill form fields\n```bash\npython scripts\u002Ffill_fillable_fields.py document.pdf output.pdf --fields '{\"field_name\": \"value\"}'\n```\n\n### Fill with annotations (non-fillable PDFs)\n```bash\npython scripts\u002Ffill_pdf_form_with_annotations.py document.pdf output.pdf --data '{\"x,y\": \"text\"}'\n```\n\n### Validate bounding boxes\n```bash\npython scripts\u002Fcheck_bounding_boxes.py document.pdf\n```\n\n### Convert PDF to images\n```bash\npython scripts\u002Fconvert_pdf_to_images.py document.pdf output_dir\u002F --dpi 150\n```\n\n### Create validation image with overlays\n```bash\npython scripts\u002Fcreate_validation_image.py document.pdf output.png\n```\n\n## Command-Line Tools\n\n### pdftotext (poppler-utils)\n```bash\npdftotext input.pdf output.txt              # Extract text\npdftotext -layout input.pdf output.txt      # Preserve layout\npdftotext -f 1 -l 5 input.pdf output.txt   # Pages 1-5\n```\n\n### qpdf\n```bash\nqpdf --empty --pages file1.pdf file2.pdf -- merged.pdf     # Merge\nqpdf input.pdf --pages . 1-5 -- pages1-5.pdf               # Split\nqpdf input.pdf output.pdf --rotate=+90:1                    # Rotate\nqpdf --password=mypassword --decrypt encrypted.pdf out.pdf  # Decrypt\n```\n\n## Common Tasks\n\n### Extract Text from Scanned PDFs (OCR)\n```python\nimport pytesseract\nfrom pdf2image import convert_from_path\n\nimages = convert_from_path('scanned.pdf')\ntext = \"\"\nfor i, image in enumerate(images):\n    text += f\"Page {i+1}:\\n\"\n    text += pytesseract.image_to_string(image)\n    text += \"\\n\\n\"\n```\n\n### Add Watermark\n```python\nfrom pypdf import PdfReader, PdfWriter\n\nwatermark = PdfReader(\"watermark.pdf\").pages[0]\nreader = PdfReader(\"document.pdf\")\nwriter = PdfWriter()\n\nfor page in reader.pages:\n    page.merge_page(watermark)\n    writer.add_page(page)\n\nwith open(\"watermarked.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n### Password Protection\n```python\nfrom pypdf import PdfReader, PdfWriter\n\nreader = PdfReader(\"input.pdf\")\nwriter = PdfWriter()\nfor page in reader.pages:\n    writer.add_page(page)\nwriter.encrypt(\"userpassword\", \"ownerpassword\")\nwith open(\"encrypted.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n## Quick Reference\n\n| Task | Best Tool | Command\u002FCode |\n|------|-----------|--------------|\n| URL → text | web_extract | `web_extract(url=...)` |\n| Fast text extraction | pymupdf | `fitz.open(...).get_text()` |\n| Scanned \u002F OCR | marker-pdf | `marker_single doc.pdf out\u002F` |\n| Semantic search\u002Fedit | nano-pdf | `NanoPDF(...).search(...)` |\n| Merge PDFs | pypdf | `writer.add_page(page)` |\n| Split PDFs | pypdf | One page per file |\n| Extract text (layout) | pdfplumber | `page.extract_text()` |\n| Extract tables | pdfplumber | `page.extract_tables()` |\n| Create PDFs | reportlab | Canvas or Platypus |\n| Fill forms | scripts | `fill_fillable_fields.py` |\n","> **Important:** All `scripts\u002F` paths are relative to this skill directory.\n> Use `run_skill_script` tool to execute scripts, or run with: `cd {this_skill_dir} && python scripts\u002F...`\n\n# PDF Processing Guide\n\n## Prerequisites\n\n- **pypdf**: core PDF reading and writing\n- **pdfplumber**: text and table extraction\n- **reportlab**: PDF creation\n- **pdftotext** (poppler-utils): command-line text extraction\n- **pdftoppm** (poppler-utils): PDF-to-image conversion\n- **qpdf**: PDF manipulation (merge, split, rotate, decrypt)\n\n## Tool Selection Decision Table\n\nChoose the right approach before starting:\n\n| Input | Condition | Recommended Tool |\n|-------|-----------|-----------------|\n| URL | PDF accessible via URL | `web_extract(url)` — fastest, no download needed |\n| Local file | Text-native PDF (generated by software) | `pymupdf` — ~25 MB install, instant extraction |\n| Local file | Scanned\u002Fimage-only PDF (no selectable text) | `marker-pdf` — OCR with layout preservation (~5 GB, needs GPU or CPU) |\n| Local file | Form filling or page manipulation | `pypdf` \u002F `pdfplumber` + form scripts |\n| Local file | NLP editing or semantic search | `nano-pdf` — sentence-level operations |\n\n**URL-first rule**: If the user provides a URL, always try URL extraction first before downloading.\n\n## Overview\n\nThis guide covers essential PDF processing operations using Python libraries and command-line tools.\n\n## URL-First Extraction\n\nIf the user provides a URL pointing to a PDF, extract it without downloading:\n\n```\nweb_extract(url=\"https:\u002F\u002Fexample.com\u002Freport.pdf\")\n```\n\nFall back to download + local processing only if `web_extract` returns empty or errors.\n\n---\n\n## Fast Extraction: pymupdf (fitz)\n\n**Best for**: Text-native PDFs (digital, not scanned). Install: `pip install pymupdf` (~25 MB).\n\n```python\nimport fitz  # pymupdf\n\ndoc = fitz.open(\"document.pdf\")\nprint(f\"Pages: {doc.page_count}\")\n\n# Extract all text (fast)\nfull_text = \"\\n\".join(page.get_text() for page in doc)\n\n# Extract with layout blocks (tables, columns)\nfor page in doc:\n    blocks = page.get_text(\"blocks\")  # (x0,y0,x1,y1,text,block_no,block_type)\n    for block in blocks:\n        print(block[4])  # text content\n\n# Extract images\nfor page in doc:\n    for img in page.get_images():\n        xref = img[0]\n        base = doc.extract_image(xref)\n        with open(f\"img_{xref}.{base['ext']}\", \"wb\") as f:\n            f.write(base[\"image\"])\n```\n\npymupdf is 5-10× faster than pypdf for text extraction and preserves layout better.\n\n---\n\n## OCR Extraction: marker-pdf\n\n**Best for**: Scanned PDFs, image-only PDFs, or documents where `pymupdf` returns garbled text.\nInstall: `pip install marker-pdf` (~5 GB with models).\n\n```bash\n# Single file\nmarker_single document.pdf output_dir\u002F --batch_multiplier 2\n\n# Batch\nmarker input_dir\u002F output_dir\u002F --workers 4\n```\n\nOutputs Markdown with preserved headings, tables, and code blocks.\n\n**Decision signal**: Run `pymupdf` first. If extracted text has \u003C50% printable characters or looks like garbage, switch to `marker-pdf`.\n\n---\n\n## NLP Editing: nano-pdf\n\n**Best for**: Semantic search, sentence-level edits, keyword replacement in text-native PDFs.\nInstall: `pip install nano-pdf`.\n\n```python\nfrom nano_pdf import NanoPDF\n\ndoc = NanoPDF(\"document.pdf\")\n\n# Search sentences\nresults = doc.search(\"termination clause\", top_k=5)\nfor r in results:\n    print(r.page, r.text, r.score)\n\n# Replace text (produces new PDF)\ndoc.replace(\"old phrase\", \"new phrase\", output=\"modified.pdf\")\n```\n\n---\n\n## Python Libraries\n\n### pypdf - Basic Operations\n\n#### Merge PDFs\n```python\nfrom pypdf import PdfWriter, PdfReader\n\nwriter = PdfWriter()\nfor pdf_file in [\"doc1.pdf\", \"doc2.pdf\", \"doc3.pdf\"]:\n    reader = PdfReader(pdf_file)\n    for page in reader.pages:\n        writer.add_page(page)\n\nwith open(\"merged.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n#### Split PDF\n```python\nreader = PdfReader(\"input.pdf\")\nfor i, page in enumerate(reader.pages):\n    writer = PdfWriter()\n    writer.add_page(page)\n    with open(f\"page_{i+1}.pdf\", \"wb\") as output:\n        writer.write(output)\n```\n\n#### Extract Metadata\n```python\nreader = PdfReader(\"document.pdf\")\nmeta = reader.metadata\nprint(f\"Title: {meta.title}\")\nprint(f\"Author: {meta.author}\")\n```\n\n#### Rotate Pages\n```python\nreader = PdfReader(\"input.pdf\")\nwriter = PdfWriter()\npage = reader.pages[0]\npage.rotate(90)  # Rotate 90 degrees clockwise\nwriter.add_page(page)\nwith open(\"rotated.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n### pdfplumber - Text and Table Extraction\n\n#### Extract Text with Layout\n```python\nimport pdfplumber\n\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    for page in pdf.pages:\n        text = page.extract_text()\n        print(text)\n```\n\n#### Extract Tables\n```python\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    for i, page in enumerate(pdf.pages):\n        tables = page.extract_tables()\n        for j, table in enumerate(tables):\n            print(f\"Table {j+1} on page {i+1}:\")\n            for row in table:\n                print(row)\n```\n\n#### Advanced Table Extraction\n```python\nimport pandas as pd\n\nwith pdfplumber.open(\"document.pdf\") as pdf:\n    all_tables = []\n    for page in pdf.pages:\n        tables = page.extract_tables()\n        for table in tables:\n            if table:\n                df = pd.DataFrame(table[1:], columns=table[0])\n                all_tables.append(df)\n\nif all_tables:\n    combined_df = pd.concat(all_tables, ignore_index=True)\n    combined_df.to_excel(\"extracted_tables.xlsx\", index=False)\n```\n\n### reportlab - Create PDFs\n\n#### Basic PDF Creation\n```python\nfrom reportlab.lib.pagesizes import letter\nfrom reportlab.pdfgen import canvas\n\nc = canvas.Canvas(\"hello.pdf\", pagesize=letter)\nwidth, height = letter\nc.drawString(100, height - 100, \"Hello World!\")\nc.line(100, height - 140, 400, height - 140)\nc.save()\n```\n\n#### Subscripts and Superscripts\n\n**IMPORTANT**: Never use Unicode subscript\u002Fsuperscript characters in ReportLab PDFs. The built-in fonts do not include these glyphs, causing them to render as solid black boxes.\n\nUse ReportLab's XML markup tags instead:\n```python\nfrom reportlab.platypus import Paragraph\nfrom reportlab.lib.styles import getSampleStyleSheet\nstyles = getSampleStyleSheet()\nchemical = Paragraph(\"H\u003Csub>2\u003C\u002Fsub>O\", styles['Normal'])\nsquared = Paragraph(\"x\u003Csuper>2\u003C\u002Fsuper> + y\u003Csuper>2\u003C\u002Fsuper>\", styles['Normal'])\n```\n\n## PDF Form Processing\n\n### Check if PDF has fillable fields\n```bash\npython scripts\u002Fcheck_fillable_fields.py document.pdf\n```\n\n### Extract form field info\n```bash\npython scripts\u002Fextract_form_field_info.py document.pdf\n```\n\n### Extract form structure (non-fillable PDFs)\n```bash\npython scripts\u002Fextract_form_structure.py document.pdf\n```\n\n### Fill form fields\n```bash\npython scripts\u002Ffill_fillable_fields.py document.pdf output.pdf --fields '{\"field_name\": \"value\"}'\n```\n\n### Fill with annotations (non-fillable PDFs)\n```bash\npython scripts\u002Ffill_pdf_form_with_annotations.py document.pdf output.pdf --data '{\"x,y\": \"text\"}'\n```\n\n### Validate bounding boxes\n```bash\npython scripts\u002Fcheck_bounding_boxes.py document.pdf\n```\n\n### Convert PDF to images\n```bash\npython scripts\u002Fconvert_pdf_to_images.py document.pdf output_dir\u002F --dpi 150\n```\n\n### Create validation image with overlays\n```bash\npython scripts\u002Fcreate_validation_image.py document.pdf output.png\n```\n\n## Command-Line Tools\n\n### pdftotext (poppler-utils)\n```bash\npdftotext input.pdf output.txt              # Extract text\npdftotext -layout input.pdf output.txt      # Preserve layout\npdftotext -f 1 -l 5 input.pdf output.txt   # Pages 1-5\n```\n\n### qpdf\n```bash\nqpdf --empty --pages file1.pdf file2.pdf -- merged.pdf     # Merge\nqpdf input.pdf --pages . 1-5 -- pages1-5.pdf               # Split\nqpdf input.pdf output.pdf --rotate=+90:1                    # Rotate\nqpdf --password=mypassword --decrypt encrypted.pdf out.pdf  # Decrypt\n```\n\n## Common Tasks\n\n### Extract Text from Scanned PDFs (OCR)\n```python\nimport pytesseract\nfrom pdf2image import convert_from_path\n\nimages = convert_from_path('scanned.pdf')\ntext = \"\"\nfor i, image in enumerate(images):\n    text += f\"Page {i+1}:\\n\"\n    text += pytesseract.image_to_string(image)\n    text += \"\\n\\n\"\n```\n\n### Add Watermark\n```python\nfrom pypdf import PdfReader, PdfWriter\n\nwatermark = PdfReader(\"watermark.pdf\").pages[0]\nreader = PdfReader(\"document.pdf\")\nwriter = PdfWriter()\n\nfor page in reader.pages:\n    page.merge_page(watermark)\n    writer.add_page(page)\n\nwith open(\"watermarked.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n### Password Protection\n```python\nfrom pypdf import PdfReader, PdfWriter\n\nreader = PdfReader(\"input.pdf\")\nwriter = PdfWriter()\nfor page in reader.pages:\n    writer.add_page(page)\nwriter.encrypt(\"userpassword\", \"ownerpassword\")\nwith open(\"encrypted.pdf\", \"wb\") as output:\n    writer.write(output)\n```\n\n## Quick Reference\n\n| Task | Best Tool | Command\u002FCode |\n|------|-----------|--------------|\n| URL → text | web_extract | `web_extract(url=...)` |\n| Fast text extraction | pymupdf | `fitz.open(...).get_text()` |\n| Scanned \u002F OCR | marker-pdf | `marker_single doc.pdf out\u002F` |\n| Semantic search\u002Fedit | nano-pdf | `NanoPDF(...).search(...)` |\n| Merge PDFs | pypdf | `writer.add_page(page)` |\n| Split PDFs | pypdf | One page per file |\n| Extract text (layout) | pdfplumber | `page.extract_text()` |\n| Extract tables | pdfplumber | `page.extract_tables()` |\n| Create PDFs | reportlab | Canvas or Platypus |\n| Fill forms | scripts | `fill_fillable_fields.py` |\n",{"name":5,"platforms":53,"description":7,"dependencies":54},[47,46,45],{"tools":55,"commands":58},[56,57],"skillScriptTool","skillFileTool",[41],"dev","11106843d72d25b29c2cd08d7fdbbd222c21df6a","mateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf",361,"https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw","https:\u002F\u002Fclaw.mate.vip","https:\u002F\u002Fgithub.com\u002Fmateaix","2026-11-13 15:43:14",{"source":8,"skillName":5,"commands":68,"prompt":78,"zipAvailable":79},[69,72,75],{"tool":70,"command":71},"npx","npx skills add mateaix\u002Fmateclaw --skill pdf",{"tool":73,"command":74},"bunx","bunx skills add mateaix\u002Fmateclaw --skill pdf",{"tool":76,"command":77},"pnpm","pnpm dlx skills add mateaix\u002Fmateclaw --skill pdf","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002FSKILL.md",true,[81,87,92,96,102,106,110,114,118,122,126],{"path":82,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":85,"sourceHtmlUrl":86},"forms.md","REFERENCE","参考文档",12063,"https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002Fforms.md",{"path":88,"resourceType":89,"resourceTypeDesc":90,"sizeBytes":91,"sourceHtmlUrl":15},"LICENSE.txt","LICENSE","许可证",1467,{"path":93,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":94,"sourceHtmlUrl":95},"reference.md",16692,"https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002Freference.md",{"path":97,"resourceType":98,"resourceTypeDesc":99,"sizeBytes":100,"sourceHtmlUrl":101},"scripts\u002Fcheck_bounding_boxes.py","SCRIPT","脚本",2774,"https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002Fscripts\u002Fcheck_bounding_boxes.py",{"path":103,"resourceType":98,"resourceTypeDesc":99,"sizeBytes":104,"sourceHtmlUrl":105},"scripts\u002Fcheck_fillable_fields.py",268,"https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002Fscripts\u002Fcheck_fillable_fields.py",{"path":107,"resourceType":98,"resourceTypeDesc":99,"sizeBytes":108,"sourceHtmlUrl":109},"scripts\u002Fconvert_pdf_to_images.py",1008,"https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002Fscripts\u002Fconvert_pdf_to_images.py",{"path":111,"resourceType":98,"resourceTypeDesc":99,"sizeBytes":112,"sourceHtmlUrl":113},"scripts\u002Fcreate_validation_image.py",1258,"https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002Fscripts\u002Fcreate_validation_image.py",{"path":115,"resourceType":98,"resourceTypeDesc":99,"sizeBytes":116,"sourceHtmlUrl":117},"scripts\u002Fextract_form_field_info.py",4300,"https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002Fscripts\u002Fextract_form_field_info.py",{"path":119,"resourceType":98,"resourceTypeDesc":99,"sizeBytes":120,"sourceHtmlUrl":121},"scripts\u002Fextract_form_structure.py",3945,"https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002Fscripts\u002Fextract_form_structure.py",{"path":123,"resourceType":98,"resourceTypeDesc":99,"sizeBytes":124,"sourceHtmlUrl":125},"scripts\u002Ffill_fillable_fields.py",3819,"https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002Fscripts\u002Ffill_fillable_fields.py",{"path":127,"resourceType":98,"resourceTypeDesc":99,"sizeBytes":128,"sourceHtmlUrl":129},"scripts\u002Ffill_pdf_form_with_annotations.py",3235,"https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fpdf\u002Fscripts\u002Ffill_pdf_form_with_annotations.py",[131,144,173,199,226,245],{"skillNo":132,"name":133,"nameZh":6,"description":134,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":135,"licenseFileUrl":6,"sourceHtmlUrl":136,"categories":137,"keywords":139,"publishedAt":143},"01M6KW155AABG05Q3FR8CN3D9H","sample","Test fixture for SkillBundleMaterializer.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Ftest\u002Fresources\u002Ftest-bundles\u002Fsample\u002FSKILL.md",[138],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[133,140,141,142],"test","for","fixture","2026-11-10 10:12:30",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":135,"licenseFileUrl":6,"sourceHtmlUrl":148,"categories":149,"keywords":155,"publishedAt":143},"01M6KW0P1T4EGBRN0HYZKJSHGB","xhs_note","小红书图文创作 \u002F 笔记 \u002F 种草文案 (xiaohongshu \u002F red note) — 端到端：成文→配图(≥3 张竖版)→去AI化→在线预览打包交付。以图为主、文字辅助：标题四件套 + 碎句正文 + 话题标签，配 3:4 竖版卡片，最少 3 张图。honors user persona & style memory.","https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fxhs_note\u002FSKILL.md",[150],{"categoryNo":151,"categoryName":152,"taxonomyType":153,"taxonomyTypeDesc":154},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[156,157,158,159,160,161,162,40,163,164,165,166,167,168,169,170,46,171,45,47,172],"note","xhs note","xhs","创作","persona","memory","红书","red","图文","内容创作","style","小红书","笔记","xiaohongshu","去AI化","文案","文字",{"skillNo":174,"name":175,"nameZh":6,"description":176,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":135,"licenseFileUrl":6,"sourceHtmlUrl":177,"categories":178,"keywords":180,"publishedAt":143},"01M6KW0J69PPWSCVSR6JVJ0P1F","x_intel","Read X (Twitter) posts, search, timelines and user profiles via the official xurl CLI.","https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fx_intel\u002FSKILL.md",[179],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[181,182,183,184,185,186,187,188,189,190,46,191,192,193,194,195,196,197,198,47],"x intel","shell","xurl","execute","twitter","social-media","via","profiles","research","true","read","command","cli","social","search","official","Media","posts",{"skillNo":200,"name":201,"nameZh":6,"description":202,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":135,"licenseFileUrl":6,"sourceHtmlUrl":203,"categories":204,"keywords":213,"publishedAt":143},"01M6KW0DEPAYEF2JQ70PGN0Y8D","writing-plans","Write implementation plans: bite-sized tasks, paths, code.","https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fwriting-plans\u002FSKILL.md",[205,208,211,212],{"categoryNo":206,"categoryName":207,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":209,"categoryName":210,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":151,"categoryName":152,"taxonomyType":153,"taxonomyTypeDesc":154},[214,215,216,217,218,219,220,221,222,223,224,225],"plans","writing plans","writing","implementation","planning","paths","write","documentation","tasks","code","workflow","design",{"skillNo":227,"name":228,"nameZh":6,"description":229,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":135,"licenseFileUrl":6,"sourceHtmlUrl":230,"categories":231,"keywords":233,"publishedAt":143},"01M6KW08Q6EEN0ZSH5JRMAFH0B","webhook-subscriptions","Webhook subscriptions: event-driven agent runs.","https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Fwebhook-subscriptions\u002FSKILL.md",[232],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[234,235,236,237,238,239,240,241,242,243,244],"subscriptions","webhook subscriptions","webhook","event-driven","automation","event","integrations","push","events","notifications","driven",{"skillNo":246,"name":247,"nameZh":6,"description":248,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":135,"licenseFileUrl":6,"sourceHtmlUrl":249,"categories":250,"keywords":258,"publishedAt":143},"01M6KW04W8S4EMJHSNHY3HWAY3","test-driven-development","TDD: enforce RED-GREEN-REFACTOR, tests before code.","https:\u002F\u002Fgithub.com\u002Fmateaix\u002Fmateclaw\u002Fblob\u002Fdev\u002Fmateclaw-server\u002Fsrc\u002Fmain\u002Fresources\u002Fskills\u002Ftest-driven-development\u002FSKILL.md",[251,254,257],{"categoryNo":252,"categoryName":253,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":255,"categoryName":256,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[259,140,244,260,261,163,262,263,264,265,223,266,267,268],"development","test driven development","quality","tdd","tests","enforce","refactor","testing","red-green-refactor","green"]