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

script continues after after i stop running it.

Participant ,
Nov 15, 2017 Nov 15, 2017

Copy link to clipboard

Copied

So below is a script which opens ai files in a series of folder inside a main folder and saves them somewhere as a PDF.

The script works in that it loops through the available files and PDFs them. when i run this step by step it, it reaches the last file in the last folder and ends. When I just run it, it gets done with looping through and starts looping through again but not at the command of extendscript. I press stop script and the script stops but illustrator keeps looping endlessly though without extendscript. I have to force close Illustrator.

But as i said the loop has a stop in it. it works fine run step by step.

If anyone has any suggestions?

Here is the script(not very pretty):

//where to save to

var topFolder =Folder.selectDialog("Where?"); // Change me. Currently the script's folder.

x = 0

var up = false

const afolders

var descended = false

forEachDescendantFile(topFolder, doStuffIfdocument, up); // Don't change this line.

//checks that the file is ai and ends with TF. if so it is opened

function doStuffIfdocument(oFile) {

        var checkName = oFile.fsName

         if (checkName.search(".ai") > 1 && checkName.search("TF") > 1) {

        var document = app.open(oFile);

            try {

                doStuff(document);

            }

            catch (err){

                 document.close(SaveOptions.DONOTSAVECHANGES);

                

            }

            finally{

                if (x < afolders){

                    up = true

                forEachDescendantFile(topFolder, doStuffIfdocument, up)

                }

        }

    }

}

//saves it as a PDF

function doStuff(document) {

    var aiApp = app.activeDocument;

    saveName ="C:\\Users\\user\\Desktop\\TF PDF" + "\\" + aiApp.name;

    saveName = saveName.substring(0, saveName.length - 3);

    saveName = saveName + "_183"

    dest = new File (saveName);

    saveOpts = new PDFSaveOptions();

    saveOpts.pDFPreset = 'dane';

    aiApp.saveAs(dest, saveOpts);

    aiApp.close(SaveOptions.DONOTSAVECHANGES);

    } 

// loops though folders and files

function forEachDescendantFile(folder, callback, up) {

    var aChildren = folder.getFiles();

    if (this.descended == false){

        afolders = aChildren.length

    }

    for (var i = 0; i < aChildren.length; i++) {

        if (up == true){

            i = x

            up = false

        }

        var child = aChildren;

        if (child instanceof File) {

            callback(child);

        }

        else if (child instanceof Folder) {

            x += 1

            this.descended = true

            if (child.name != "CNX") {

                this.forEachDescendantFile(child, callback);

                }

            else if (x  > afolders){

                 //this should kill the script.

                 throw new Error("Something went badly Right!");

            }

            else{

                up = true

            }

        }

        else {

            throw new Error("The object at \"" + child.fullName + "\" is a child of a folder and yet is not a file or folder.");

        }

    }

}

TOPICS
Scripting

Views

1.0K

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 , Nov 15, 2017 Nov 15, 2017

ok, give this a try. I don't have a PC to test on, so it MIGHT take some minor debugging as it pertains to paths, but with mac paths this script seemed to work just fine to do what you wanted to do, at least as far as i understood the workflow. You'll also need to double check the PDFSaveOptions properties. I removed those from my testing because i didn't have a pdf preset called 'dane'.

Let me know how this works for you.

*EDIT*

woops. i put in some logic to handle files that caused errors during

...

Votes

Translate

Translate
Adobe
Participant ,
Nov 15, 2017 Nov 15, 2017

Copy link to clipboard

Copied

Hello again

an update on my above problem.

Yesterday this code keep throwing an error at the saveAs pdf, saying Illegel argument. Today the code worked ok for the morning. Then it started running off into an endless loop. Now the same code is calling up a Save As window in the Illlustrator window.

There must be something unstable about this code but have know idea what that could be.

If anyone has any Ideas it would be much appreciated.

Thanks,

Dane

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 ,
Nov 15, 2017 Nov 15, 2017

Copy link to clipboard

Copied

without looking all through it, the first thing that stands out is "i = x". If you ever need to adjust the counter of a loop that is driven by counter-based iteration, try to reformulate the function such that whichever goals you want to accomplish are accomplished with means other than this.

The thing which I would do is instead of processing inside a function which gets folders or files or children of folders is adding each file and any useful properties into an array. Then after all files are cataloged, that's where you can apply processing within this 'linear context', so your focus can be more on the processing instead of issues caused by the rest of the function.

Suppose you got an array which looks like this:

[{ file : "path/file.ai", folderNestedLevel : 1 }, { file : "path/file-2.ai", folderNestedLevel : 2 }]

Now you can go through the linear array and choose to stop based on any condition, or choose to simply omit certain files, or certain files based on folder nesting, or folder parent names if you put those into the array. This way the exclusion logic is separated from file-gathering logic and would make it easier to prevent bugs.

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 ,
Nov 15, 2017 Nov 15, 2017

Copy link to clipboard

Copied

You have an infinite loop (or more than one) written into your script.

It's hard to know for sure what's happening as i have to debug this line by line without the help of the IDE because i'd have to rewrite some stuff and generate a test directory with test files and subdirectories etc and i don't have time to do all that.

But some issues that jump right out at me is that you're declaring a const called afolders, but you're not initializing it. I think in most JS engines, this doesn't work, but apparently it does in illustrator. Anyway, later on in the script you're changing the value of afolders to the length of files in a given folder. const variables are not supposed to be changed, but again, apparently this is allowed.

Anyway, the meat of the problem is that you're constantly redefining the variable afolders and then checking it's value against the global variable x. As i looked through the code i couldn't identify a scenario in which x would be less than afolders, therefore the conditional block in your finally block will always execute.

That's where the infinite loop comes in. the function call in your finally block starts all the way over at the beginning. it's identical to the function call you make at the beginning of the script. So instead of recursively digging down into the folder structure, you're simply processing some files (if any are present) but as soon as a folder is discovered, you start all over again at the beginning.

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 ,
Nov 15, 2017 Nov 15, 2017

Copy link to clipboard

Copied

ok, give this a try. I don't have a PC to test on, so it MIGHT take some minor debugging as it pertains to paths, but with mac paths this script seemed to work just fine to do what you wanted to do, at least as far as i understood the workflow. You'll also need to double check the PDFSaveOptions properties. I removed those from my testing because i didn't have a pdf preset called 'dane'.

Let me know how this works for you.

*EDIT*

woops. i put in some logic to handle files that caused errors during export, but i never actually defined the errorList array or did anything about that array at the end. here's the updated version.

function container()

{

    const SAVE_PATH = "c:\\Users\\user\\Desktop\\TF PDF\\";

    var topFolder = Folder.selectDialog("Where?");

    var filesToProcess = [];

    var errorList = [];

    function validFile(file)

    {

        return (/TF.*\.ai/i.test(file.name));

    }

    function getFilesFromFolder(curfolder)

    {

        var files = curfolder.getFiles();

        var curFile;

        var len = files.length;

        for(var x=0;x<len;x++)

        {

            curFile = files;

            if(curFile instanceof File && validFile(curFile))

            {

                filesToProcess.push(curFile);

            }

            else if(curFile instanceof Folder)

            {

                getFilesFromFolder(curFile);

            }

        }

    }

    function processFiles(files)

    {

        var len = files.length;

        for(var x=0;x<len;x++)

        {

            try

            {

                var myDoc = app.open(files);

                savePDF(myDoc);

            }

            catch(e)

            {

                errorList.push("Failed to process the file: " + files.name + ".\nError msg: " + e);

            }

        }

    }

    function savePDF(doc)

    {

        var saveName = doc.name.substring(0,doc.name.length-3) + "_183";

        var dest = new File(SAVE_PATH + "\\" + saveName);

        var saveOpts = new PDFSaveOptions();

        doc.saveAs(dest,saveOpts);

        doc.close(SaveOptions.DONOTSAVECHANGES);

    }

    if(topFolder)

    {

        getFilesFromFolder(topFolder);

    }

    if(!filesToProcess.length)

    {

        alert("no files found");

    }

    else

    {

        processFiles(filesToProcess);

    }

    if(errorList.length)

    {

        alert("The Following Errors Occurred:\n" + errorList.join("\n"));

    }

}

container();

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
Participant ,
Nov 16, 2017 Nov 16, 2017

Copy link to clipboard

Copied

Thanks for your reply Williamadowling.

My code is definitely on the messy confusing side. I usually hack a way at a code till it does what i want.

In response to your first reply, according to what i have read a const can be declared and at some other point it can be initialized. I needed a global const but i need the value for it out of a function. Consts declared in a function disappear when the function is finished. Perhaps making a function specifically for that purpose would have been the right approach.

aFolder does not get defined more than once because it is protected by the "descended" boolean which can not be reversed once it has been made true. It never changes.

It does in fact dig into all the folders open and pdf all required files. does everything i want. Unfortunately it does it again and again.

I am just trying to explain the thinking behind what i did, however misguided it may have been.

So your script: It works perfectly. Really great. I like that it doesn’t jumping back and for between finding and saving. Saving the paths in an array is also excellent. Well maybe that would be obvious to people that know how to code properly?

Another thing is the recursing through the tree structure. I spent days writing a script to looked through tree structures. I have no idea why yours is 9 lines long. Ill have to spend more time looking at that bit of the code.

Thank you very much for taking the time to look through my code and writing this new one. It is immensly helpful.

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 ,
Nov 16, 2017 Nov 16, 2017

Copy link to clipboard

Copied

LATEST

Your code was indeed messy and confusing. And that's definitely not intended to be a dig at you or a criticism. We all start that way. When you first start out and you rely on piecing together snippets from other bits of code that perhaps you don't understand fully, it doesn't take long at all for a script to get jumbled, bloated and redundant. For this reason, i always encourage people to read someone else's code to see how they did something, then use the knowledge gleaned to write your own code, instead of copying and pasting different snippets. it will go a LONG way to helping you understand what the code does.

coding is a very specific and personalized/custom art. it's exceedingly rare that you'll find exactly what you need from another script. So you either end up with some snippets that have extra things (that may cause errors and make things hard to debug) or some snippets that are missing some things you do need. Either way, i find it more difficult to adapt someone else's code for my purposes. Though, as i said. I started by doing exactly that. So perhaps there's an important lesson to be learned by feeling the pain inflicted by copying and pasting snippets.

As to the array of files to process, credit definitely goes to Silly-V​ for that idea. I wouldn't have done it that way were it not for his suggestion, but once he said it, it seemed so obvious.

And finally, recursion. It's often said that in order to fully understand recursion.. You must first understand recursion.

When you're writing a recursive function, i believe simplicity is absolutely key. every variable increases the chances that something will go wrong, and recursion is notoriously difficult to debug, because it takes a lot of time, effort and concentration to figure out where in the process things went pear shaped. The goal is to boil things down into the simplest possible decision structure. In this case, we're fortunate because we basically only have two options.. the item passed to the function can only be a file, or a folder. if it's a file, check if it's valid. if it's a folder, call the function again with the newly found folder. No need to keep track of whether or not the function was called from itself or not.

It just takes practice. And with enough practice and thought, it will click. Silly-V wrote a recursive function for me a couple years ago that broke my brain. but as i played with it, tested it, adjusted it, and even used a piece of paper to step through it manually by writing down the results of each statement and evaluating what should happen next, things started to fall into place.

TL;dr

We love questions around here. do feel free to post any old question at any old time and you'll find an answer (though occasionally the answer will be "i don't know..."). I owe my entire knowledge base to this forum because people kept answering my questions.

Best of luck.

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