Communitygithub.com

asadeisa/arabic-office-skills

Habilidades de agente para geração correta de saída em árabe/RTL em PDF, Word e PowerPoint — com visualização PNG para verificação visual

O que é arabic-office-skills?

Este conjunto de habilidades resolve problemas complexos de renderização de texto em árabe e outras línguas da direita para a esquerda (RTL) em documentos PDF, Word e PowerPoint. O foco principal é a geração de PDFs com a biblioteca ReportLab, que não possui suporte nativo para texto bidirecional (bidi), resultando em caracteres desconectados, palavras invertidas e parágrafos embaralhados. A habilidade fornece um construtor `ArabicPDF` que integra as bibliotecas `arabic-reshaper` e `python-bidi` para aplicar as transformações corretas de forma e ordem visual, além de incluir funções de visualização com `pypdfium2` para verificação visual obrigatória, já que a extração de texto não detecta esses defeitos. O documento SKILL.md detalha oito mecanismos essenciais para a correção, como quebra de linha manual, espelhamento de caracteres e isolamento de termos latinos. A habilidade também estabelece um limite claro: para Word e PowerPoint, o texto deve ser passado em ordem lógica bruta, sem pré-formatação, utilizando as habilidades `arabic-docx` e `arabic-pptx` separadas. Além disso, oferece orientações sobre fontes, numeração arábico-indiana e boas práticas de redação formal em árabe para evitar que o texto gerado pareça artificial. Suporta as plataformas Claude Code, Cursor e Codex, e é essencial para desenvolvedores que precisam gerar documentos técnicos ou oficiais em árabe, persa, urdu ou hebraico.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add asadeisa/arabic-office-skills

Perguntar na sua IA favorita

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

Documentação

Geração de PDF em Árabe / RTL

O código ReportLab ingênuo produz árabe que está sutil e completamente errado: letras aparecem desconectadas, palavras dentro de uma linha correm para trás e linhas dentro de um parágrafo trocam de lugar. Nada disso é visível no texto extraído — apenas na renderização. Esta habilidade agrupa um construtor que já resolve esses problemas.

Use scripts/arabic_pdf.py em vez de escrever lógica de reformatação do zero. Cada modo de falha abaixo foi encontrado ao testá-lo em um documento real.

Dependências

pip install reportlab arabic-reshaper python-bidi pypdfium2

pypdfium2 é usado apenas para visualização, mas a visualização não é opcional — veja Verificação abaixo.

Construindo um documento

Importe o construtor copiando scripts/arabic_pdf.py para o diretório do seu script de geração, ou adicionando a pasta scripts/ desta habilidade ao sys.path:

import pathlib, sys
sys.path.insert(0, str(pathlib.Path.home() / ".claude" / "skills" / "arabic-pdf" / "scripts"))
from arabic_pdf import ArabicPDF, preview

pdf = ArabicPDF("relatorio.pdf", doc_title="عنوان المستند", page_numbers=True)

pdf.title("عنوان المستند")
pdf.subtitle("سطر فرعي")

pdf.heading("أولاً — المقدمة")
pdf.para("فقرة عربية تتضمن مصطلحات لاتينية مثل PostgreSQL و FastAPI.")

pdf.heading("ثانياً — جدول")
pdf.table(
    ["البند", "التفصيل"],                     # primeira coluna à direita
    [["الواجهة الخلفية", "Python — FastAPI"],
     ["قاعدة البيانات", "PostgreSQL — SQLAlchemy"]],
    [5.0, 11.0],                              # larguras das colunas em cm
)

pdf.bullets(["نقطة أولى", "نقطة ثانية"])
pdf.save()

preview("relatorio.pdf")     # um PNG por página

Ajuste o caminho se a habilidade estiver em outro local — nada mais no construtor depende de onde está instalado.

Os métodos encadeiam, então pdf.heading(...).para(...) também funciona.

MétodoPropósito
title / subtitleCabeçalho centralizado do documento
headingTítulo de seção em negrito, alinhado à direita
paraParágrafo de corpo
bullets(items, marker="–")Uma linha alinhada à direita por item
table(header, rows, widths_cm)Tabela RTL; ordem de leitura natural na entrada, colunas invertidas na saída
spacer(pts) / page_break()Controle de layout
save()Escreve o arquivo, retorna o caminho

O texto de células e parágrafos pode conter \n para forçar uma quebra de linha.

Verificação — sempre renderize e olhe

Após save(), chame preview() e veja os PNGs com a ferramenta de Leitura. A extração de texto não consegue capturar defeitos RTL, porque os caracteres estão todos presentes e corretos; apenas sua ordem e forma estão errados. Verifique especificamente:

  • A primeira palavra de cada parágrafo está no canto superior direito?
  • Os termos latinos (PostgreSQL, FastAPI) estão onde devem estar no meio da frase, em vez de pular para a extrema esquerda da linha?
  • As letras estão unidas ou separadas como ا ل س ل ا م?
  • Alguma caixa preta sólida? A fonte não possui esses glifos — escolha outra.
  • Os parênteses estão na direção correta — (20 فأكثر) não )20 فأكثر(?
  • Pares dentro de termos latinos estão intactos — Array<String>, DECIMAL(5,2)?
  • Alguma linha de tabela foi órfã para a próxima página?

Corrigir um defeito que você nunca procurou custa muito mais tarde, quando o documento já está com seu destinatário.

Como a correção é alcançada

Útil ao adaptar o construtor ou depurar um documento incomum.

  1. Formatação — arabic_reshaper mapeia caracteres para formas de apresentação posicionais para que as letras se conectem.
  2. Bidi com uma direção base explícita — get_display(..., base_dir="R"). Sem base_dir, a direção é inferida a partir do primeiro caractere forte, então uma linha começando com uma palavra latina é disposta da esquerda para a direita e o árabe após ela fica errado. Esta é a causa mais comum de "quase certo, mas algumas linhas estão embaralhadas".
  3. Quebra de linha manual — o texto reformatado está em ordem visual. Se o reportlab o quebrar, as palavras que ele empurra para a próxima linha são as logicamente primeiras, então as linhas saem embaralhadas. O construtor quebra primeiro, reformata cada linha separadamente e as une com <br/> para que o reportlab nunca requeibre. Uma margem de segurança de 8pt cobre diferenças de medição; uma linha que transborda por um ponto é suficiente para invertê-la.
  4. Espelhamento — get_display reordena, mas nunca aplica a regra bidi L4, que diz que um caractere espelhado disposto da direita para a esquerda é desenhado como seu parceiro. Sem ela, (20 فأكثر) retorna com os dois parênteses em posições trocadas e seus glifos originais, e imprime )20 فأكثر(. O prepare() os substitui primeiro, para que a reordenação mova o glifo correto.
  5. Ilhas latinas — < e > são espelhados, mas não são colchetes pareados do Unicode, portanto a regra que mantém DECIMAL(5,2) unido não os cobre; o > de Array<String> assume a direção do árabe após ele e é jogado para o lado oposto. Cada trecho latino é envolvido em LRI…PDI e os isolados são removidos novamente após a reordenação, para que nada invisível chegue ao PDF.
  6. Escapamento após a formatação — o reportlab precisa que &, <, > sejam escapados, mas escapar primeiro envia &lt; através da passagem bidi como quatro caracteres e seu ; final é ejetado para o lado oposto da linha. Formate, depois escape.
  7. Colunas de tabela invertidas — o reportlab dispõe as colunas da esquerda para a direita, então o construtor as inverte, permitindo que você passe as colunas na ordem de leitura natural.
  8. KeepTogether em tabelas — evita que uma linha solitária fique em uma nova página.

Os pontos 4–6 são da mesma classe de defeito que as execuções de colchetes divididas descritas em arabic-docx, alcançadas pela direção oposta: lá um par não deve ser dividido entre as execuções, aqui um par não deve ser meio-espelhado. Qualquer caractere espelhado deve ser resolvido junto com seu parceiro.

Fontes

register_fonts() procura por uma fonte compatível com árabe: Arial, depois Tahoma no Windows, Arial no macOS, Noto Naskh Arabic, depois DejaVu Sans no Linux. Para usar uma face específica (Amiri e Cairo são adequadas para documentos formais):

from arabic_pdf import register_fonts
register_fonts("/caminho/Amiri-Regular.ttf", "/caminho/Amiri-Bold.ttf")   # antes de ArabicPDF(...)

As fontes internas do Reportlab não têm cobertura de árabe, portanto uma TTF deve ser registrada — é por isso que uma fonte ausente aparece como caixas pretas em vez de um erro.

Nunca leve esta abordagem para o Word ou PowerPoint

Este é o limite mais importante em toda a família de habilidades RTL.

reportlab / PillowWord / PowerPoint
Mecanismo de textonenhummecanismo bidirecional completo
Esperaglifos finais em ordem visualUnicode bruto em ordem lógica
Técnicareformatar + bidi + quebra manualflags de direção no XML

A pré-formatação é necessária aqui e destrutiva lá: Word e PowerPoint formatam no momento da renderização, portanto fornecer a eles formas de apresentação faz com que formatem uma segunda vez — glifos quebrados e texto que não pode mais ser pesquisado, copiado ou verificado ortograficamente. As duas abordagens são opostas, não variações.

Use arabic-docx para .docx e arabic-pptx para .pptx. Não transporte código entre os três sem reler por que eles diferem.

Notas

  • arabic_digits("38") → "٣٨" quando numerais arábico-indianos são desejados. Puramente cosmético; os dígitos ocidentais são perfeitamente normais na escrita técnica árabe.
  • Mantenha a formatação contida por padrão — texto preto, linhas finas. Documentos acadêmicos e oficiais em árabe são lidos como mais credíveis dessa forma, e usuários pedindo "simples" querem dizer isso.
  • O mesmo mecanismo lida com persa, urdu e hebraico; apenas a fonte precisa cobrir o script.

O que faz o árabe gerado parecer gerado

Não o vocabulário — os acréscimos. Cada hábito abaixo diz ao leitor algo sobre como o documento foi escrito, em vez de sobre seu assunto, e um leitor editando manualmente exclui todos eles. Escreva a frase, não o relato de escrevê-la.

HábitoEm vez deEscreva
Narrar o ato de escrever«الشروط ثلاثة، نذكرها صراحة فيما يلي»«الشروط ثلاثة:»
Apontar para outra seção«…ونعود إلى هذه النقطة لاحقاً»احذف العبارة
Rótulos de versão ou status em um título«الخطة (النسخة الثانية — معتمدة)»«الخطة»
Argumentar contra uma opção que ninguém levantou«نحفظ المسار فقط. تخزين الملف كاملاً يضخّم الحجم بلا فائدة.»«نحفظ المسار فقط.»
Justificar uma escolha pelo que o briefing omitiu«لم يرد ذلك في الطلب، غير أن طبيعة العمل تفرضه.»«طبيعة العمل تفرض ذلك.»
Primeira pessoa do singular«وأستطيع لاحقاً تحليل الحالات»«ويمكن لاحقاً تحليل الحالات»
Reafirmar um fato que o documento já forneceuتكرار المعلومة في قسم آخراحذف التكرار

O árabe formal prefere o impessoal ou o plural em vez de «أنا»; o singular soa como uma anotação para si mesmo, em vez de um documento.

Habilidades Relacionadas