необходимо добавить теги documentId и instanceId для метаинформации .indd после создания отсутствующих documentId и InstanceIds для ссылок - PullRequest
1 голос
/ 18 июня 2019

Используя ExtendScript, я обновляю отсутствующие DocumentId и InstanceId для ссылок файла Indesign (.indd), используя ссылочный код на , требуется синтаксис setProperty для объекта XMP, Это работает нормально и обновляет все ссылки, пропускающие DoumentId и InstanceId должным образом. Но проблема, с которой я сейчас сталкиваюсь, заключается в том, что в самом файле .indd есть метаинформация, в которой эти вновь созданные DocumentId и InstanceId отсутствуют для этих конкретных ссылок.

Пожалуйста, обратитесь к метаинформации ниже файла .indd с четырьмя ресурсами для лучшего понимания. Здесь у него четыре ресурса: два .psd файла и два .ai файла. Метаинформация файла .indd содержит <stRef:instanceID> и <stRef:documentID> для двух ресурсов .ai, поскольку эти теги (<stRef:instanceID> и <stRef:documentID>) отсутствуют для двух других ресурсов .psd. Даже после создания отсутствующих DocumentId и InstanceId для файлов .psd в метаданных файла .indd для этих двух ресурсов эти два тега <stRef:instanceID> и <stRef:documentID> все еще отсутствуют. Как я могу обновить DocumentId и InstanceId этих отсутствующих ссылок даже в метаинформации .indd файла?

<xmpMM:Manifest>
  <rdf:Bag>
    <rdf:li rdf:parseType="Resource">
      <stMfs:linkForm>ReferenceStream</stMfs:linkForm>
      <xmpMM:placedXResolution>300.00</xmpMM:placedXResolution>
      <xmpMM:placedYResolution>300.00</xmpMM:placedYResolution>
      <xmpMM:placedResolutionUnit>Inches</xmpMM:placedResolutionUnit>
      <stMfs:reference rdf:parseType="Resource">
        <stRef:lastURL>file:///Users/superadmin/Downloads/266x165mm_VPA_WS_SP_M-1F/Links/6604_RGB.psd</stRef:lastURL>
      </stMfs:reference>
    </rdf:li>
    <rdf:li rdf:parseType="Resource">
      <stMfs:linkForm>ReferenceStream</stMfs:linkForm>
      <xmpMM:placedXResolution>72.00</xmpMM:placedXResolution>
      <xmpMM:placedYResolution>72.00</xmpMM:placedYResolution>
      <xmpMM:placedResolutionUnit>Inches</xmpMM:placedResolutionUnit>
      <stMfs:reference rdf:parseType="Resource">
        <stRef:lastURL>file:///Users/superadmin/Downloads/266x165mm_VPA_WS_SP_M-1F/Links/Silver_001_RGB.psd</stRef:lastURL>
      </stMfs:reference>
    </rdf:li>
    <rdf:li rdf:parseType="Resource">
      <stMfs:linkForm>ReferenceStream</stMfs:linkForm>
      <xmpMM:placedXResolution>72.00</xmpMM:placedXResolution>
      <xmpMM:placedYResolution>72.00</xmpMM:placedYResolution>
      <xmpMM:placedResolutionUnit>Inches</xmpMM:placedResolutionUnit>
      <stMfs:reference rdf:parseType="Resource">
        <stRef:instanceID>uuid:d34cbf16-4c87-4344-a0db-6cf67ffe6f84</stRef:instanceID>
        <stRef:documentID>xmp.did:fd9d95eb-fe2d-4fca-92a2-1906d98a10f4</stRef:documentID>
        <stRef:lastURL>file:///Users/superadmin/Downloads/266x165mm_VPA_WS_SP_M-1F/Links/bkgd_rgb_en.ai</stRef:lastURL>
    </stMfs:reference>
    </rdf:li>
    <rdf:li rdf:parseType="Resource">
      <stMfs:linkForm>ReferenceStream</stMfs:linkForm>
      <xmpMM:placedXResolution>72.00</xmpMM:placedXResolution>
      <xmpMM:placedYResolution>72.00</xmpMM:placedYResolution>
      <xmpMM:placedResolutionUnit>Inches</xmpMM:placedResolutionUnit>
      <stMfs:reference rdf:parseType="Resource">
        <stRef:instanceID>uuid:afd031b3-018a-434a-989f-c0e35ff0cebb</stRef:instanceID>
        <stRef:documentID>xmp.did:f4cbc476-258f-4807-8734-d8afc200fbfb</stRef:documentID>
        <stRef:lastURL>file:///Users/superadmin/Downloads/266x165mm_VPA_WS_SP_M-1F/Links/bax_logo_whitebox_cmyk.ai</stRef:lastURL>
      </stMfs:reference>
    </rdf:li>
  </rdf:Bag>
</xmpMM:Manifest>

1 Ответ

1 голос
/ 19 июня 2019

Эта проблема <stRef:instanceID> и <stRef:documentID> в <xmpMM:Manifest> <rdf:Bag>, не отраженная в мета-файле indd, возникает, когда:

  • Обновление ссылок вручную, нажав «Обновить ссылки» в палитре ссылок InDesign.
  • Или вообще не обновлять статус ссылок.

Вам необходимо программно обновить статус ссылок InDesign с помощью вашего скрипта после добавления отсутствующих DocumentID и InstanceID к связанному ресурсу. Для этого вы можете использовать следующую функцию:

/**
 * Update all document links whose state is outdated.
 * @param {Object} doc - A reference to the .indd to update.
 */
function updateOutdatedLinks(doc) {
  for (var i = 0, len = doc.links.length; i < len; i++) {
    var link = doc.links[i];
    if (link.status === LinkStatus.LINK_OUT_OF_DATE) {
      link.update();
    }
  }
}

script.jsx

Ниже приведена полная рабочая версия, которая добавит недостающие DocumentID и / или InstanceID к соответствующим ссылкам, а затем обновит свой статус в .indd

#target indesign

$.level=0;

// Warn if there are no documents open.
if (!app.documents.length) {
  alert('Open a document and try again.', 'Missing Document', false);
  exit();
}

var doc = app.activeDocument;

/**
 * Loads the AdobeXMPScript library.
 * @returns {Boolean} True if the library loaded successfully, otherwise false.
 */
function loadXMPLibrary() {
  if (!ExternalObject.AdobeXMPScript) {
    try {
      ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
    } catch (e) {
      alert('Failed loading AdobeXMPScript library\n' + e.message, 'Error', true);
      return false;
    }
  }
  return true;
}

/**
 * Checks the status of all Indesign links, and exits if the state is not OK.
 * @param {Object} doc - A reference to the .indd to check.
 * @returns {Boolean} True if the state of all links are OK, otherwise false.
 */
function linksStatusCheck(doc) {
  for (var i = 0, len = doc.links.length; i < len; i++) {
    if (doc.links[i].status !== LinkStatus.NORMAL) {
      alert('The status of all links must be OK \nPlease update link status ' +
          'via the Links panel and try again', 'Link Status', true);
      exit();
    }
  }
  return true;
}

/**
 * Generate a unique identifier (UUID/GUID). Note this runs on macOS only.
 * @returns {String} - The generated unique identifier.
 */
function generateUUID() {
  var cmd = 'do shell script "uuidgen | tr -d " & quoted form of "-"';
  return app.doScript(cmd, ScriptLanguage.applescriptLanguage);
}

/**
 * Add an XMP property and value to a given file.
 * @param {String} filePath - Path to the file/asset to add the XMP metadata.
 * @param {String} xmpProperty - Name of the XMP property.
 * @param {String} xmpValue - Value to assign to the XMP property.
 */
function addXmpPropertyAndValue(filePath, xmpProperty, xmpValue) {
  var xmpFile = new XMPFile(filePath, XMPConst.FILE_UNKNOWN, XMPConst.OPEN_FOR_UPDATE);
  var xmp = xmpFile.getXMP();

  xmp.setProperty(XMPConst.NS_XMP_MM, xmpProperty, xmpValue);

  if (xmpFile.canPutXMP(xmp)) {
    xmpFile.putXMP(xmp);
  }

  xmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
}

/**
 * Add an `instanceID` to the XMP packet of a file/asset.
 * @param {String} filePath - Path to the file/asset to add the XMP metadata.
 * @param {String} uuid - The unique identifier (UUID/GUID) value to add.
 */
function addInstanceID(filePath, uuid) {
  addXmpPropertyAndValue(filePath, 'InstanceID', 'xmp.iid:' + uuid);
}

/**
 * Add an `documentID` to the XMP packet of a file/asset.
 * @param {String} filePath - Path to the file/asset to add the XMP metadata.
 * @param {String} uuid - The unique identifier (UUID/GUID) value to add.
 */
function addDocumentID(filePath, uuid) {
  addXmpPropertyAndValue(filePath, 'DocumentID', 'xmp.did:' + uuid);
  addXmpPropertyAndValue(filePath, 'OriginalDocumentID', 'xmp.did:' + uuid);
}

/**
 * Adds both `instanceID` and `documentID` to the XMP packet of a file/asset.
 * Note: Both properties share the same unique identifier (UUID/GUID).
 * @param {String} filePath - Path to the file/asset to add the XMP metadata.
 * @param {String} uuid - The unique identifier (UUID/GUID) value to add.
 */
function addDocumentIDAndInstanceID(filePath) {
  var uuid = generateUUID();
  addInstanceID(filePath, uuid);
  addDocumentID(filePath, uuid);
}

/**
 * Checks both XMP properties, `DocumentID` and `instanceID`, exist in each
 * linked file associated with an InDesign document (.indd). When a link does
 * not contain the aforementioned properties a new one is added.
 * @param {Object} doc - A reference to the .indd to check.
 */
function checkLinksXMP(doc) {
  for (var i = 0, len = doc.links.length; i < len; i++) {

    var link = doc.links[i];
    var linkFilepath = File(link.filePath).fsName;
    var linkFileName = link.name;

    var xmpFile = new XMPFile(linkFilepath, XMPConst.FILE_INDESIGN, XMPConst.OPEN_FOR_READ);
    var xmp = xmpFile.getXMP();

    // Retrieve values from external links XMP.
    var documentID = xmp.getProperty(XMPConst.NS_XMP_MM, 'DocumentID', XMPConst.STRING);
    var instanceID = xmp.getProperty(XMPConst.NS_XMP_MM, 'InstanceID', XMPConst.STRING);

    // Add missing XMP property/values...
    if (!documentID && !instanceID) {
      addDocumentIDAndInstanceID(linkFilepath);
    } else if (!documentID) {
      addDocumentID(linkFilepath, generateUUID());
    } else if (!instanceID) {
      addInstanceID(linkFilepath, generateUUID());
    }
  }
}

/**
 * Update all document links whose state is outdated.
 * @param {Object} doc - A reference to the .indd to update.
 */
function updateOutdatedLinks(doc) {
  for (var i = 0, len = doc.links.length; i < len; i++) {
    var link = doc.links[i];
    if (link.status === LinkStatus.LINK_OUT_OF_DATE) {
      link.update();
    }
  }
}

if (loadXMPLibrary() && linksStatusCheck(doc)) {
  checkLinksXMP(doc);
  updateOutdatedLinks(doc); // <-- Update status after.
}

Примечания:

  1. Обратите внимание, как после проверки и обновления любых пропущенных DocumentID или InstanceID мы вызываем функцию updateOutdatedLinks, т.е. видим эту часть в скрипте:

    // ...
    
    if (loadXMPLibrary() && linksStatusCheck(doc)) {
      checkLinksXMP(doc);
      updateOutdatedLinks(doc); // <-- Update status after.
    }
    
  2. Также (как примечание) вы можете видеть, что в функцию checkLinksXMP мы включили следующую условную логику, то есть эту часть ниже:

    // Add missing XMP property/values...
    if (!documentID && !instanceID) {
      addDocumentIDAndInstanceID(linkFilepath);
    } else if (!documentID) {
      addDocumentID(linkFilepath, generateUUID());
    } else if (!instanceID) {
      addInstanceID(linkFilepath, generateUUID());
    }
    

    Обратите внимание, что если отсутствуют оба documentID && instanceID (т.е. первое условие выше), мы используем один и тот же UUID / GUID для обоих значений. Обратитесь к логике в функции addDocumentIDAndInstanceID, в которой вы видите, что один и тот же UUID / GUID является общим для обоих свойств.

  3. В дополнение к вышеприведенному сценарию вам потребуется добавить дополнительные функции, которые сохраняют изменения, внесенные в .indd после вызова функции updateOutdatedLinks. Э.Г.

    if (loadXMPLibrary() && linksStatusCheck(doc)) {
      checkLinksXMP(doc);
      updateOutdatedLinks(doc);
      doc.save(); // <-- Also ddd this to save the `.indd`
    }
    
  4. Заменить функцию generateUUID на что-то, что работает кроссплатформенно .

...