• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

#targetengite directive never works with #include directive

Community Beginner ,
Aug 13, 2024 Aug 13, 2024

Copy link to clipboard

Copied

Imagine you have files

  • main.jsx
  • utils.jsx

In "main.jsx" you specify #target, #targetengine directives so some of your variables could be persistent and use #include to get your utils functions so you could use them later.

 

And... Here you go, your values are not persistent. They become persistent only if you get rid of #include statement. Is it intended behaviour? How do i make #targetengine work and keep my variables at next script run with #include directive? Unfortunately i can't serialize my values to string and save it later so session is my only option.

Example code below:

--- main.jsx ---

 

#target illustrator
#targetengine "session001"

#include 'utils.jsx';


if (isNaN(foo)) var foo = 0;

foo += 2;

alert(foo);

 

--- utils.jsx ---

 

var bar = null;

 

 

 
 

 

 

TOPICS
Bug , How-to , Scripting

Views

264

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Aug 13, 2024 Aug 13, 2024

Hi @some_5675, DOM reference in Illustrator are fragile, so I wouldn't waste any time trying to keep one. They are broken by many common actions, such as closing/re-opening the document, or simply adding or removing a page item "before" the reference page item (altering the DOM "after" the page item should be fine).

 

One of your problems is the speed to retrieve your page items graph. Have you tried using 

var myItem = doc.getPageItemFromUuid(myPageItemID);

exclusively to create your graph? Is

...

Votes

Translate

Translate
Adobe
Enthusiast ,
Aug 13, 2024 Aug 13, 2024

Copy link to clipboard

Copied

It seems `targetengine` may not be supported in newer versions of Ai (docs), but I've never used that directive so I don't know for sure (docs just may be old). It is hard to tell what you are trying to accomplish with your code but if you need something to persist you could always write it to a file (and read it later) or use `$.setenv()` and `$.getenv()`. I use both options a lot with "include" files and it works great.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 13, 2024 Aug 13, 2024

Copy link to clipboard

Copied

Thank you for the reply. It's a pitty if it not works that way.

quote

It is hard to tell what you are trying to accomplish with your code

Screenshot_9.png

I have graph-like structure inside SVG. Each item is a native PathItem object. I parse all objects from layer and build graph structure to manipulate it later but it builds everytime i run the script and could take a while. I want to keep the data i parsed last time.

 

I tried to use json2 library but it refuses to serialize my object (probably because it has PathItem objects inside and they are not serializable) and script fails without an error. So i need a way to somehow keep my data persistent.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 13, 2024 Aug 13, 2024

Copy link to clipboard

Copied

You can save "JSON-like" data to a file and read it back using `eval()` (docs) without an external library.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 13, 2024 Aug 13, 2024

Copy link to clipboard

Copied

Thanks, will check it closer. But i think it obviously will not keep reference of PathItem for me so i won't be able to manipulate with certain item like change it's color and i'll need to parse all references again, right?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 13, 2024 Aug 13, 2024

Copy link to clipboard

Copied

Yep, you could give the items a tag or see if they have a uuid already assigned, then use those as a reference.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 13, 2024 Aug 13, 2024

Copy link to clipboard

Copied

Also forgot to mention that if i serialize data to string i will definitely will loose PathItem reference on retrieving so i will need to acquire/parse it again. So session and keeping runtime variables is my best option.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 13, 2024 Aug 13, 2024

Copy link to clipboard

Copied

Sorry, just saw this after posting my other comment. Yeah, you will not be able to serialize a built-in PathItem to my knowledge. Maybe you could take just the info you need from the path item (like point data) and serialize that for later manipulation.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 13, 2024 Aug 13, 2024

Copy link to clipboard

Copied

Hi @some_5675, DOM reference in Illustrator are fragile, so I wouldn't waste any time trying to keep one. They are broken by many common actions, such as closing/re-opening the document, or simply adding or removing a page item "before" the reference page item (altering the DOM "after" the page item should be fine).

 

One of your problems is the speed to retrieve your page items graph. Have you tried using 

var myItem = doc.getPageItemFromUuid(myPageItemID);

exclusively to create your graph? Is it too slow?

- Mark

 

P.S. As you noticed the JSON library cannot stringify DOM items. This is for two immediate reasons: (1) they contain cyclic structures that would cause JSON.stringify to loop forever if not aborted, eg. there are properties that return a parent object, which itself has properties that return the original child object, and (2) Illustrator crashes when trying to read some properties of some DOM items! Not to mention that you really don't want to serialize the entire thing—it can be quite long and slow process.

 

The usual approach is to provide JSON.stringify with a `replacer` function (and JSON.parse with a `reviver` function, if necessary). Here is a little example of a replacer for stringifying a PathItem:

/**
 * Example replacer for PathItem
 * @param {String|Number} [key] - the access key (default: undefined).
 * @param {*} value - the value to replace.
 * @returns {*?} - the value to serialize.
 */
function pathItemReplacer(key, value) {

    // unfortunately we have to try/catch here
    // because some DOM objects throw weird errors
    // for no good reasons
    try {

        if ('parent' === key)
            // parent objects usually cause cyclic structure
            // and we don't want them anyway
            return undefined;

        if ('Number' === key.constructor.name)
            // don't interfere with normal array access
            return value;

        if (
            'PathItem' === value.typename
            || 'PathPoint' === value.typename
        )
            // send this back for further serialising
            return value;

        switch (key) {

            case 'uuid':
            case 'anchor':
            case 'leftDirection':
            case 'rightDirection':
                // JSON can stringify these
                return value;

            case 'note':
                // only if exists
                return '' !== value ? value : undefined;

            case 'pointType':
                // special handling
                return String(value);

            case 'pathPoints':
                // JSON can't always handle "collections"
                // so return a normal Array
                var pathPoints = [];
                for (var i = 0; i < value.length; i++)
                    pathPoints[i] = value[i];
                return pathPoints;

            case 'fillColor':
            case 'strokeColor':
                // just for an example, we'll
                // only stringify a swatch name
                if (
                    value
                    && value.typename
                    && 'SpotColor' === value.typename
                )
                    return value.spot.name;

            default:
                // ignore everything else
                return undefined;

        };

    }

    catch (error) {
        // we definitely don't want anything that throws errors!
        return undefined;
    }

};

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 14, 2024 Aug 14, 2024

Copy link to clipboard

Copied

Much thanks for the clear answer. In the end i implemented script i need without keeping record of last graph structure and time it need to initialize is not hardcore and by far i can live with it.

 

Was not aware about 'getPageItemFromUuid'. Next time if i found myself in a performance issue i definitely will try it or the replacer function you suggested. Thanks.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 14, 2024 Aug 14, 2024

Copy link to clipboard

Copied

LATEST

Also some operations are very slow for no good reason, eg.

myPageItem.selected = true

So it is better to avoid selecting items individually and instead do, eg.

myDoc.selection = myArrayOfItems;

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines