Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
Enregistrement en format IDML
#5
un petit javascript.jsx pour convertir tous les fichiers Adobe Indesign .indd en fichier .idml. 
Le script traite les dossiers et sous-dossiers, sauvegarde dans un dossier Export_idml en respectant les dossiers et sous-dossiers. 
Merci ChatGPT

Fonctionnement
Il demande de sélectionner un dossier source.
Il parcourt récursivement tous ses dossiers et sous-dossiers.
Il détecte les fichiers .indd.
Il peut également traiter les modèles .indt.
Il crée automatiquement :
Dossier sélectionné/
└── export_idml/
Il reproduit toute l’arborescence d’origine dans export_idml.
Il exporte chaque document en .idml.
Il ferme chaque document sans modifier ni enregistrer le fichier source.
Il produit un rapport détaillé

Protections professionnelles intégrées
exclusion automatique du dossier export_idml pendant l’analyse ;
traitement indépendant de chaque fichier ;
poursuite du traitement lorsqu’un document est défectueux ;
option d’arrêt à la première erreur ;
détection des documents déjà ouverts dans InDesign ;
avertissement en présence de documents ouverts et non enregistrés ;
option de remplacement ou de conservation des IDML existants ;
exclusion facultative des fichiers et dossiers masqués ;
restauration du niveau d’interaction d’InDesign après exécution ;
journal UTF-8 avec date, heure, source, destination et erreur ;
statistiques finales : fichiers trouvés, exportés, ignorés et en échec ;
compatibilité des chemins macOS et Windows


Installation
Dans InDesign 2026 :
Ouvrez Fenêtre > Utilitaires > Scripts.
Dans le panneau Scripts, faites un clic droit sur Utilisateur.
Sélectionnez Révéler dans le Finder sur macOS ou Révéler dans l’Explorateur sous Windows.
Copiez le fichier Export_IDML_recursif_InDesign_2026.jsx dans le dossier ouvert.
Revenez dans InDesign.
Double-cliquez sur le script.

Evolution possible :
Un pourcentage de traitement

Export_IDML_recursif_InDesign_2026.jsx


Code :
#target "InDesign"
#targetengine "batchExportIDML"

/*
   Export IDML récursif — Adobe InDesign 2026
   Version : 1.0.0
   Fonction :
     - sélection d'un dossier source ;
     - recherche récursive des fichiers .indd et, en option, .indt ;
     - création de <dossier_source>/export_idml ;
     - conservation de l'arborescence ;
     - export IDML sans modifier les fichiers sources ;
     - journal UTF-8 détaillé ;
     - gestion des erreurs fichier par fichier.

   Installation :
     Fenêtre > Utilitaires > Scripts
     Clic droit sur "Utilisateur" > Révéler dans l’Explorateur/Finder
     Copier ce fichier .jsx dans le dossier Scripts Panel.
*/

(function () {
   "use strict";

   var SCRIPT_NAME = "Export IDML récursif";
   var SCRIPT_VERSION = "1.0.0";
   var EXPORT_FOLDER_NAME = "export_idml";

   var stats = {
       found: 0,
       exported: 0,
       skipped: 0,
       failed: 0,
       startedAt: new Date()
   };

   var logLines = [];
   var originalInteractionLevel = app.scriptPreferences.userInteractionLevel;
   var sourceRoot = null;
   var exportRoot = null;
   var settings = null;

   function main() {
       if (app.documents.length > 0 && hasUnsavedDocuments()) {
           var proceed = confirm(
               "Des documents InDesign ouverts comportent des modifications non enregistrées.\r\r" +
               "Le script ne les fermera pas, mais il est recommandé de les enregistrer avant un traitement par lot.\r\r" +
               "Continuer ?",
               false,
               SCRIPT_NAME
           );
           if (!proceed) {
               return;
           }
       }

       sourceRoot = Folder.selectDialog(
           "Sélectionnez le dossier contenant les fichiers InDesign à convertir en IDML"
       );

       if (!sourceRoot) {
           return;
       }

       settings = showOptionsDialog();
       if (!settings) {
           return;
       }

       exportRoot = new Folder(sourceRoot.fsName + "/" + EXPORT_FOLDER_NAME);

       if (!ensureFolder(exportRoot)) {
           alert(
               "Impossible de créer le dossier d’export :\r" + exportRoot.fsName,
               SCRIPT_NAME,
               true
           );
           return;
       }

       logHeader();

       app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;

       try {
           scanFolder(sourceRoot, exportRoot);
       } catch (fatalError) {
           log("ERREUR FATALE", sourceRoot.fsName, formatError(fatalError));
       } finally {
           app.scriptPreferences.userInteractionLevel = originalInteractionLevel;
       }

       stats.finishedAt = new Date();
       writeLog();
       showSummary();
   }

   function showOptionsDialog() {
       var dlg = new Window("dialog", SCRIPT_NAME + " — v" + SCRIPT_VERSION);
       dlg.orientation = "column";
       dlg.alignChildren = ["fill", "top"];

       var info = dlg.add(
           "statictext",
           undefined,
           "Les fichiers IDML seront placés dans un dossier « " +
           EXPORT_FOLDER_NAME +
           " » créé à la racine du dossier sélectionné.",
           { multiline: true }
       );
       info.preferredSize.width = 520;

       var formatsPanel = dlg.add("panel", undefined, "Fichiers à traiter");
       formatsPanel.orientation = "column";
       formatsPanel.alignChildren = "left";
       formatsPanel.margins = 14;

       var includeINDD = formatsPanel.add("checkbox", undefined, "Documents InDesign (.indd)");
       includeINDD.value = true;
       includeINDD.enabled = false;

       var includeINDT = formatsPanel.add("checkbox", undefined, "Modèles InDesign (.indt)");
       includeINDT.value = false;

       var behaviorPanel = dlg.add("panel", undefined, "Comportement");
       behaviorPanel.orientation = "column";
       behaviorPanel.alignChildren = "left";
       behaviorPanel.margins = 14;

       var overwrite = behaviorPanel.add(
           "checkbox",
           undefined,
           "Remplacer les fichiers IDML existants"
       );
       overwrite.value = false;

       var skipHidden = behaviorPanel.add(
           "checkbox",
           undefined,
           "Ignorer les fichiers et dossiers masqués"
       );
       skipHidden.value = true;

       var stopOnError = behaviorPanel.add(
           "checkbox",
           undefined,
           "Arrêter le traitement à la première erreur"
       );
       stopOnError.value = false;

       var buttons = dlg.add("group");
       buttons.alignment = "right";
       buttons.add("button", undefined, "Annuler", { name: "cancel" });
       buttons.add("button", undefined, "Convertir", { name: "ok" });

       if (dlg.show() !== 1) {
           return null;
       }

       return {
           includeINDT: includeINDT.value,
           overwrite: overwrite.value,
           skipHidden: skipHidden.value,
           stopOnError: stopOnError.value
       };
   }

   function scanFolder(currentSourceFolder, currentExportFolder) {
       var entries;
       var i;
       var entry;
       var childExportFolder;

       try {
           entries = currentSourceFolder.getFiles();
       } catch (e) {
           stats.failed++;
           log("DOSSIER ILLISIBLE", currentSourceFolder.fsName, formatError(e));
           if (settings.stopOnError) {
               throw e;
           }
           return;
       }

       entries.sort(sortByName);

       for (i = 0; i < entries.length; i++) {
           entry = entries[i];

           if (settings.skipHidden && isHidden(entry)) {
               continue;
           }

           if (entry instanceof Folder) {
               if (samePath(entry, exportRoot)) {
                   continue;
               }

               childExportFolder = new Folder(currentExportFolder.fsName + "/" + entry.name);

               if (!ensureFolder(childExportFolder)) {
                   stats.failed++;
                   log(
                       "DOSSIER NON CRÉÉ",
                       childExportFolder.fsName,
                       "Impossible de créer le dossier de destination."
                   );
                   if (settings.stopOnError) {
                       throw new Error("Impossible de créer : " + childExportFolder.fsName);
                   }
                   continue;
               }

               scanFolder(entry, childExportFolder);
               continue;
           }

           if (entry instanceof File && isSupportedFile(entry)) {
               stats.found++;
               convertFile(entry, currentExportFolder);
           }
       }
   }

   function convertFile(sourceFile, destinationFolder) {
       var document = null;
       var openedByScript = false;
       var destinationFile = buildDestinationFile(sourceFile, destinationFolder);

       try {
           if (isDocumentAlreadyOpen(sourceFile)) {
               stats.skipped++;
               log(
                   "IGNORÉ",
                   sourceFile.fsName,
                   "Le document est déjà ouvert dans InDesign."
               );
               return;
           }

           if (destinationFile.exists) {
               if (!settings.overwrite) {
                   stats.skipped++;
                   log(
                       "IGNORÉ",
                       sourceFile.fsName,
                       "Le fichier IDML existe déjà : " + destinationFile.fsName
                   );
                   return;
               }

               if (!destinationFile.remove()) {
                   throw new Error(
                       "Impossible de remplacer le fichier IDML existant : " +
                       destinationFile.fsName
                   );
               }
           }

           document = app.open(sourceFile, false);
           openedByScript = true;

           /*
               IDML est exposé par le DOM InDesign via
               ExportFormat.INDESIGN_MARKUP.
           */
           document.exportFile(
               ExportFormat.INDESIGN_MARKUP,
               destinationFile,
               false
           );

           if (!destinationFile.exists) {
               throw new Error(
                   "InDesign n’a pas créé le fichier IDML attendu."
               );
           }

           stats.exported++;
           log("EXPORTÉ", sourceFile.fsName, destinationFile.fsName);

       } catch (e) {
           stats.failed++;
           log("ÉCHEC", sourceFile.fsName, formatError(e));

           if (settings.stopOnError) {
               throw e;
           }
       } finally {
           if (openedByScript && document && document.isValid) {
               try {
                   document.close(SaveOptions.NO);
               } catch (closeError) {
                   log(
                       "AVERTISSEMENT",
                       sourceFile.fsName,
                       "Fermeture impossible : " + formatError(closeError)
                   );
               }
           }
       }
   }

   function buildDestinationFile(sourceFile, destinationFolder) {
       var baseName = sourceFile.name.replace(/\.[^\.]+$/, "");
       var extension = getExtension(sourceFile.name);
       var candidate = new File(destinationFolder.fsName + "/" + baseName + ".idml");

       /*
           Évite une collision rare lorsque deux fichiers du même dossier
           portent le même nom avec les extensions .indd et .indt.
       */
       if (
           extension === "indt" &&
           candidate.exists &&
           !settings.overwrite
       ) {
           candidate = new File(
               destinationFolder.fsName + "/" + baseName + "__modele.idml"
           );
       }

       return candidate;
   }

   function isSupportedFile(file) {
       var extension = getExtension(file.name);

       if (extension === "indd") {
           return true;
       }

       return settings.includeINDT && extension === "indt";
   }

   function getExtension(name) {
       var match = name.toLowerCase().match(/\.([^.]+)$/);
       return match ? match[1] : "";
   }

   function ensureFolder(folder) {
       if (folder.exists) {
           return true;
       }

       /*
           Folder.create() ne crée pas toujours toute une chaîne absente.
           La récursion garantit que le parent existe déjà.
       */
       try {
           return folder.create();
       } catch (e) {
           return false;
       }
   }

   function isDocumentAlreadyOpen(file) {
       var i;
       var doc;
       var filePath = normalizePath(file.fsName);

       for (i = 0; i < app.documents.length; i++) {
           doc = app.documents[i];

           try {
               if (
                   doc.saved &&
                   normalizePath(doc.fullName.fsName) === filePath
               ) {
                   return true;
               }
           } catch (e) {
               // Document sans chemin exploitable : sans incidence.
           }
       }

       return false;
   }

   function hasUnsavedDocuments() {
       var i;
       for (i = 0; i < app.documents.length; i++) {
           try {
               if (app.documents[i].modified) {
                   return true;
               }
           } catch (e) {}
       }
       return false;
   }

   function samePath(a, b) {
       return normalizePath(a.fsName) === normalizePath(b.fsName);
   }

   function normalizePath(path) {
       var normalized = String(path).replace(/\\/g, "/");
       if ($.os.toLowerCase().indexOf("windows") >= 0) {
           normalized = normalized.toLowerCase();
       }
       return normalized.replace(/\/+$/, "");
   }

   function isHidden(entry) {
       /*
           Le point initial couvre les éléments Unix/macOS.
           La propriété hidden, lorsqu’elle est disponible, couvre aussi
           certains éléments masqués sous Windows.
       */
       if (/^\./.test(entry.name)) {
           return true;
       }

       try {
           return entry.hidden === true;
       } catch (e) {
           return false;
       }
   }

   function sortByName(a, b) {
       var nameA = a.name.toLowerCase();
       var nameB = b.name.toLowerCase();

       if (nameA < nameB) {
           return -1;
       }
       if (nameA > nameB) {
           return 1;
       }
       return 0;
   }

   function log(status, source, detail) {
       logLines.push(
           [
               formatDate(new Date()),
               status,
               source || "",
               detail || ""
           ].join("\t")
       );
   }

   function logHeader() {
       logLines.push(SCRIPT_NAME + "\tVersion " + SCRIPT_VERSION);
       logLines.push("Début\t" + formatDate(stats.startedAt));
       logLines.push("Dossier source\t" + sourceRoot.fsName);
       logLines.push("Dossier export\t" + exportRoot.fsName);
       logLines.push(
           "Options\tINDT=" + settings.includeINDT +
           "; remplacement=" + settings.overwrite +
           "; masqués ignorés=" + settings.skipHidden +
           "; arrêt sur erreur=" + settings.stopOnError
       );
       logLines.push("");
       logLines.push("Date et heure\tÉtat\tSource\tDétail");
   }

   function writeLog() {
       var logFile = new File(exportRoot.fsName + "/rapport_export_idml.txt");
       var summary = [
           "",
           "RÉSUMÉ",
           "Fichiers détectés\t" + stats.found,
           "Exports réussis\t" + stats.exported,
           "Fichiers ignorés\t" + stats.skipped,
           "Échecs\t" + stats.failed,
           "Fin\t" + formatDate(stats.finishedAt),
           "Durée\t" + formatDuration(stats.finishedAt - stats.startedAt)
       ];

       logFile.encoding = "UTF-8";
       logFile.lineFeed = "Unix";

       try {
           if (logFile.open("w")) {
               logFile.write(logLines.concat(summary).join("\n"));
               logFile.close();
           }
       } catch (e) {
           try {
               if (logFile.opened) {
                   logFile.close();
               }
           } catch (ignore) {}

           alert(
               "Le traitement est terminé, mais le journal n’a pas pu être écrit :\r" +
               formatError(e),
               SCRIPT_NAME,
               true
           );
       }
   }

   function showSummary() {
       var message =
           "Traitement terminé.\r\r" +
           "Fichiers détectés : " + stats.found + "\r" +
           "Exports réussis : " + stats.exported + "\r" +
           "Fichiers ignorés : " + stats.skipped + "\r" +
           "Échecs : " + stats.failed + "\r" +
           "Durée : " + formatDuration(stats.finishedAt - stats.startedAt) + "\r\r" +
           "Dossier de sortie :\r" + exportRoot.fsName + "\r\r" +
           "Journal : rapport_export_idml.txt";

       alert(message, SCRIPT_NAME, stats.failed > 0);
   }

   function formatError(error) {
       var parts = [];

       try {
           if (error.name) {
               parts.push(error.name);
           }
       } catch (e1) {}

       try {
           if (error.message) {
               parts.push(error.message);
           } else {
               parts.push(String(error));
           }
       } catch (e2) {
           parts.push("Erreur inconnue");
       }

       try {
           if (error.line) {
               parts.push("ligne " + error.line);
           }
       } catch (e3) {}

       return parts.join(" — ");
   }

   function formatDate(date) {
       function pad(value) {
           return value < 10 ? "0" + value : String(value);
       }

       return (
           date.getFullYear() + "-" +
           pad(date.getMonth() + 1) + "-" +
           pad(date.getDate()) + " " +
           pad(date.getHours()) + ":" +
           pad(date.getMinutes()) + ":" +
           pad(date.getSeconds())
       );
   }

   function formatDuration(milliseconds) {
       var totalSeconds = Math.max(0, Math.round(milliseconds / 1000));
       var hours = Math.floor(totalSeconds / 3600);
       var minutes = Math.floor((totalSeconds % 3600) / 60);
       var seconds = totalSeconds % 60;
       var parts = [];

       if (hours > 0) {
           parts.push(hours + " h");
       }
       if (minutes > 0 || hours > 0) {
           parts.push(minutes + " min");
       }
       parts.push(seconds + " s");

       return parts.join(" ");
   }

   main();

}());
Vos applications :
  • > Affinity Photo Mac
  • > Affinity Designer Mac
  • > Affinity Publisher Mac
  • > Affinity Photo Windows
  • > Affinity Designer Windows
  • > Affinity Publisher Windows
  • > Affinity Photo iPad
  • > Affinity Designer iPad
  • > Affinity Publisher iPad
  • > Affinity by Canva Mac
  • > Affinity by Canva Windows
  • > Affinity by Canva Ipad
- Version : 3
  


Messages dans ce sujet
Enregistrement en format IDML - par PatLilou - 31-03-23, 11:46:50
RE: Enregistrement en format IDML - par YvanM - 03-04-23, 07:25:39
RE: Enregistrement en format IDML - par PatLilou - 03-04-23, 14:11:33
RE: Enregistrement en format IDML - par AdKyburg - 10-05-26, 18:06:25
RE: Enregistrement en format IDML - par jacqq - 06-08-26, 18:55:50

Atteindre :


Utilisateur(s) parcourant ce sujet :
1 visiteur(s)


Articles Amazon recommandés pour accompagner vos logiciels Affinity


Affinity & Canva - Guide Utilisateur
Affinity
Guide Utilisateur
Voir sur Amazon
Guide de l'utilisateur d'Affinity V3
Guide utilisateur
Affinity V3
Voir sur Amazon
Affinity Guide de l'utilisateur
Affinity Guide
de l'utilisateur
Voir sur Amazon
Guide d'utilisation Affinity pour débutants
Affinity pour
les débutants
Voir sur Amazon
Affinity V3 pour débutants
Affinity V3
pour débutants
Voir sur Amazon