Saída em árabe correta
Objetivo: Árabe que renderiza, lê e soa natural na primeira tentativa, em qualquer formato de saída.
1. Decida três coisas antes de escrever qualquer coisa
| Decisão | Padrão | Alterar quando |
|---|---|---|
| Localidade do público | ar + região se conhecida (ar-SA, ar-EG, ar-AE, ar-MA...) | O usuário nomeia um país/cidade/mercado |
| Dígitos | Ocidentais 0-9 para UI, preços, telefones, código, gráficos. Indo-arábicos ٠-٩ para texto formal/editorial voltado ao Egito, Arábia Saudita, Iraque, Levante, Sudão, Iêmen | O usuário pede, ou a marca/região claramente usa ٠-٩. Magrebe (MA/DZ/TN) sempre usa 0-9 |
| Registro | Árabe Moderno Padrão (فصحى), claro e moderno, não clássico | O usuário pede um dialeto (egípcio, golfo, levantino...) ou o canal é casual (promoções no WhatsApp, posts sociais): veja references/writing.md |
Nunca misture sistemas de dígitos em uma única saída.
2. Regras principais (aplicam-se a todos os tipos de saída)
- Declare a direção na raiz, uma vez. Depois deixe tudo herdar.
❌
<html>+style="direction:rtl"espalhado em elementos ✅<html lang="ar" dir="rtl">· docx<w:bidi/>+<w:rtl/>· pptxrtl="1"· FlutterDirectionality(textDirection: TextDirection.rtl)/locale: Locale('ar') - Use direções lógicas, nunca esquerda/direita. "Início" é o lado direito em árabe.
❌
margin-left,ml-4,text-left,left: 0,EdgeInsets.only(left:)✅margin-inline-start,ms-4,text-start,inset-inline-start: 0,EdgeInsetsDirectional.only(start:) - Isole ilhas LTR (números de telefone, e-mails, URLs, código, nomes em inglês próximos a números, números negativos).
❌
اتصل على +966 50 123 4567.→ renderiza como4567 123 50 966+✅اتصل على <bdi dir="ltr">+966 50 123 4567</bdi>.· texto simples: envolva com LRI…PDI (…) ou coloque LRMantes de-5 - Campos de entrada para telefone, e-mail, URL, código, IBAN, senhas permanecem
dir="ltr"mesmo dentro de um formulário RTL (alinhe-os comtext-end). - Espelhe apenas ícones direcionais. Setas para trás/frente, chevrons, enviar, responder, desfazer/refazer, direção de progresso invertem. Reproduzir/pausar, controles de mídia, marcas de seleção, relógios, pesquisa, logotipos, marcas e números não invertem.
- Tipografia: use uma fonte desenhada para árabe (lista em
references/typography.md), line-height ≥ 1.6 para texto corrido, e deixe espaço acima e abaixo para tashkeel. Nunca apliqueletter-spacing/tracking-*,uppercase,italicou alturasoverflow:hiddenapertadas para árabe. - Formação: texto bruto para renderizadores que formam árabe, texto formatado para o resto. Nunca ambos.
Navegadores, Word, LibreOffice, PowerPoint, WeasyPrint, Chromium PDF, matplotlib ≥ 3.11, Pillow com libraqm, fpdf2 com
set_text_shaping()formam árabe sozinhos: passe a string bruta. reportlab, PyMuPDFinsert_text, OpenCV, matplotlib ≤ 3.10, Pillow sem raqm desenham glifo por glifo: passeprepare(text)descripts/shape_text.py. Reformatar texto para um renderizador que já forma árabe inverte novamente (verificado no matplotlib 3.11 e Pillow+raqm). - Pontuação árabe:
،vírgula,؛ponto e vírgula,؟ponto de interrogação,«»aspas. Mantenha.e!. Não use espaço antes da pontuação e um espaço depois. - Escreva em árabe nativamente, não traduza palavra por palavra. Verbos imperativos para botões (
أرسل,احفظ,ابدأ الآن), e sem ordem de palavras do inglês. Vejareferences/writing.md. - Formate números/datas/moedas com o locale, não com concatenação de strings. Use
Intl.NumberFormat('ar-SA', ...)/Intl.DateTimeFormat('ar-EG-u-nu-latn', ...), e sempre definanu(dígitos) eca(calendário) explicitamente.
3. Carregue a referência para o seu tipo de saída
Leia apenas o que a tarefa precisa:
| Saída | Leia |
|---|---|
| HTML, CSS, Tailwind, React, Next.js, Vue, React Native, Flutter, HTML de e-mail | references/web.md + references/bidi.md |
| Árabe + inglês/números misturados em qualquer lugar (incl. markdown, texto simples, SMS, strings JSON) | references/bidi.md |
| Fontes, line-height, tashkeel, pesos, justificação | references/typography.md |
| Word (.docx), PowerPoint (.pptx), PDF | references/documents.md |
| matplotlib, Pillow, SVG, canvas, OpenCV, Plotly, qualquer imagem com texto | references/charts-images.md |
| Copywriting, tradução, dialetos, numerais, datas, moedas, nomes, Hijri | references/writing.md |
4. O que inverte em RTL e o que não inverte
| Inverte (espelha o layout) | Permanece igual |
|---|---|
| Ordem de leitura, alinhamento de texto, ordem de navegação, lado da barra lateral | Números de telefone, cartões de crédito, IBANs (sempre LTR) |
Breadcrumbs, paginação, steppers: "próximo" aponta para a esquerda. Texto › > ( inverte automaticamente, mas → e ícones SVG não | Blocos de código, saída de terminal, URLs, e-mails |
| Setas para trás/próximo, chevrons, direção de deslize de carrosséis/sliders | Eixo x de gráficos de série temporal (o tempo corre da esquerda para a direita). Eixos de categoria podem inverter |
| Ordem das colunas da tabela (primeira coluna à direita) | Controles de mídia (play ▶, avanço rápido), relógios, marcas de seleção |
| Barras de progresso e sliders de intervalo preenchem da direita | Logotipos, marcas, fotos, mapas |
Rótulos de formulários à direita, botão fechar × à esquerda de um diálogo | Expressões matemáticas e os próprios números (1.234,5 permanece 1.234,5) |
| Lado de deslize de toasts/drawers, emblemas em avatares, marcadores de lista | Atalhos de teclado (Ctrl+S) |
5. Antes de finalizar
- Execute o linter em qualquer código que você produziu (precisa apenas da biblioteca padrão do Python):
python <skill-dir>/scripts/rtl_check.py <arquivo-ou-pasta>Corrija todos oserror. Corrijawarnings a menos que sejam intencionais, e marque os intencionais com um comentáriortl-ok. - Renderize e veja quando puder, depois verifique se as letras estão conectadas, a primeira palavra está à direita, a pontuação está no final esquerdo e os números são lidos na ordem correta:
- HTML:
python -m playwright screenshot --full-page file://$PWD/index.html shot.png(ounpx playwright screenshot …). Se não houver navegador disponível,weasyprint index.html out.pdffornece uma renderização estática. - docx/pptx:
soffice --headless --convert-to pdf arquivo.docx, depois rasterize o PDF. - PDF → PNG:
python -c "import pymupdf; pymupdf.open('f.pdf')[0].get_pixmap(dpi=110).save('f.png')" - Imagens/gráficos: abra o PNG que você escreveu.
- HTML:
- Se os scripts não puderem ser executados (sem Python, sem shell), percorra esta lista de verificação manualmente:
- raiz
dir="rtl"+lang="ar…"(ou o equivalente do formato) - sem
left/rightem espaçamento, posicionamento ou alinhamento - telefones/e-mails/URLs/código isolados e LTR
- ícones direcionais espelhados, outros intactos
- fonte árabe carregada, line-height ≥ 1.6, sem letter-spacing, itálico ou maiúsculas
- texto em imagem/PDF: caminho de formação corresponde ao renderizador (regra 7)
-
،؛؟usados, um sistema de dígitos, MSA natural (ou o dialeto solicitado)
- raiz
Scripts
scripts/rtl_check.py <caminho>: verifica HTML/CSS/Tailwind/JSX/TSX/Vue/Svelte/React Native/Flutter em busca de bugs RTL. Imprimearquivo:linha, o problema e a correção exata. Código de saída 1 em erros. Apenas stdlib.scripts/shape_text.py:prepare(text, alvo)para renderizadores que não formam árabe. Ele detecta suporte nativo do matplotlib/Pillow e retorna o texto inalterado quando a formação não é necessária. Usaarabic-reshaper+python-bidi(instalados via pip sob demanda) ou recai para um formatador embutido com stdlib.python shape_text.py --checkinforma o que esta máquina precisa.