Эта проблема <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.
}
Примечания:
Обратите внимание, как после проверки и обновления любых пропущенных DocumentID
или InstanceID
мы вызываем функцию updateOutdatedLinks
, т.е. видим эту часть в скрипте:
// ...
if (loadXMPLibrary() && linksStatusCheck(doc)) {
checkLinksXMP(doc);
updateOutdatedLinks(doc); // <-- Update status after.
}
Также (как примечание) вы можете видеть, что в функцию 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 является общим для обоих свойств.
В дополнение к вышеприведенному сценарию вам потребуется добавить дополнительные функции, которые сохраняют изменения, внесенные в .indd
после вызова функции updateOutdatedLinks
. Э.Г.
if (loadXMPLibrary() && linksStatusCheck(doc)) {
checkLinksXMP(doc);
updateOutdatedLinks(doc);
doc.save(); // <-- Also ddd this to save the `.indd`
}
Заменить функцию generateUUID
на что-то, что работает кроссплатформенно .