ExtendScript не включает объект JSON со связанными методами для синтаксического анализа, а именно JSON.parse()
и JSON.stringify()
. Он также не предоставляет никакой другой встроенной функции для анализа JSON.
Решение:
Попробуйте использовать polyfill для обеспечения функциональности JSON, например JSON-js , созданный Дугласом Крокфордом.
Что вам нужно сделать:
Загрузите файл JavaScript с именем json2.js из репозитория Github и сохраните его в том же месте / папке, что и ваш файл .jsx
.
Примечание Вы можете просто скопировать и вставить raw версию json2.js из того же репозитория Github, чтобы вручную создать файл json2.js , если вы предпочитают.
Затем в верхней части текущего файла .jsx
вам потребуется #include
файл json2.js
, добавив следующую строку кода:
#include "json2.js";
Это аналогично тому, как вы можете использовать оператор import
для включения модуля в современный JavaScript (ES6).
A pathname для местоположения json2.js
может быть предоставлено, если вы решите сохранить файл в другом месте / папке, чем ваш .jsx
файл.
Включив json2.js
в ваш файл .jsx
, вы получите рабочие методы JSON; JSON.parse()
и JSON.stringify()
.
* * Пример тысяча шестьдесят-два: * * тысяча шестьдесят-три
Следующий ExtendScript (.jsx
) является рабочим примером, который генерирует JSON для указания всех ссылок, связанных с текущим документом InDesign (.indd
).
example.jsx
#include "json2.js";
$.level=0;
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;
}
/**
* Obtains the values f XMP properties for `DocumentID` and `instanceID` in
* each linked file associated with an InDesign document (.indd). A returns the
* information formatted as JSON,
* @param {Object} doc - A reference to the .indd to check.
* @returns {String} - The information formatted as JSON.
*/
function getLinksInfoAsJson(doc) {
var linksInfObj = {};
linksInfObj['indd-name'] = doc.name;
linksInfObj.location = doc.filePath.fsName;
linksInfObj.links = [];
for (var i = 0, len = doc.links.length; i < len; i++) {
var linkFilepath = File(doc.links[i].filePath).fsName;
var linkFileName = doc.links[i].name;
var xmpFile = new XMPFile(linkFilepath, XMPConst.FILE_INDESIGN, XMPConst.OPEN_FOR_READ);
var allXMP = xmpFile.getXMP();
// Retrieve values from external links XMP.
var documentID = allXMP.getProperty(XMPConst.NS_XMP_MM, 'DocumentID', XMPConst.STRING);
var instanceID = allXMP.getProperty(XMPConst.NS_XMP_MM, 'InstanceID', XMPConst.STRING);
// Ensure we produce valid JSON...
// - When `instanceID` or `documentID` values equal `undefined` change to `null`.
// - When `instanceID` or `documentID` exist ensure it's a String.
instanceID = instanceID ? String(instanceID) : null;
documentID = documentID ? String(documentID) : null;
linksInfObj.links.push({
'name': linkFileName,
'path': linkFilepath,
'docId': documentID,
'insId': instanceID
});
}
return JSON.stringify(linksInfObj, null, 2);
}
if (loadXMPLibrary()) {
var linksJson = getLinksInfoAsJson(doc);
$.writeln(linksJson);
}
Выход:
Запуск приведенного выше сценария приведет к записи в формате JSON, как показано в следующем примере, на вашу консоль:
{
"indd-name": "foobar.indd",
"location": "/path/to/the/document",
"links":[
{
"name": "one.psd",
"path": "/path/to/the/document/links/one.psd",
"docId": "5E3AE91C0E2AD0A57A0318E078A125D6",
"insId": "xmp.iid:0480117407206811AFFD9EEDCD311C32"
},
{
"name": "two.jpg",
"path": "/path/to/the/document/links/two.jpg",
"docId": "EDC4CCF902ED087F654B6AB54C57A833",
"insId": "xmp.iid:FE7F117407206811A61394AAF02B0DD6"
},
{
"name": "three.png",
"path": "/path/to/the/document/links/three.png",
"docId": null,
"insId": null
}
]
}
Sidenote: Моделирование вашего JSON:
Вы заметили, что вывод JSON (см. Выше) структурирован иначе, чем вы пытались структурировать его в данном примере. Основное отличие состоит в том, что вы использовали имена ссылок в качестве имен свойств / ключей, например, в следующем примере:
Пример проблемной структуры JSON
{
"one.psd": {
"docId": "5E3AE91C0E2AD0A57A0318E078A125D6",
"insId": "xmp.iid:0480117407206811AFFD9EEDCD311C32"
},
"two.jpg": {
"docId": "EDC4CCF902ED087F654B6AB54C57A833",
"insId": "xmp.iid:FE7F117407206811A61394AAF02B0DD6"
}
...
}
Создание JSON, подобного этому примеру, не идеально, потому что если бы у вас было две ссылки с одинаковым именем, вы бы сообщали только об одной из них. У вас не может быть двух свойств / ключей с одинаковым именем в объекте.
Edit:
В ответ на комментарий ОП:
Привет, RobC, кроме использования #include 'json2.js'
, есть ли другой способ включить внешний файл js в файл JSX?
Существует несколько альтернативных способов:
Вы можете использовать $.evalFile()
. Например, замените #include "json2.js";
на следующие две строки:
var json2 = File($.fileName).path + "/" + "json2.js";
$.evalFile(json2);
Примечание: В этом примере предполагается, что json2.js
находится в той же папке, что и ваш .jsx
В качестве альтернативы, если вы хотите полностью избежать существования дополнительного файла json2.js
. Вы можете добавить IIFE (выражение для немедленного вызова функции) вверху файла .jsx
. Затем скопируйте и вставьте в него содержимое файла json2.js . Например:
(function () {
// <-- Paste the content of `json2.js` here.
})();
Примечание: Если размер кода является проблемой, рассмотрите минимизацию содержимого json2.js
перед вставкой его в IIFE.