office-docs
Office document ingestion for RAG: DOCX (python-docx, mammoth to markdown), PPTX (python-pptx with image extraction), XLSX (openpyxl, pandas, table-aware chunking), plus Notion/Confluence/Quip export to markdown. Preserves headings, lists, comments, and embedded images. USE WHEN: user mentions "DOCX", "Word document", "python-docx", "mammoth", "PPTX", "PowerPoint", "python-pptx", "XLSX", "Excel", "openpyxl", "spreadsheet", "Notion export", "Confluence export", "Quip export", "office documents" DO NOT USE FOR: generic multi-format partitioning - use `unstructured-io`; PDF exports of office docs - use `pdf-extraction`; structured markdown vaults - use `markdown-structured`; emails with office attachments (handle extraction here, ingestion via `email-ingestion`)
What this skill does
# Office Documents for RAG
## Format Matrix
| Format | Library | Markdown Path | Tables | Images | Comments |
|--------|---------|---------------|--------|--------|----------|
| DOCX | python-docx | mammoth | Yes | python-docx `InlineShape` | python-docx |
| PPTX | python-pptx | custom | Limited | `shape.image.blob` | `slide.notes_slide` |
| XLSX | openpyxl / pandas | custom | Native | Embedded images | openpyxl |
| Notion | Notion API + notion-to-md | Native | Yes | Block downloads | Discussion blocks |
| Confluence | atlassian-python-api | html2md | Yes | Attachments endpoint | Inline comments API |
| Quip | Quip API | html2md | Yes | Blob endpoint | Section comments |
## DOCX — python-docx + mammoth
```python
# Structured extraction with python-docx
from docx import Document
from docx.oxml.ns import qn
def extract_docx(path: str) -> list[dict]:
doc = Document(path)
out = []
heading_stack: list[str] = []
for para in doc.paragraphs:
style = (para.style.name or "").lower()
text = para.text.strip()
if not text:
continue
if style.startswith("heading"):
try:
level = int(style.split()[-1])
except ValueError:
level = 1
heading_stack = heading_stack[: level - 1] + [text]
out.append({"type": "heading", "level": level, "text": text,
"path": list(heading_stack)})
elif style == "list paragraph":
out.append({"type": "list_item", "text": text,
"path": list(heading_stack)})
else:
out.append({"type": "paragraph", "text": text,
"path": list(heading_stack)})
# Tables
for t_idx, table in enumerate(doc.tables):
rows = [[cell.text.strip() for cell in row.cells] for row in table.rows]
out.append({"type": "table", "index": t_idx, "rows": rows,
"path": list(heading_stack)})
return out
```
### DOCX to Markdown with Mammoth
```python
import mammoth
with open("brief.docx", "rb") as f:
result = mammoth.convert_to_markdown(
f,
style_map="""
p[style-name='Heading 1'] => h1:fresh
p[style-name='Heading 2'] => h2:fresh
p[style-name='Quote'] => blockquote:fresh
r[style-name='Code'] => code
""",
convert_image=mammoth.images.img_element(lambda img: {
"src": save_image(img),
}),
)
markdown = result.value
for message in result.messages:
print("mammoth:", message.type, message.message)
```
### Comments and Revisions
```python
from docx.oxml.ns import qn
def extract_comments(path: str) -> list[dict]:
doc = Document(path)
comments_part = doc.part.package.part_related_by_reltype(
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"
)
xml = comments_part.blob
from lxml import etree
tree = etree.fromstring(xml)
out = []
for c in tree.findall(qn("w:comment")):
out.append({
"id": c.get(qn("w:id")),
"author": c.get(qn("w:author")),
"date": c.get(qn("w:date")),
"text": " ".join(t.text or "" for t in c.iter(qn("w:t"))),
})
return out
# Tracked changes: look for w:ins (insertion) and w:del (deletion) elements
```
### Embedded Images from DOCX
```python
from pathlib import Path
def extract_docx_images(path: str, out_dir: str):
doc = Document(path)
Path(out_dir).mkdir(parents=True, exist_ok=True)
for rel in doc.part.rels.values():
if "image" in rel.reltype:
blob = rel.target_part.blob
ext = rel.target_part.partname.split(".")[-1]
(Path(out_dir) / f"{rel.rId}.{ext}").write_bytes(blob)
```
## PPTX — Slide to Markdown
```python
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE
from pathlib import Path
def pptx_to_markdown(path: str, image_dir: str) -> list[dict]:
Path(image_dir).mkdir(parents=True, exist_ok=True)
prs = Presentation(path)
slides = []
for i, slide in enumerate(prs.slides, start=1):
parts: list[str] = []
title = ""
for shape in slide.shapes:
if shape.has_text_frame:
for para in shape.text_frame.paragraphs:
txt = " ".join(run.text for run in para.runs).strip()
if not txt:
continue
if shape == slide.shapes.title and not title:
title = txt
parts.append(f"# {txt}")
else:
bullet = "- " if para.level > 0 else ""
parts.append(f"{' ' * para.level}{bullet}{txt}")
if shape.shape_type == MSO_SHAPE_TYPE.PICTURE:
img = shape.image
name = f"slide{i}_{shape.shape_id}.{img.ext}"
(Path(image_dir) / name).write_bytes(img.blob)
parts.append(f"")
notes = ""
if slide.has_notes_slide:
notes = slide.notes_slide.notes_text_frame.text.strip()
slides.append({
"slide": i,
"title": title,
"markdown": "\n\n".join(parts),
"notes": notes,
})
return slides
```
## XLSX — Table-Aware Chunking
```python
import openpyxl
import pandas as pd
from dataclasses import dataclass
@dataclass
class SheetChunk:
sheet: str
range: str
markdown: str
row_start: int
row_end: int
def xlsx_to_chunks(path: str, rows_per_chunk: int = 50) -> list[SheetChunk]:
wb = openpyxl.load_workbook(path, data_only=True, read_only=True)
out: list[SheetChunk] = []
for sheet_name in wb.sheetnames:
df = pd.read_excel(path, sheet_name=sheet_name, header=0)
if df.empty:
continue
# Split by logical blocks of rows, keep header in each chunk
for start in range(0, len(df), rows_per_chunk):
end = min(start + rows_per_chunk, len(df))
slice_df = df.iloc[start:end]
md = slice_df.to_markdown(index=False)
out.append(SheetChunk(
sheet=sheet_name,
range=f"{sheet_name}!A{start+2}:{end+1}",
markdown=md,
row_start=start + 2,
row_end=end + 1,
))
return out
```
### Cell Comments + Embedded Images
```python
import openpyxl
wb = openpyxl.load_workbook("data.xlsx")
for ws in wb.worksheets:
for row in ws.iter_rows():
for cell in row:
if cell.comment:
print(ws.title, cell.coordinate,
cell.comment.author, cell.comment.text)
for img in ws._images: # openpyxl internal list
print(ws.title, img.anchor._from.col, img.anchor._from.row, img.ref)
```
### Preserve Formulas and Formats
```python
wb_formulas = openpyxl.load_workbook("data.xlsx", data_only=False)
wb_values = openpyxl.load_workbook("data.xlsx", data_only=True)
for fsheet, vsheet in zip(wb_formulas.worksheets, wb_values.worksheets):
for fcell, vcell in zip(fsheet["A1:D10"], vsheet["A1:D10"]):
for fc, vc in zip(fcell, vcell):
if fc.data_type == "f":
print(fc.coordinate, "formula:", fc.value, "value:", vc.value)
```
## Notion Export to Markdown
```python
import os
from notion_client import Client
from notion_to_md import NotionToMarkdown # notion-to-md-py
notion = Client(auth=os.environ["NOTION_TOKEN"])
n2m = NotionToMarkdown(notion_client=notion)
def export_page(page_id: str) -> str:
blocks = n2m.page_to_markdown(page_id)
return n2m.to_markdown_string(blocks)["parent"]
# Walk a database
db = notion.databases.query(database_id=os.environ["NOTION_DB"])
for page in db["results"]:
md = export_page(page["id"])
save_chunk(page["id"], md)
```
## Confluence Export
```python
from atlassiRelated in Image & Video
watch
IncludedWatch a video (URL or local path). Downloads with yt-dlp, extracts auto-scaled frames with ffmpeg, pulls the transcript from captions (or Whisper API fallback), and hands the result to Claude so it can answer questions about what's in the video.
physical-ai-defect-image-generation
IncludedUse when the user wants to orchestrate defect image generation, run associated setup, or handle outputs on OSMO. The Day 0 path handles cold-start with USD-to-ROI, image-edit augmentation, and AnomalyGen to create initial PCBA datasets. The Day 1 path performs inference and labeling on real images. This skill helps with first-time asset setup, creation of finetuning checkpoints, and configuring deployment. Trigger keywords: defect image generation, dig workflow, dig pipeline, defect image detection workflow, aoi pipeline, aoi anomalygen, usd2roi anomalygen, day 0 pcba, day 1 pcba, day 1 real-photo alignment, day 1 manual roi, metal surface anomaly, glass defect, anomalygen finetune, setup_pcb, setup_metal, setup_glass, setup_pretrained, dig setup, dig datasets, dig pretrained checkpoint, dig image-edit endpoint.
accelint-react-best-practices
IncludedReact performance optimization and best practices. ALWAYS use this skill when working with any React code - writing components, hooks, JSX; refactoring; optimizing re-renders, memoization, state management; reviewing for performance; fixing hydration mismatches; debugging infinite re-renders, stale closures, input focus loss, animations restarting; preventing remounting; implementing transitions, lazy initialization, effect dependencies. Even simple React tasks benefit from these patterns. Covers React 19+ (useEffectEvent, Activity, ref props). Triggers - useEffect, useState, useMemo, useCallback, memo, inline components, nested components, components inside components, re-render, performance, hydration, SSR, Next.js, useDeferredValue, combined hooks.
elevenlabs-agents
IncludedBuild conversational AI voice agents with ElevenLabs Platform using React, JavaScript, React Native, or Swift SDKs. Configure agents, tools (client/server/MCP), RAG knowledge bases, multi-voice, and Scribe real-time STT. Use when: building voice chat interfaces, implementing AI phone agents with Twilio, configuring agent workflows or tools, adding RAG knowledge bases, testing with CLI "agents as code", or troubleshooting deprecated @11labs packages, Android audio cutoff, CSP violations, dynamic variables, or WebRTC config. Keywords: ElevenLabs Agents, ElevenLabs voice agents, AI voice agents, conversational AI, @elevenlabs/react, @elevenlabs/client, @elevenlabs/react-native, @elevenlabs/elevenlabs-js, @elevenlabs/agents-cli, elevenlabs SDK, voice AI, TTS, text-to-speech, ASR, speech recognition, turn-taking model, WebRTC voice, WebSocket voice, ElevenLabs conversation, agent system prompt, agent tools, agent knowledge base, RAG voice agents, multi-voice agents, pronunciation dictionary, voice speed control, elevenlabs scribe, @11labs deprecated, Android audio cutoff, CSP violation elevenlabs, dynamic variables elevenlabs, case-sensitive tool names, webhook authentication
humanizer
IncludedHumanize AI-generated text by detecting and removing patterns typical of LLM output. Rewrites text to sound natural, specific, and human. Uses 28 pattern detectors, 560+ AI vocabulary terms across 3 tiers, and statistical analysis (burstiness, type-token ratio, readability) for comprehensive detection. Use when asked to humanize text, de-AI writing, make content sound more natural/human, review writing for AI patterns, score text for AI detection, or improve AI-generated drafts. Covers content, language, style, communication, and filler categories.
generating-mermaid-diagrams
IncludedSalesforce architecture diagrams using Mermaid with ASCII fallback. Use this skill when generating text-based diagrams for Salesforce architecture, OAuth flows, ERDs, integration sequences, or Agentforce structure. TRIGGER when: user says "diagram", "visualize", "ERD", or asks for sequence diagrams, flowcharts, class diagrams, or architecture visualizations in Mermaid. DO NOT TRIGGER when: user wants PNG/SVG image output (use generating-visual-diagrams), or asks about non-Salesforce systems.