Communitygithub.com

kyopark2014/strands-skills

Mostra como usar habilidades de agente no Strands SDK

O que é strands-skills?

Esta skill de agente fornece um guia abrangente para processamento de PDFs usando bibliotecas Python como reportlab, pypdf e pdfplumber, com foco especial na geração de PDFs que contenham texto em coreano. Ela documenta passo a passo como registrar fontes coreanas (TTF ou CID), criar novos PDFs com texto simples ou tabelas, extrair texto e tabelas de PDFs existentes, mesclar, dividir, rotacionar e proteger arquivos PDF com senha. A skill é útil para desenvolvedores que precisam automatizar a criação e manipulação de documentos PDF em projetos de software, especialmente em contextos multilíngues que exigem suporte a caracteres coreanos. Ela funciona em qualquer ambiente Python com as bibliotecas instaladas e orienta o uso da ferramenta `execute_code` para executar os códigos de exemplo, salvando todos os arquivos gerados no diretório `artifacts/`.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add kyopark2014/strands-skills

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Guia de Processamento de PDF

Visão Geral

Este guia aborda operações essenciais de processamento de PDF usando bibliotecas Python. Use a ferramenta execute_code para executar o código Python mostrado abaixo. Todos os arquivos gerados devem ser salvos no diretório artifacts/.

Configuração de Fonte Coreana (Obrigatória — Incluir em todo código de criação de PDF)

Ao criar PDFs com texto em coreano, é obrigatório registrar uma fonte coreana. Inclua o código de registro de fonte abaixo no início de todo código de criação de PDF.

Importante: O AppleSDGothicNeo.ttc do macOS possui outlines PostScript e não pode ser usado com reportlab.

Prioridade de fontes:

  1. assets/NanumGothic-Regular.ttf (arquivo TTF — mais confiável)
  2. Fonte CID HYGothic-Medium (embutida no reportlab — não requer arquivo adicional, fallback seguro)
import os
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.cidfonts import UnicodeCIDFont

def register_korean_font():
    """Registra uma fonte coreana e retorna o nome da fonte. Deve ser chamado antes da criação do PDF."""
    # 1ª opção: NanumGothic TTF
    ttf_paths = [
        os.path.join("assets", "NanumGothic-Regular.ttf"),
        "/usr/share/fonts/truetype/nanum/NanumGothic.ttf",
        "/usr/share/fonts/nanum/NanumGothic.ttf",
        "/Library/Fonts/NanumGothic.ttf",
    ]
    for path in ttf_paths:
        if os.path.exists(path):
            try:
                pdfmetrics.registerFont(TTFont("KoreanFont", path))
                return "KoreanFont"
            except Exception:
                continue

    # 2ª opção: Fonte CID (embutida no reportlab, sem arquivo adicional)
    try:
        pdfmetrics.registerFont(UnicodeCIDFont("HYGothic-Medium"))
        return "HYGothic-Medium"
    except Exception:
        pass

    return "Helvetica"  # Fallback final (sem suporte a coreano)

font_name = register_korean_font()

Criando Novos PDFs (reportlab)

Criação Básica de PDF (somente inglês)

from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
import os

os.makedirs("artifacts", exist_ok=True)
c = canvas.Canvas("artifacts/hello.pdf", pagesize=A4)
width, height = A4
c.drawString(100, height - 100, "Hello World!")
c.save()

Criação de PDF com Coreano (padrão recomendado)

import os
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.cidfonts import UnicodeCIDFont

# 1) Registrar fonte coreana
font_name = "Helvetica"
for path in [os.path.join("assets", "NanumGothic-Regular.ttf"),
             "/usr/share/fonts/truetype/nanum/NanumGothic.ttf"]:
    if os.path.exists(path):
        try:
            pdfmetrics.registerFont(TTFont("KoreanFont", path))
            font_name = "KoreanFont"
            break
        except Exception:
            continue
if font_name == "Helvetica":
    try:
        pdfmetrics.registerFont(UnicodeCIDFont("HYGothic-Medium"))
        font_name = "HYGothic-Medium"
    except Exception:
        pass

# 2) Definir estilos para coreano
styles = getSampleStyleSheet()
styles.add(ParagraphStyle("Title_KO",   parent=styles["Title"],    fontName=font_name, fontSize=20, spaceAfter=20, textColor=colors.HexColor("#1a1a2e")))
styles.add(ParagraphStyle("H1_KO",      parent=styles["Heading1"], fontName=font_name, fontSize=16, spaceAfter=14, textColor=colors.HexColor("#16213e")))
styles.add(ParagraphStyle("H2_KO",      parent=styles["Heading2"], fontName=font_name, fontSize=14, spaceAfter=12, textColor=colors.HexColor("#0f3460")))
styles.add(ParagraphStyle("Normal_KO",  parent=styles["Normal"],   fontName=font_name, fontSize=10, leading=14, spaceAfter=8))
styles.add(ParagraphStyle("Bullet_KO",  parent=styles["Normal"],   fontName=font_name, fontSize=10, leading=14, leftIndent=20, bulletIndent=10))

# 3) Construir PDF
os.makedirs("artifacts", exist_ok=True)
doc = SimpleDocTemplate("artifacts/report.pdf", pagesize=A4,
    topMargin=0.8*inch, bottomMargin=0.8*inch, leftMargin=0.75*inch, rightMargin=0.75*inch)

story = []
story.append(Paragraph("Título do Relatório", styles["Title_KO"]))
story.append(Spacer(1, 16))
story.append(Paragraph("1. Visão Geral", styles["H1_KO"]))
story.append(Paragraph("Este relatório contém conteúdo de exemplo.", styles["Normal_KO"]))
story.append(Spacer(1, 8))
story.append(Paragraph("2. Detalhes", styles["H1_KO"]))
story.append(Paragraph("• Primeiro item", styles["Bullet_KO"]))
story.append(Paragraph("• Segundo item", styles["Bullet_KO"]))
story.append(PageBreak())
story.append(Paragraph("3. Apêndice", styles["H1_KO"]))
story.append(Paragraph("Conteúdo adicional.", styles["Normal_KO"]))

doc.build(story)
print("PDF criado: artifacts/report.pdf")

PDF com Tabela em Coreano

import os
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.cidfonts import UnicodeCIDFont

# Registrar fonte
font_name = "Helvetica"
for path in [os.path.join("assets", "NanumGothic-Regular.ttf"),
             "/usr/share/fonts/truetype/nanum/NanumGothic.ttf"]:
    if os.path.exists(path):
        try:
            pdfmetrics.registerFont(TTFont("KoreanFont", path))
            font_name = "KoreanFont"
            break
        except Exception:
            continue
if font_name == "Helvetica":
    try:
        pdfmetrics.registerFont(UnicodeCIDFont("HYGothic-Medium"))
        font_name = "HYGothic-Medium"
    except Exception:
        pass

styles = getSampleStyleSheet()
styles.add(ParagraphStyle("Title_KO",  parent=styles["Title"],  fontName=font_name, fontSize=18, textColor=colors.HexColor("#1a1a2e")))
styles.add(ParagraphStyle("Normal_KO", parent=styles["Normal"], fontName=font_name, fontSize=10))

os.makedirs("artifacts", exist_ok=True)
doc = SimpleDocTemplate("artifacts/table_report.pdf", pagesize=A4)

data = [
    ["Item", "Descrição", "Custo"],
    ["Servidor", "Instância EC2", "$120"],
    ["Armazenamento", "Bucket S3", "$45"],
    ["Banco de Dados", "RDS PostgreSQL", "$89"],
]
table = Table(data, colWidths=[120, 200, 80])
table.setStyle(TableStyle([
    ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#e8eaf6")),
    ("TEXTCOLOR", (0, 0), (-1, 0), colors.HexColor("#1a1a2e")),
    ("FONTNAME", (0, 0), (-1, -1), font_name),
    ("FONTSIZE", (0, 0), (-1, -1), 10),
    ("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#bdbdbd")),
    ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
    ("TOPPADDING", (0, 0), (-1, -1), 6),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 6),
]))

doc.build([
    Paragraph("Relatório de Análise de Custos", styles["Title_KO"]),
    Spacer(1, 16),
    table
])
print("PDF criado: artifacts/table_report.pdf")

Notas Importantes sobre reportlab

  • Ao usar texto em coreano, inclua obrigatoriamente o código de registro de fonte acima.
  • O AppleSDGothicNeo.ttc do macOS possui outlines PostScript e não pode ser usado com reportlab. Nunca o utilize.
  • Se a fonte TTF (assets/NanumGothic-Regular.ttf) não estiver disponível, use a fonte CID HYGothic-Medium.
  • Se a fonte não for registrada, o texto coreano aparecerá quebrado ou como quadrados vazios (□).
  • NUNCA use caracteres Unicode de subscrito/sobrescrito (₀₁₂₃₄₅₆₇₈₉) em PDFs do ReportLab — use as tags <sub> e <super>.

Lendo PDFs (pypdf)

Extrair Texto

from pypdf import PdfReader

reader = PdfReader("input.pdf")
text = ""
for page in reader.pages:
    text += page.extract_text()
print(text)

Mesclar PDFs

from pypdf import PdfWriter, PdfReader

writer = PdfWriter()
for pdf_file in ["doc1.pdf", "doc2.pdf"]:
    reader = PdfReader(pdf_file)
    for page in reader.pages:
        writer.add_page(page)

with open("artifacts/merged.pdf", "wb") as output:
    writer.write(output)

Dividir PDF

from pypdf import PdfReader, PdfWriter

reader = PdfReader("input.pdf")
for i, page in enumerate(reader.pages):
    writer = PdfWriter()
    writer.add_page(page)
    with open(f"artifacts/page_{i+1}.pdf", "wb") as output:
        writer.write(output)

Rotacionar Páginas

from pypdf import PdfReader, PdfWriter

reader = PdfReader("input.pdf")
writer = PdfWriter()
page = reader.pages[0]
page.rotate(90)
writer.add_page(page)

with open("artifacts/rotated.pdf", "wb") as output:
    writer.write(output)

Proteção com Senha

from pypdf import PdfReader, PdfWriter

reader = PdfReader("input.pdf")
writer = PdfWriter()
for page in reader.pages:
    writer.add_page(page)
writer.encrypt("userpassword", "ownerpassword")

with open("artifacts/encrypted.pdf", "wb") as output:
    writer.write(output)

Extração de Tabelas (pdfplumber)

import pdfplumber

with pdfplumber.open("input.pdf") as pdf:
    for page in pdf.pages:
        text = page.extract_text()
        tables = page.extract_tables()
        for table in tables:
            for row in table:
                print(row)

Referência Rápida

TarefaBibliotecaFunção Principal
Criar PDFreportlabSimpleDocTemplate / canvas
Ler/Mesclar/Dividir PDFpypdfPdfReader / PdfWriter
Extrair tabelaspdfplumberpage.extract_tables()
Proteger com senhapypdfwriter.encrypt()
Rotacionar páginaspypdfpage.rotate()

Habilidades Relacionadas