Código aberto · Exemplo prático

Corrigir o texto árabe de um PDF: um exemplo prático

Um certificado de amostra cujo árabe aparece certo na tela mas copia como quadrados e letras erradas, corrigido com arabic-pdf-repair em um só comando. Baixe os dois arquivos, compare o que eles colam e rode o mesmo código nos seus PDFs.

1. Baixe os arquivos de amostra

Os dois arquivos são um certificado de uma página criado para este exemplo: os nomes e dados são fictícios. A camada de texto do original está quebrada como as antigas ferramentas do Windows deixavam; o arquivo corrigido é o original depois do comando abaixo. As páginas ficam exatamente iguais.

2. Copie o texto do original

Estas são as primeiras linhas como o pdf.js, o leitor de PDF do Firefox e de muitos apps web, as extrai. Cada □ é um caractere de controle: invisível ou um quadrado, conforme onde você cola.

□دة إ □□م دورة
□ □□ ا□□ر□□□□دة □□ر □□□□
□ □ إدارة ا□□□□□ □□ن
□ري
□□□"! ا□□رة □"
'□ أ □% □□$□ح دورة

3. Corrija com um comando

Com Node.js 20 ou mais recente, sem instalar nada. O comando informa cada fonte corrigida e grava a cópia corrigida ao lado do original, que ele nunca altera:

$ npx arabic-pdf-repair certificate.pdf
fixed CertArabic: 65 codes
wrote certificate.repaired.pdf

4. Copie o texto de novo

As mesmas linhas, copiadas de certificate.repaired.pdf:

شهادة إتمام دورة
مركز ريادة للتدريب المهني
تشهد إدارة المركز بأن
سارة يوسف المنصوري
قد أتمت بنجاح دورة
أساسيات تحرير المستندات الرقمية

A busca também funciona: a palavra التعلم não aparece no original e aparece uma vez no arquivo corrigido.

5. A mesma correção no seu código

No Node.js, instale o pacote (npm install arabic-pdf-repair) e passe os bytes do arquivo para repairTextLayer. Ele retorna o arquivo corrigido e as fontes corrigidas, ou null quando não há nada a corrigir:

import { readFile, writeFile } from "node:fs/promises";
import { repairTextLayer } from "arabic-pdf-repair";

const input = new Uint8Array(await readFile("certificate.pdf"));
const result = await repairTextLayer(input);
if (result) {
  await writeFile("certificate.repaired.pdf", result.bytes);
  console.log(result.fonts); // [{ name: "CertArabic", codes: 65 }]
}

A biblioteca não usa nenhuma API do Node.js, então também roda no navegador ou num web worker, com um arquivo escolhido pelo usuário, sem enviá-lo:

import { repairTextLayer } from "arabic-pdf-repair";

const picker = document.querySelector("input[type=file]");
picker.addEventListener("change", async () => {
  const file = picker.files[0];
  const result = await repairTextLayer(new Uint8Array(await file.arrayBuffer()));
  if (!result) return; // nothing to repair
  const url = URL.createObjectURL(new Blob([result.bytes], { type: "application/pdf" }));
  window.open(url); // the repaired copy; the file never left the browser
});

Por que o original copia como texto ilegível

  • Um PDF desenha cada letra como uma forma (um glifo) de uma fonte. Para copiá-la, o leitor precisa de uma tabela no arquivo, chamada ToUnicode, que diz qual letra cada forma representa.
  • A fonte do original não tem essa tabela. Seus glifos só têm os nomes de glifos árabes da Microsoft (afii62753 em diante), que os leitores não reconhecem como letras, então a cópia sai com caracteres de controle e letras soltas.
  • O arabic-pdf-repair lê esses nomes, grava a tabela que falta e não muda mais nada: os mesmos glifos nos mesmos lugares, a mesma página.

Próximos passos