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

Copy grouped object and xml structure

New Here ,
Feb 10, 2023 Feb 10, 2023

Copy link to clipboard

Copied

Hi, 

I Use either UXP or classic Extendscript, and want to do the following:

Duplicate a group of items that all has xml tags in this form:

screen.png

 

  • On the page there is an empty textframe tagged with <product>
  • The textframe is tagged with <texts> and conatins two tags: <title> and <body>.
  • the picture is located in a dummy tag <pics> and is tagged with <pic>.

 

All items is grouped and located on a master page.

With a script, I then  want to:

  1. Duplicate the group.
  2. Move the items to a page in the document.
  3. Duplicate all tags in the structure, so they are identical, but directly under the Root.

 

Problem:

I end up with either just duplicating the structure, but then the reference to the items on the page is lost

OR

I end up with duplicating the items on the page, but then the tags does not move along with it, like in this picture, they get stuck in their original location. (Only the <product> tag and the dummy <pics> tag are moved. The rest is still in their original position in the structure.

screen_dupe.png

 

If I use app.copy() the items and the structure is copied correctly. But this means I have to select the items with the script and then use copy. I would rather use duplicate.

 

So... duplicate is different from copy.

 

Is there a way to duplicate items and the xml structure?

 

 

 

 

TOPICS
Scripting

Views

729

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

People's Champ , Feb 11, 2023 Feb 11, 2023

Here is a jsx approach. The idea is to export the group as a snippet (idms), then place this one on the destination page. This approach has many advantages:

- Not specifically resource consuming

- xml structure is preserved

- xml product node is found at the root level

- simple to manage

 

var doc  = app.activeDocument;
var root = doc.xmlElements.item(0);
var product = root.evaluateXPathExpression("./Masters/Product");
if(product.length){
    product = product[0];
    var xc = product.xmlContent;
    
...

Votes

Translate

Translate
People's Champ ,
Feb 11, 2023 Feb 11, 2023

Copy link to clipboard

Copied

Here is a jsx approach. The idea is to export the group as a snippet (idms), then place this one on the destination page. This approach has many advantages:

- Not specifically resource consuming

- xml structure is preserved

- xml product node is found at the root level

- simple to manage

 

var doc  = app.activeDocument;
var root = doc.xmlElements.item(0);
var product = root.evaluateXPathExpression("./Masters/Product");
if(product.length){
    product = product[0];
    var xc = product.xmlContent;
    if(xc.constructor.name==="Story"){
        var tf = xc.textContainers[0];
        var gp = tf.parent;
        if(gp.constructor.name=="Group"){
            var tmpFile = File(Folder.temp+"/temp.idms");
           gp.exportFile(ExportFormat.INDESIGN_SNIPPET, tmpFile);
           doc.pages.item(0).place(tmpFile);
           tmpFile.remove();
        }
    }
}

 

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
New Here ,
Feb 13, 2023 Feb 13, 2023

Copy link to clipboard

Copied

Hi Loic,

 

Great solution! I just was not into thinking like that.
You are a great recourse to this community!

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
New Here ,
Feb 16, 2023 Feb 16, 2023

Copy link to clipboard

Copied

Hi @Loic.Aigon .

It works But if the temp.idms file does not already exists I get this error when it comes to the line with doc.pages.item(0).place(tmpFile)

JavaScript Error!
Error Number: 29446
Error String: Either the file does not exist, you do not have permission, or the file may be in use by another application

But, the file is created and is present in the directory when this code has been run:

gp.exportFile(ExportFormat.INDESIGN_SNIPPET, File(tmpFile))

 

So.. next time i run it, it works, but then the file is removed with tmpFile.remove(), since the script manage to run fully.

And then next time it generates the error again.

 

Tried creating a file just before the exportFile line, with
tmpFile.open('w'); tmpFile.write(); tmpFile.close();

But same error.

Tried adding a $.SLEEP(2000) right after the export, but no help...

 

Any ideas?

 

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
People's Champ ,
Feb 16, 2023 Feb 16, 2023

Copy link to clipboard

Copied

My bad, it's likely your error is due to the little typo:

gp.exportFile(ExportFormat.INDESIGN_SNIPPET, File(tmpFile));

given that tmpFile is already a File instance.

So 

gp.exportFile(ExportFormat.INDESIGN_SNIPPET, tmpFile);

would be preferable.

Once that said, you may want to check if the problem is for writing the file itself by using

gp.exportFile(ExportFormat.INDESIGN_SNIPPET, tmpFile);

if(tmpFile.exists) //then place

or if problem persists

try{

//the whole code

}

catch(err){

alert(err.line+"//"+err.message);

}

It may send you back though at the error message you get implying a possible permission issue. However, it would be surprising given that we use the temp folder.

You can try using teh desktop instead to give it a try:

tmpFile = File(Folder.desktop+"/temp.idms");

gp.exportFile(ExportFormat.INDESIGN_SNIPPET,tmpFile);

 

This should work, no need to use sleep. 

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
New Here ,
Feb 16, 2023 Feb 16, 2023

Copy link to clipboard

Copied

Something fishy is going on.

I had already noticed the extra File instance, but it generates the same result either way.

Tried this on two different computers, but with same result.

The curious thing, that leads me to thinking that this is permission related, is that if I set the tmpFile to a new folder, and run the script, it works. The first time, even if there is no file present in that folder, since it's the first time I run it. Try it again and it fails like before. So, only the first time works like it should.

 

I have tried:

  • Try/Catch, same error.
  • Change to different folders, like desktop etc.
  • Changing tmpFile = File(... to tmpFile = new File(...

Always the same result, with referene to this line: 

doc.pages.item(0).place(tmpFile);
Is there something wrong with tmpFile.remove()? Maybe Indesign locks the file, even if it does not exist and next time the script runs, the file gets created and is instantly locked?
I'm just guessing now....
 
Just tried restarting Indesign between the runs = success = Indesign seems to lock the file?.
If I run the script once and it works, then Undo (ctrl+z) once and run it again it works, every time.
 
My latest attempt with a copy of the file = same result:

 

try{
    var doc  = app.activeDocument;
    var root = doc.xmlElements.item(0);
    var product = root.evaluateXPathExpression("./Masters/Product");
    if(product.length){
        product = product[0];
        var xc = product.xmlContent;
        if(xc.constructor.name==="Story"){
            var tf = xc.textContainers[0];
            var gp = tf.parent;
            if(gp.constructor.name=="Group"){
                var tmpFile = File(Folder.temp+"/temp.idms");

                tmpFile.copy(Folder.temp+"/temp2.idms");
                tmpFile2 = File(Folder.temp+"/temp2.idms");

                gp.exportFile(ExportFormat.INDESIGN_SNIPPET, tmpFile2);

                doc.pages.item(0).place(tmpFile2);
                tmpFile.remove();
                tmpFile2.remove();
                
            }
        }
    }
} 
catch(err){
    alert(err.line+"//"+err.message);
}

 

 

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
People's Champ ,
Feb 16, 2023 Feb 16, 2023

Copy link to clipboard

Copied

LATEST

Not a permission issue, I get that behaviour too after I run the script a few times. Obviously, there may be some I/O issues. There would a solution using async export and monitoring background task execution but it seems overkilling for your need.

The other solution is to get back to duplication and dealing with tag and structure. The only issue then is to ensure that you can rely on some by default structure. Will your "product" masters always built the same way?

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 ,
Feb 16, 2023 Feb 16, 2023

Copy link to clipboard

Copied

But in order to duplicate something - you need to have a reference to it - so if you have a reference - what is the problem with copying it? 

 

Can you show part of your code where you try to duplicate? What is the destination? 

 

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