Chaque action est un item de menu separe : "Imposer un livret", "Delivretiser", etc. Un clic = une action. Seul le creep est demande via app.response. Corrige aussi "doc is not defined". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
289 lines
12 KiB
JavaScript
Executable File
289 lines
12 KiB
JavaScript
Executable File
// Imposition-02-Livret.js
|
|
// ---------------------------------------------------------------------------
|
|
// Suite d'imposition professionnelle - Folder-Level Script pour Adobe Acrobat Pro
|
|
// Module 2 : Creer un livret / Delivretiser (signature de cahier, piqure a cheval)
|
|
//
|
|
// Depend de Imposition-00-Core.js (doit etre charge avant).
|
|
//
|
|
// ATTENTION TECHNIQUE - a lire avant utilisation en production :
|
|
// Le placement des pages source sur les planches composites repose sur
|
|
// CDImp.Util.placerPageDansRect()/extraireRegionPage() (voir Core.js), qui
|
|
// utilisent la technique "template + recadrage de CropBox" standard en
|
|
// JavaScript pur pour Acrobat (sans plugin natif). Cette technique n'a pas
|
|
// pu etre executee/verifiee dans une vraie session Acrobat depuis cet
|
|
// environnement de developpement (Acrobat n'y est pas installe) : a tester
|
|
// sur un PDF reel avant tout usage en production.
|
|
// ---------------------------------------------------------------------------
|
|
|
|
if (typeof CDImp === "undefined") {
|
|
throw new Error("Imposition-02-Livret.js : CDImp.Core doit etre charge avant ce fichier.");
|
|
}
|
|
|
|
CDImp.Livret = CDImp.Livret || {};
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Calcul de l'ordre des pages (imposition en cahier unique, piqure a cheval)
|
|
// -----------------------------------------------------------------------
|
|
/**
|
|
* Calcule l'imbrication des pages pour un cahier unique (selle/pliage central).
|
|
* Fonction symetrique : utilisee aussi bien pour imposer (Page logique ->
|
|
* position sur planche) que pour delivretiser (position sur planche -> page
|
|
* logique), puisque l'imposition en cahier simple est sa propre inverse au
|
|
* niveau de la formule (seul le sens d'utilisation change).
|
|
*
|
|
* Pour N pages (multiple de 4), chaque feuille porte 4 pages : 2 au recto,
|
|
* 2 au verso. Exemple pour N=8 :
|
|
* Feuille 1 - recto : (8 | 1) verso : (2 | 7)
|
|
* Feuille 2 - recto : (6 | 3) verso : (4 | 5)
|
|
*
|
|
* @param {Number} nPages nombre total de pages (doit etre un multiple de 4)
|
|
* @returns {Array} liste de planches, dans l'ordre d'impression :
|
|
* [{ feuille: 1, face: "recto", gauche: 8, droite: 1 }, ...]
|
|
* "gauche"/"droite" sont des numeros de page 1-based du document source.
|
|
*/
|
|
CDImp.Livret.calculerOrdre = function (nPages) {
|
|
if (nPages % 4 !== 0) {
|
|
throw new Error("calculerOrdre : le nombre de pages (" + nPages + ") doit etre un multiple de 4.");
|
|
}
|
|
var nFeuilles = nPages / 4;
|
|
var planches = [];
|
|
for (var s = 0; s < nFeuilles; s++) {
|
|
planches.push({ feuille: s + 1, face: "recto", gauche: nPages - 2 * s, droite: 2 * s + 1 });
|
|
planches.push({ feuille: s + 1, face: "verso", gauche: 2 * s + 2, droite: nPages - 2 * s - 1 });
|
|
}
|
|
return planches;
|
|
};
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Ajout de pages blanches pour atteindre un multiple de 4
|
|
// -----------------------------------------------------------------------
|
|
/**
|
|
* Insere nManque pages blanches dans doc, a la position demandee.
|
|
* Les pages blanches reprennent le format (largeur/hauteur) de la premiere
|
|
* page du document.
|
|
*
|
|
* @param {Doc} doc document a modifier (modification en place)
|
|
* @param {Number} nManque nombre de pages blanches a ajouter
|
|
* @param {String} position "debut" | "fin" | "apres_couverture"
|
|
*/
|
|
CDImp.Livret.ajouterPagesBlanches = function (doc, nManque, position) {
|
|
if (nManque <= 0) {
|
|
return;
|
|
}
|
|
var boxRef = doc.getPageBox({ nPage: 0, cBox: "Crop" });
|
|
var largeur = Math.abs(boxRef[2] - boxRef[0]);
|
|
var hauteur = Math.abs(boxRef[3] - boxRef[1]);
|
|
|
|
CDImp.Util.avecPrivileges(function () {
|
|
for (var k = 0; k < nManque; k++) {
|
|
var idxInsertion;
|
|
switch (position) {
|
|
case "debut":
|
|
idxInsertion = 0;
|
|
break;
|
|
case "apres_couverture":
|
|
idxInsertion = 1;
|
|
break;
|
|
case "fin":
|
|
default:
|
|
idxInsertion = doc.numPages; // toujours recalcule : ajoute en fin
|
|
break;
|
|
}
|
|
doc.newPage({ nPage: idxInsertion, width: largeur, height: hauteur });
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Demande a l'utilisateur ou inserer les pages blanches manquantes, via un
|
|
* menu contextuel simple (app.popUpMenu, API stable et bien documentee,
|
|
* preferee ici a un second execDialog pour limiter les risques sur un choix
|
|
* aussi simple).
|
|
*
|
|
* @returns {String|null} "debut" | "fin" | "apres_couverture", ou null si
|
|
* l'utilisateur annule.
|
|
*/
|
|
CDImp.Livret._demanderPositionPagesBlanches = function (nManque) {
|
|
var choix = app.popUpMenu(
|
|
{ cName: "A la fin du document (" + nManque + " page(s))", cReturn: "fin" },
|
|
{ cName: "Au debut du document (" + nManque + " page(s))", cReturn: "debut" },
|
|
{ cName: "Juste apres la couverture (page 1)", cReturn: "apres_couverture" }
|
|
);
|
|
return choix || null;
|
|
};
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Construction du document imposes (sens direct : pages -> livret)
|
|
// -----------------------------------------------------------------------
|
|
/**
|
|
* Construit le document de sortie : une page composite (format double, en
|
|
* paysage) par planche recto/verso, avec les deux pages source positionnees
|
|
* cote a cote.
|
|
*
|
|
* @param {Doc} srcDoc document source (deja complete a un multiple de 4 pages)
|
|
* @param {Array} planches resultat de CDImp.Livret.calculerOrdre()
|
|
* @param {Number} creepMm compensation de chasse en mm, appliquee
|
|
* progressivement vers l'interieur du cahier (0 = desactive)
|
|
* @returns {Doc} le nouveau document compose
|
|
*/
|
|
CDImp.Livret.construireDocument = function (srcDoc, planches, creepMm) {
|
|
var boxSrc = srcDoc.getPageBox({ nPage: 0, cBox: "Crop" });
|
|
var largeurSrc = Math.abs(boxSrc[2] - boxSrc[0]);
|
|
var hauteurSrc = Math.abs(boxSrc[3] - boxSrc[1]);
|
|
var largeurDest = largeurSrc * 2;
|
|
var hauteurDest = hauteurSrc;
|
|
var nFeuilles = planches.length / 2;
|
|
|
|
var destDoc;
|
|
CDImp.Util.avecPrivileges(function () {
|
|
destDoc = new Doc();
|
|
destDoc.newPage({ nPage: 0, width: largeurDest, height: hauteurDest });
|
|
for (var k = 1; k < planches.length; k++) {
|
|
destDoc.newPage({ nPage: k, width: largeurDest, height: hauteurDest });
|
|
}
|
|
});
|
|
|
|
for (var i = 0; i < planches.length; i++) {
|
|
var planche = planches[i];
|
|
|
|
// Decalage de chasse (creep) : croissant en s'eloignant du centre du
|
|
// cahier vers l'exterieur, applique symetriquement gauche/droite.
|
|
var decalageCreepPt = creepMm
|
|
? CDImp.Util.mmToPt(creepMm) * (nFeuilles - planche.feuille)
|
|
: 0;
|
|
|
|
CDImp.Util.placerPageDansRect(srcDoc, planche.gauche, destDoc, i,
|
|
[decalageCreepPt, 0, decalageCreepPt + largeurSrc, hauteurSrc]);
|
|
CDImp.Util.placerPageDansRect(srcDoc, planche.droite, destDoc, i,
|
|
[largeurSrc - decalageCreepPt, 0, largeurDest - decalageCreepPt, hauteurSrc]);
|
|
}
|
|
|
|
return destDoc;
|
|
};
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Delivretisation (sens inverse : livret imposes -> ordre de lecture normal)
|
|
// -----------------------------------------------------------------------
|
|
/**
|
|
* Reconstitue l'ordre de lecture normal d'un PDF imposé en cahier piqûre a
|
|
* cheval : chaque page du document source est une planche double (recto ou
|
|
* verso) contenant deux pages logiques cote a cote, dans l'ordre produit par
|
|
* CDImp.Livret.construireDocument(). On reutilise calculerOrdre() pour
|
|
* retrouver, pour chaque planche, les numeros de page logique a replacer a
|
|
* gauche et a droite, puis on extrait chaque moitie vers sa position finale.
|
|
*
|
|
* Limite connue : ne compense pas une eventuelle chasse (creep) appliquee
|
|
* lors de l'imposition d'origine (les pages reconstituees seront legerement
|
|
* decalees si un creep non nul avait ete utilise).
|
|
*
|
|
* @param {Doc} doc document imposes (planches doubles), document actif si omis
|
|
*/
|
|
CDImp.Livret.delivretiser = function (doc) {
|
|
doc = CDImp.Util.getDocActif(doc);
|
|
|
|
var nPlanches = doc.numPages;
|
|
if (nPlanches % 2 !== 0) {
|
|
CDImp.Util.erreur("Delivretiser : le document doit contenir un nombre pair de planches\n(une planche recto + une planche verso par feuille).");
|
|
return;
|
|
}
|
|
var nPagesLogiques = nPlanches * 2;
|
|
|
|
var planches;
|
|
try {
|
|
planches = CDImp.Livret.calculerOrdre(nPagesLogiques);
|
|
} catch (e) {
|
|
CDImp.Util.erreur(e.toString());
|
|
return;
|
|
}
|
|
|
|
var boxRef = doc.getPageBox({ nPage: 0, cBox: "Crop" });
|
|
var largeurPlanche = Math.abs(boxRef[2] - boxRef[0]);
|
|
var hauteur = Math.abs(boxRef[3] - boxRef[1]);
|
|
var largeurDemiPage = largeurPlanche / 2;
|
|
|
|
var destDoc;
|
|
try {
|
|
CDImp.Util.avecPrivileges(function () {
|
|
destDoc = new Doc();
|
|
destDoc.newPage({ nPage: 0, width: largeurDemiPage, height: hauteur });
|
|
for (var k = 1; k < nPagesLogiques; k++) {
|
|
destDoc.newPage({ nPage: k, width: largeurDemiPage, height: hauteur });
|
|
}
|
|
});
|
|
|
|
for (var i = 0; i < planches.length; i++) {
|
|
var planche = planches[i];
|
|
var rectGauche = [0, 0, largeurDemiPage, hauteur];
|
|
var rectDroite = [largeurDemiPage, 0, largeurPlanche, hauteur];
|
|
|
|
CDImp.Util.extraireRegionPage(doc, i + 1, rectGauche, destDoc, planche.gauche - 1);
|
|
CDImp.Util.extraireRegionPage(doc, i + 1, rectDroite, destDoc, planche.droite - 1);
|
|
}
|
|
} catch (e) {
|
|
CDImp.Util.erreur("Erreur lors de la delivretisation : " + e.toString());
|
|
return;
|
|
}
|
|
|
|
if (CDImp.Auto && CDImp.Auto.enregistrerDerniereAction) {
|
|
CDImp.Auto.enregistrerDerniereAction("Livret.delivretiser", {});
|
|
}
|
|
|
|
CDImp.Util.info("Delivretisation terminee (" + nPagesLogiques + " pages reconstituees).\nPensez a l'enregistrer (Ctrl+S) sous un nouveau nom.");
|
|
};
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Point d'entree du module (appele depuis le panneau principal, Module 1)
|
|
// -----------------------------------------------------------------------
|
|
CDImp.Livret.imposer = function () {
|
|
var doc = CDImp.Util.getDocActif();
|
|
var nPages = doc.numPages;
|
|
var reste = nPages % 4;
|
|
|
|
var info = "Document : " + nPages + " pages.";
|
|
if (reste !== 0) {
|
|
info += "\n" + (4 - reste) + " page(s) blanche(s) seront ajoutees a la fin.";
|
|
}
|
|
|
|
var saisie = app.response({
|
|
cQuestion: info + "\n\nCompensation de chasse (creep) en mm par feuille :\n(0 = aucune)",
|
|
cTitle: "Imposer un livret",
|
|
cDefault: "0"
|
|
});
|
|
if (saisie === null) return;
|
|
var creepMm = parseFloat(saisie) || 0;
|
|
|
|
if (reste !== 0) {
|
|
CDImp.Livret.ajouterPagesBlanches(doc, 4 - reste, "fin");
|
|
nPages = doc.numPages;
|
|
}
|
|
|
|
var planches = CDImp.Livret.calculerOrdre(nPages);
|
|
var destDoc = CDImp.Livret.construireDocument(doc, planches, creepMm);
|
|
|
|
if (CDImp.Auto && CDImp.Auto.enregistrerDerniereAction) {
|
|
CDImp.Auto.enregistrerDerniereAction("Livret.imposer", { creepMm: creepMm });
|
|
}
|
|
|
|
app.alert("Livret cree avec succes (" + planches.length + " planches).\nPensez a l'enregistrer sous un nouveau nom.");
|
|
|
|
CDImp.Util.info("Livret cree avec succes (" + planches.length + " planches).\nPensez a l'enregistrer (Ctrl+S) sous un nouveau nom.");
|
|
};
|
|
|
|
/**
|
|
* Variante directe sans dialogues, utilisee par le Module 7 (Automatisation)
|
|
* pour rejouer une action enregistree sur un nouveau document. Ne gere pas
|
|
* l'ajout de pages blanches (le document doit deja etre un multiple de 4).
|
|
*/
|
|
CDImp.Livret.executerAvecParams = function (doc, params) {
|
|
doc = CDImp.Util.getDocActif(doc);
|
|
var nPages = doc.numPages;
|
|
if (nPages % 4 !== 0) {
|
|
CDImp.Util.erreur("Repeter l'action : le document (" + nPages + " pages) n'est pas un multiple de 4.\nUtilisez le module Livret manuellement pour ajouter les pages blanches.");
|
|
return;
|
|
}
|
|
var planches = CDImp.Livret.calculerOrdre(nPages);
|
|
var destDoc = CDImp.Livret.construireDocument(doc, planches, params.creepMm || 0);
|
|
CDImp.Util.info("Livret recree avec succes (" + planches.length + " planches).");
|
|
return destDoc;
|
|
};
|