Copy link to clipboard
Copied
I've made a script in CEP/jsx that lists the document structure of a given node in the document. E.g. I can ask for "app.activeDocument.graphicLines" and get back a JSON for all lines in the document (se screenshot "CEP_getJson_graphicLines.png"), or if I want the whole document I ask for "app.activeDocument.pageItems" (see screenshot "CEP_getJson_pageItems.png")
I want to do the same in UXP, i.e. get back every item / node in the document structure in JSON, but no luck so far
Has anyone done this?
Copy link to clipboard
Copied
Could you tell me which InDesign DOM API is exactly not working as expected in UXP scripting?
Copy link to clipboard
Copied
I was hoping to be able to do something like this
<script>
const id = require("indesign");
const app = id.app;
console.log(app.activeDocument);
console.log(JSON.stringify(app.activeDocument));
</script>
But I can't stringify the object, I only get this in the console
Document {}
{}
I.e. stringify doesn't work. It seems like everything in the object is functions (+ it is recursive), so I had to make a workaround that loops through the whole object up to a certain level and generate a new object.
Is there any way of getting the document as a "normal JSON object"?
Copy link to clipboard
Copied
These InDesign DOM APIs in UXP mimic the exact behaviour as in ExtendScript/CEP. I see the same behaviour in ExtendScript and UXP on executing alert(app.activeDocument).
So, I wonder how you were able to generate the JSON string from app.activeDocument in CEP.
Copy link to clipboard
Copied
TLDR; I've gone for getting exactly the data I need in UXP instead of trying to serialize big chunks of the document structure
This is how I do it in CEP / ES3 (beware of terrible code):
Let's say I want all page items with data "two levels down", this is what I have in my main HTML page:
async function getObject(what) {
try {
let res = await runEvalScript(what);
return JSON.parse(res);
} catch (error) {
return [];
}
}
var pageItemsData = await getObject('objMain.getObjectFromIndesign("app.activeDocument.pageItems", 2)');
console.log(pageItemsData);
// push pageItemsData to server
and over to the "CEP-part":
#include './json2.jsx';
var doc = app.activeDocument;
// ES3 doesn't have much array functions, so let's use a string-hack instead
// Declare globaly
var dictionaryString = ''
function traverseObject(obj, loopLevel, dictionaryString, traverseLevels) {
if (loopLevel > traverseLevels) {
return { 'exitLoop': true };
}
loopLevel = loopLevel + 1;
var newObj = {};
for (var prop in obj) {
try {
if (obj.hasOwnProperty(prop) && obj[prop] !== null) {
// We could probably just keep as-is, but just to be sure
newObj[prop] = obj[prop].toString();
}
} catch (error) {
// Not much to do
}
if (newObj[prop] !== undefined) {
// Not sure we need to convert to string, but just to be sure...
var stringCheck = newObj[prop].toString();
if (stringCheck.indexOf('[object')) {
// Keep
} else if (prop === 'parent' || prop === 'events' || prop === 'eventListeners' || prop === 'properties' || prop === 'parentStory') {
// Ignore
delete newObj[prop];
} else {
// Traverse (original) object
if (dictionaryString.indexOf('|' + stringCheck + '|') > 0) {
// If we get a hit on this we probably have a loop / allready have the param
} else {
dictionaryString += stringCheck + '|';
newObj[prop] = traverseObject(obj[prop], loopLevel, dictionaryString, traverseLevels);
}
}
}
}
return newObj;
}
var objMain = {};
objMain.getObjectFromIndesign = function(object, traverseLevels) {
if (object === undefined || object === '') {
return [];
}
var returnObject = [];
var looper = eval(object);
for (var i = 0; i < looper.length; i++) {
var obj = looper[i];
// ES3 doesn't have much array functions, so let's use a string-hack instead to keep track of duplicates
dictionaryString = '|';
var newObj = traverseObject(obj, 0, dictionaryString, traverseLevels);
returnObject.push(newObj);
}
return JSON.stringify(returnObject);
}
const id = require("indesign");
const app = id.app;
const graphicLines = [];
for (i = 0; i < app.activeDocument.graphicLines.length; i += 1) {
const fields = {
name: app.activeDocument.graphicLines.item(i).name,
strokeWeight: app.activeDocument.graphicLines.item(i).strokeWeight,
fillColor: {
name: app.activeDocument.graphicLines.item(i).fillColor.name,
},
}
graphicLines.push(fields);
}
console.log(graphicLines);
// send graphicLines to server
That said; if there is a solution to getting complete JSON (up to a level) for e.g. graphicLines, I would appreciate to se how it is done 🙂
Copy link to clipboard
Copied
Where exactly do you fail in UXP script? Can you share some examples, what does the method getObjectFromInDesign require as an input and what do you get instead when you run the DOM API call in UXP?
-Manan
Copy link to clipboard
Copied
The screenshot is from a CEP plugin I made. With the new (beta) release of UXP scripting for InDesign we're scrapping CEP and moving to UXP
The problem now is to get a JSON object I can serialize and push to the server, i.e. the previous comment I made further up in this thread
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more