#!/usr/bin/env node /** * Script pour extraire les positions exactes des placeholders {{Signature...}} * depuis un PDF */ const fs = require('fs'); const path = require('path'); /** * Regex pour matcher les placeholders de signature * Format: {{Label;role=Role;type=type;height=H;width=W}} */ const PLACEHOLDER_REGEX = /\{\{([^;]+);role=([^;]+);type=([^;]+);height=(\d+);width=(\d+)\}\}/g; async function extractPlaceholders(pdfPath) { console.log(`\nπŸ“„ Analyse du PDF: ${pdfPath}\n`); try { // Lire le PDF comme texte brut const pdfBuffer = fs.readFileSync(pdfPath); const pdfText = pdfBuffer.toString('latin1'); console.log(`βœ… PDF chargΓ©\n`); const placeholders = []; let pageNum = 1; // Chercher les placeholders dans le texte let match; PLACEHOLDER_REGEX.lastIndex = 0; // Reset la regex while ((match = PLACEHOLDER_REGEX.exec(pdfText)) !== null) { placeholders.push({ page: pageNum, // On va essayer de dΓ©terminer la page label: match[1].trim(), role: match[2].trim(), type: match[3].trim(), height: parseInt(match[4]), width: parseInt(match[5]), fullMatch: match[0], }); } // Essayer de mieux dΓ©terminer les pages en cherchant les marqueurs de page const pageBreakRegex = /\x0c/g; // Form feed character let pageBreakMatch; let lastBreakIndex = 0; let pageBreaks = [0]; while ((pageBreakMatch = pageBreakRegex.exec(pdfText)) !== null) { pageBreaks.push(pageBreakMatch.index); } // Associer les placeholders aux pages correctes placeholders.forEach(ph => { const placeholderPos = pdfText.indexOf(ph.fullMatch); if (placeholderPos !== -1) { // Trouver quelle page contient ce placeholder for (let i = pageBreaks.length - 1; i >= 0; i--) { if (placeholderPos >= pageBreaks[i]) { ph.page = i + 1; break; } } } }); if (placeholders.length === 0) { console.log('⚠️ Aucun placeholder trouvΓ©!\n'); return; } // Afficher les rΓ©sultats console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`); console.log('πŸ“ PLACEHOLDERS DΓ‰TECTΓ‰S'); console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`); placeholders.forEach((ph, idx) => { console.log(`${idx + 1}. ${ph.label}`); console.log(` RΓ΄le: ${ph.role}`); console.log(` Page: ${ph.page}`); console.log(` Dimensions: ${ph.width} Γ— ${ph.height} mm`); console.log(` Type: ${ph.type}\n`); }); // GΓ©nΓ©rer le code pour test-odentas-sign.js console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`); console.log('πŸ“‹ CODE POUR test-odentas-sign.js'); console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`); console.log('positions: ['); placeholders.forEach(ph => { console.log(` {`); console.log(` role: '${ph.role}',`); console.log(` page: ${ph.page},`); console.log(` x: 100, // Γ€ ajuster selon la position exacte`); console.log(` y: 680, // Γ€ ajuster selon la position exacte`); console.log(` w: ${ph.width},`); console.log(` h: ${ph.height},`); console.log(` kind: 'signature',`); console.log(` label: '${ph.label}',`); console.log(` },`); }); console.log(']'); // Sauvegarder en JSON const outputPath = pdfPath.replace('.pdf', '-placeholders.json'); fs.writeFileSync(outputPath, JSON.stringify(placeholders, null, 2)); console.log(`\nπŸ’Ύ RΓ©sultats sauvegardΓ©s: ${outputPath}\n`); } catch (error) { console.error('❌ Erreur:', error.message); process.exit(1); } } // Point d'entrΓ©e const pdfPath = process.argv[2] || path.join(__dirname, 'test-contrat.pdf'); if (!fs.existsSync(pdfPath)) { console.error(`❌ Fichier non trouvΓ©: ${pdfPath}`); process.exit(1); } extractPlaceholders(pdfPath).catch(console.error);