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

Libraries to stringify extendScript objects?

Engaged ,
Aug 12, 2020 Aug 12, 2020

Copy link to clipboard

Copied

   Has anyone come across anything like JSON.strigify() for native illustrator objects?  I'm looking for a was to stringify and parse objects and type. I've tried a couple JSON implimentations suggested in other posts, but I get stack overrun errors on stringify().

TOPICS
Scripting

Views

776

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
Adobe
Enthusiast ,
Aug 12, 2020 Aug 12, 2020

Copy link to clipboard

Copied

Do you mean using JSON.stringify for any object within a JSX file, or using JSON.stringify on specific objects like app? If the latter there shouldn't be a need to grab every single property and method of a given native object. What are you actually trying to achieve?

 

What code gives you the stack overrun error?

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
Engaged ,
Aug 12, 2020 Aug 12, 2020

Copy link to clipboard

Copied

   I need to be able to re-create groups with path items, complex paths, point text, etc. from within a script.  The exact configuration of the objects may change frequenty so I can't hard code the object creation - I need a way to quickly stringify a group so it can be embedded/updated as a variable in a script that will then parse it back into the document.

 

The stack overrun comes if I create a basic rectangle in illustrator and then try JSON.stringify() on it. I've tried 3 different JSON libraries that I've found.  But all seem to get into infinite loops trying to work with the Layers... I think because of child/parent circular relationships...

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 12, 2020 Aug 12, 2020

Copy link to clipboard

Copied

Can you give an example? By "re-create" do you just mean duplicate? Why not select the objects, copy them to clipboard, then pasteInFront, clear selection?

 

You're trying to JSON.stringify them to return them to a CEP panel? What's the need for JSON.stringify?

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 12, 2020 Aug 12, 2020

Copy link to clipboard

Copied

Not sure I understand what you mean by this part referring to JSON.stringify:

"I need a way to quickly stringify a group so it can be embedded/updated as a variable in a script that will then parse it back into the document."

 

Is this the same script or a separate script?

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
Explorer ,
Aug 13, 2020 Aug 13, 2020

Copy link to clipboard

Copied

One approach could be to do it via SVG.

 

You can export/import SVGs to the filesystem, or you may be able to take advantage of a clipboard hack...

When you copy a selection to the clipboard in Illustrator it serialises it to SVG.


As far as I can tell illustrator doesn't provide a method to directly access the clipboard contents (although there are some workarounds on Windows to do this), but what you should be able to do is create a temporary textframe on the document and paste the clipboard contents into its content property, then read the content back into your javascript to get the raw SVG text.

To paste the SVG back into the file you'd do the reverse.

Copying the text to the clipboard may be a bit tricky, but there seem to be a few discussions about how to do it, like this one: https://community.adobe.com/t5/illustrator/is-it-possible-to-copy-text-to-the-clipboard-in-illustrat...

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
Valorous Hero ,
Aug 13, 2020 Aug 13, 2020

Copy link to clipboard

Copied

#target illustrator
function test () {

	"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(t){return 10>t?"0"+t:t}function quote(t){
		return escapable.lastIndex=0,escapable.test(t)?'"'+t.replace(escapable,function(t){var e=meta[t];
			return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}
		function str(t,e){var n,r,o,f,u,i=gap,p=e[t];switch(p&&"object"==typeof p&&"function"==typeof p.toJSON&&(p=p.toJSON(t)),
			"function"==typeof rep&&(p=rep.call(e,t,p)),typeof p){case"string":return quote(p);case"number":return isFinite(p)?String(p):"null";
		case"boolean":case"null":return String(p);case"object":if(!p)return"null";if(gap+=indent,u=[],"[object Array]"===Object.prototype.toString.apply(p)){
			for(f=p.length,n=0;f>n;n+=1)u[n]=str(n,p)||"null";return o=0===u.length?"[]":gap?"[\n"+gap+u.join(",\n"+gap)+"\n"+i+"]":"["+u.join(",")+"]",gap=i,o}
				if(rep&&"object"==typeof rep)for(f=rep.length,n=0;f>n;n+=1)"string"==typeof rep[n]&&(r=rep[n],o=str(r,p),o&&u.push(quote(r)+(gap?": ":":")+o));
			else for(r in p)Object.prototype.hasOwnProperty.call(p,r)&&(o=str(r,p),o&&u.push(quote(r)+(gap?": ":":")+o));return o=0===u.length?"{}":gap?"{\n"+gap+
			u.join(",\n"+gap)+"\n"+i+"}":"{"+u.join(",")+"}",gap=i,o}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){
				return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+
				f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){
					return this.valueOf()});var cx,escapable,gap,indent,meta,rep;"function"!=typeof JSON.stringify&&
			(escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
				meta={"\b":"\\b","  ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(t,e,n){var r;
					if(gap="",indent="","number"==typeof n)for(r=0;n>r;r+=1)indent+=" ";else"string"==typeof n&&(indent=n);if(rep=e,
						e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw new Error("JSON.stringify");return str("",{"":t})}),
			"function"!=typeof JSON.parse&&(cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
				JSON.parse=function(text,reviver){function walk(t,e){var n,r,o=t[e];if(o&&"object"==typeof o)for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&
				(r=walk(o,n),void 0!==r?o[n]=r:delete o[n]);return reviver.call(t,e,o)}var j;if(text=String(text),cx.lastIndex=0,cx.test(text)&&
					(text=text.replace(cx,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),
					/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@")
						.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]")
						.replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;
				throw new SyntaxError("JSON.parse")})}();

	function ArtNode (typename, name, note, children, extraProps) {
		this.typename = typename;
		this.name = name;
		this.note = note;
		if (typename == "GroupItem") {
			this.children = children || [];
		}
		if (extraProps) {
			for (var all in extraProps) {
				this[all] = extraProps[all];
			}
		}
	};
	function getArtTree (rootArt) {
		function getNodeInfo (art) {
			var thisTypename = art.typename;
			var extraProps = null;
			switch (thisTypename) {
				case "TextFrame":
					extraProps = { "contents" : art.contents };
					break;
				case "SymbolItem":
					extraProps = { "symbol_name" : art.symbol.name };
					break;
				default:
					break;
			}
			var children = null;
			if (thisTypename == "GroupItem") {
				children = [];
				var thisPageItem, newObj;
				for (var i = 0; i < art.pageItems.length; i++) {
					thisPageItem = art.pageItems[i];
					newObj = getNodeInfo(thisPageItem);
					children.push(newObj);
				}
			}
			var thisNode = new ArtNode(
				thisTypename,
				art.name,
				art.note,
				children,
				extraProps
			);
			return thisNode;
		};
		return getNodeInfo(rootArt);
	};
	var doc = app.activeDocument;
	var sel = doc.selection[0];
	var treeObj = getArtTree(sel);
	alert(JSON.stringify(treeObj, null, 2));
};
test();​

Silly-V_0-1597332741560.png

 

{
  "typename": "GroupItem",
  "name": "",
  "note": "",
  "children": [
    {
      "typename": "GroupItem",
      "name": "",
      "note": "",
      "children": [
        {
          "typename": "TextFrame",
          "name": "MyText",
          "note": "",
          "contents": "hey!"
        },
        {
          "typename": "GroupItem",
          "name": "SpecialGroup",
          "note": "",
          "children": [
            {
              "typename": "GroupItem",
              "name": "",
              "note": "",
              "children": [
                {
                  "typename": "PathItem",
                  "name": "",
                  "note": "Note here."
                },
                {
                  "typename": "SymbolItem",
                  "name": "",
                  "note": "",
                  "symbol_name": "Gerbera"
                }
              ]
            },
            {
              "typename": "PathItem",
              "name": "",
              "note": ""
            }
          ]
        },
        {
          "typename": "GroupItem",
          "name": "",
          "note": "",
          "children": [
            {
              "typename": "PathItem",
              "name": "",
              "note": "A note."
            },
            {
              "typename": "PathItem",
              "name": "MyRect",
              "note": "MyRect's note."
            }
          ]
        }
      ]
    },
    {
      "typename": "CompoundPathItem",
      "name": "",
      "note": ""
    }
  ]
}

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
Valorous Hero ,
Aug 13, 2020 Aug 13, 2020

Copy link to clipboard

Copied

LATEST

Ugh these forums are driving me nuts. 

It took out all my text commentary but - it said"
Try this, the image here produces the following output there.

You can add shared properties such as x/y coordinates that are shared by all art items directly on the ArtNode class, and add any custom property which may contain any kind of data by adding statements to the switch block. In my example, you can see I've got a symbolItem's symbol name and a text frame's contents. In a similar way you could get fill or stroke colors widths & overprints of a pathItem.

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