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

Can I pass arguments to #include script

Enthusiast ,
Apr 24, 2025 Apr 24, 2025

I'll try to simplify this and add more detail if questions are asked:

I have two scripts: Script_A.jsx and Script_B.jsx.

 

Script_A.jsx creates a window and a button on the window runs:
#include "Script_B.jsx"

 

That works fine, but I would like to pass the window from Script_A to Script_B so Script_B can check some of the values from the window.

 

Is there a way to do this?

 

Something like:

#include "Script_B(win).jsx"

or

#include "Script_B.jsx {arguments:win}"

 

I realize it could be done by including the functions of Script_B into Script_A and making one massive script, but I'd like to make that my last resort.

 

Thanks in advance!

TOPICS
Scripting
2.1K
Translate
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 2 Correct answers

Community Expert , Apr 24, 2025 Apr 24, 2025

You could run both the scripts in the same engine, something like

#targetengine "main"

The you can set the variable you want to pass as a global variable and that will be available to script B.

 

Another approach could be to use the doScript method to call script B instead of #include. This method takes an array as an argument to pass to the calling script

-Manan

Translate
Enthusiast , Apr 24, 2025 Apr 24, 2025

Disregard, I just ran a test and if I call Script_B from Script_A using the include statement, all of the Scrpt_A variables and values are available to Script_B, so I don't need to pass it a variable.

Translate
Community Expert ,
Apr 24, 2025 Apr 24, 2025

You could run both the scripts in the same engine, something like

#targetengine "main"

The you can set the variable you want to pass as a global variable and that will be available to script B.

 

Another approach could be to use the doScript method to call script B instead of #include. This method takes an array as an argument to pass to the calling script

-Manan

Translate
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 ,
Apr 24, 2025 Apr 24, 2025

Hi @Marshall_Brooks you seem to be wanting to separate the UI (the window) from the script, which is an excellent idea. However, to do this, there are much easier ways than passing the window to a separate script file. One way that I commonly use is to handle the window creation and display (ie. the script's UI) in a function, and pass that function an object—I usually use a `settings` object containing all the properties the script needs.

 

You can see an example here. This post might be worth a bit of study because the OP's script has no separation of UI, and I post a version of the script which has the UI completely de-coupled, meaning that with a single "showUI = false" the script will run completely fine with no UI at all, using the properties already set in the `settings` object.

 

I also use #include files all the time—I store functions in the include file, and then call them from the main script. For a project I may have many many functions in such a "library" script file.

- Mark

Translate
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 ,
Apr 24, 2025 Apr 24, 2025

Thanks! I had not heard of doScript before, and I'm not necessarily trying to separate the window from the script. Also I found this thread when I was researching DoScript: https://community.adobe.com/t5/indesign-discussions/how-do-i-make-a-script-both-executable-on-its-ow...

 

Let me share more info on what I am trying to do!!

 

Script A and Script B were each originally developed independently.

 

Script A presents a window which has about 15 checkboxes. 10 of the checkboxes can be selected simultaneously and are common to checkboxes on Script B. (For discussion, lets call them Ford, Chevy, Honda, Mazda, Nissan).

 

Script B presents a different window (they both might be named win, which presents a problem). Script B's window presents other checkboxes, 10 of them are common to Script A (Ford, Chevy, Honda, Mazda, etc.), but only one can be selected at a time.

 

What I want to achieve is if the user has Chevy (and only Chevy) checked on Scirpt A and clicks the Script B button, which fires the #include statement to launch Script B, the Chevy checkbox is clicked when Script B opens.

 

Ways that I can see to achieve this - but there might be better solutions and I could be wrong - in order of what I understand:

 

  • I can modify Script B to change all references to win to win2 for similar and paste all of Script B's code into Script A. Then I can pass "win" from Script A to the functions of script b, check if Chevy is checked and only Chevy is checked, and if so, check Chevy on Script B's window.
  • If I understood the thread I linked above and @Manan Joshi's first comment, another approach would be to create a Script C and have it's first statement be #include "Script_A.jsx" Then the window of Script_A becomes a global variable and can be used by Script B. (I'm not seeing how this works - or if it does, maybe I'm overcomplicating things and the window from Script A is already avialable when I call Script B from the #include statement and I just have to modify Script B to take advantage of it.
  • If I understood @Manan Joshi second example with DoScript and my research on it, DoScript can pass a file, string, or javascript function as an argument, but not a variable like win from ScriptA. So I could use this, but I would have to add a function that checked if Chevy (Ford, Honda) was checked and only Chevy (Ford, Honda) was checked and returns a variable like CarType with value of "Chevy", "Ford", "Honda", or "" and then I can pass that in the DoScript argument to know which button to select on win2.

 

Translate
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 ,
Apr 24, 2025 Apr 24, 2025

Disregard, I just ran a test and if I call Script_B from Script_A using the include statement, all of the Scrpt_A variables and values are available to Script_B, so I don't need to pass it a variable.

Translate
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 ,
May 01, 2025 May 01, 2025

Right so basically if two scripts use the same engine they will share the execution context and hence the variables would be shared. This is what I suggested before

-Manan

Translate
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
LEGEND ,
May 02, 2025 May 02, 2025

And isn't the point / how include works? Doesn't it include complete source code of the imported script?

 

Translate
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 ,
May 02, 2025 May 02, 2025

Yes it should import the whole code. However, it does help in modularising the code into different files and that is what the OP is after I think

-Manan

Translate
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 ,
May 07, 2025 May 07, 2025

Correct, I'm using the #include statements to modularize and isolate the code, but it is from a practical standpoint and not an idealistic standpoint.

 

Basically, I like #include statements for three reasons:

 

  • I'm not an elegant coder. So one function might be 500 lines of code. If I have 10 scripts and they all call the same five functions, with include statements, that is basically 2550 lines of code. If I embedded the functions in each script, each script is 2500 lines of code and the entire codebase is 25,000 lines of code. More importantly, a 2500 line block of code is difficult to manage, if I want to change one function, I have to find where the 500 line block starts and ends amidst the other 2000 lines of code.

 

  • Equally important: Lets say I discover that a function would have increased usability if I changed three lines of code. With #include statements, I update that one function of code and everywhere that function is called, it uses the updated code. With embedded functions, I have to figure out which of my scripts called that particular function and update all of them with the new code changes.

 

  • Finally, I'm not particularly a fan of javascript. I'm used to Visual Basic for Applications and IMHO opinion JS is less structured and more tolerant of errors. (Translation: Your script is less likely to point out code errors and less likely to crash, but also less likely to run properly). As a result, while I might code a large script in VBA, in JS (ScriptUI, ExtendScript), I tend to try a part of the script, save that as a function, try part of the script using the new function, etc.

 

EDIT: Example: Checkboxes have .values, but EditText fields have .text. If I were coding in VBA, using something like "etext.value==="This text" (aside from the triple = ) would product either a syntax error or a type mismatch. In JS, etext.value is always undefined, so the comparison always resolves to false and your script runs but you don't get the expected result.


EDIT2: Another example. In one of my scripts, I wanted to deselect a check box. The way you do that is "ckbx_SelectAll.value = false;". I put  "ckbx_SelectAll = false;" Visual Basic would have highlighted that, probably shown a syntax error. Most like not run the script at all until it was fixed. Javascript just says "I don't know what this means … Oh well, must not be important … I'll just ignore it … Have a nice day!!!"

Translate
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 ,
May 07, 2025 May 07, 2025

I do have a neophyte question and this thread is probably as good as any place to ask it in!

 

For background, I'm using Extendscript/ScriptUI to display pop-up windows and manipulate FrameMaker documents. I'm not totally clear on the distinction between the two, but that's not the question. ScriptUI is supposed to be universal among Adobe apps (InDesign, LifeCycle, Photoshop, FrameMaker) - although it behaves somewhat differently in InDesign than it does in FM than it does in ExtendScript Toolkit CC, whereas I think Extendscript is unique to FrameMaker.

 

As I said above, my background is in VBA, so I tend to "think" in terms of VBA and translate the syntax into Javascirpt/ScriptUI/Extendscript, if that makes sense. (I think ScriptUI also supports VB, but virtually nobody uses it that way, so it's easy to ask questions and work in JS).

 

Question background:

 

For discussion purposes, I have two templates: Template A and Template B.

 

I have two scripts: Script A and Script B.

 

Script A displays a window (panel) to modify user variables in Template A.

 

Script B displays a window (panel) to modify user variables in Template B.

 

The scripts were intended to work independently - i.e. you would open Template A, run Script A, close Script A, open Template B, run Script B, close Script B. Predictably, they work fine that way.

 

Script B was written from Script A so they use the same syntax - i.e. the pop-up is called "win" in both scripts. Both scripts use "var doc=app.ActiveDoc" etc.

 

Question:

 

I would expect the scripts to conflict if run simultaneously - i.e. they use the same variable names and definitions for different objects. In VBA, having win defined twice would probably lead to Duplicate Definition in the Current Scope. compile error. I would expect Script A to try to modify Template B if I had that active. The scripts didn't seem to do that. They both worked as expected. Script B modified Template B even if Template A were active. Clicking buttons on the Script A window didn't confuse the Script B window, etc.

 

Could someone explain how and why this happens?

Translate
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
LEGEND ,
May 07, 2025 May 07, 2025

@Marshall_Brooks

 

I'm not JS guy - but i think it has something to do with "#targetengine" - scope of where script is run.

 

Translate
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
LEGEND ,
May 07, 2025 May 07, 2025
Translate
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
LEGEND ,
May 07, 2025 May 07, 2025

@Marshall_Brooks

 

How about close to 100k lines of code - but in VB 😉 and still growing 😉

 

Translate
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 ,
May 07, 2025 May 07, 2025

@Robert at ID-Tasker Some of the StackOverflow stuff is incorrect. #TargetEngine works in FrameMaker. I haven't used it, but if I specify #TargetEngine FrameMaker and double-click my .jsx file, I get a prompt asking if I want to run the script in FM. If I don't specify #TargetEngine, double-clicking opens the script in ESTK tool kit and I have to select FrameMaker there to run it in FrameMaker. But I typically don't specify a target engine in my scripts and they both could be running at the same time.

 

From what I can see (but this is all empirical):

  • Scripts use their current variables if applicable - i.e. if I have "win" defined in both Script A and Script B, Script A uses Script A's definition of "win" and Script B uses Scripts B's.
  • Variables are somewhat global. I.e. if Script A has a window with btnConfirm on it and Script B does not, I can mention btn.Confirm.value in Script B and is Script A is running, Script B can evaluate that.
  • "doc=app.ActiveDoc" is very common in FM, but is a bit misleading. In a way it makes sense, but it is the active document at the time the script calls it. If I have Template A active and the script sets "doc" to the active document and then I switch to Template B - "doc" is still Template A - not the CURRENT active document.

 

Off-topic - 72K lines of code in my current VBA project, but I tend to not try to brag about code length. In my case, it is usually b/c I found something that could work with minor changes and repeated it rather than building it into a subroutine that I could call repeatedly.

Translate
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
LEGEND ,
May 07, 2025 May 07, 2025

@Marshall_Brooks

 

Are those 72k lines InDesign related?

I don't duplicate code - just rewrite, add extra arguments, to make it more universal. And pretty much zero comments 😉 

 

I've sent you a private message. 

 

Translate
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 ,
May 15, 2025 May 15, 2025

Somehow I missed this post. 72k lines are Visual Basic for Microsoft Access database. I don't even have InDesign, but I was told this was the best forum for ScriptUI questions.

Translate
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 ,
Jun 23, 2025 Jun 23, 2025

I have a new issue related to this:

 

From the previous example:

 

For discussion purposes, I have two templates: Template A and Template B.

I have two scripts: Script A and Script B.

Script A displays a window (panel) to modify user variables in Template A.

Script B displays a window (panel) to modify user variables in Template B.

I also have a Master Script that checks a variable in the document and  calls either Script A or Script B.

 

What I want to do is have Script A call the Master Script if the active document changes - but since the MasterScript include Script A, I get a Stack Overrun.

 

How would I avoid this?

 

I tried using app.doScript("MasterScript.jsx") and I get an error that app.doScript is not an approved function.

 

Note that I get the error when the function first opens, before that line of code executes, so I can't exit the function to avoid the error.

 

Pseudo-Code:

 

MasterScript.jsx:

main();

function main()
{
    var doc = app.ActiveDoc;
    if(!doc.ObjectValid())
    {
        alert("No active document. Cannot continue.");
       return;
    }
    #include "Close_All_Palettes.jsx"
    var VarExists_MST = false;
    var varFmt;
    varFmt = doc.GetNamedVarFmt("_zz_Template_Type")
    if (varFmt.ObjectValid() )
    {
        VarExists_MST =true;
        if (varFmt.Fmt ==="Doc A") 
        {
            #include "Script A.jsx";
 //           return;
        }
   
        else if (varFmt.Fmt === "Doc B")
        {
             #include "Script B.jsx";
   //         return;
        }
}

Script A Excerpt:

var doc = app.ActiveDoc;
CreateMainMenu(doc);
// end Main program

function CreateMainMenu(doc) 
{
   if (!doc.ObjectValid()) 
   {
        alert("No active document. Cannot continue.");
        return;
    }
    var InitialDocName = doc.Name;
// ...
    doc = app.ActiveDoc;
    if (!VerifyTemplate(doc, InitialDocName)) 
    {
        return;}
    }
}

function VerifyTemplate(doc, InitialDocName) 
{
    var TemplateValid = false;
    if (doc.Name===InitialDocName) 
    {
        TemplateValid = true;
    }
    else
    {
        var varFmt;
        varFmt = doc.GetNamedVarFmt("_zz_Template_Type")
        if (varFmt.ObjectValid()) 
        {
            if (varFmt.Fmt === "Doc A") {
                alert("Active Document Changed. Re-opening Window. Please Re-click your selection.")
                Win_Reopen();
            }
            else
            {
// Below gives Stack Overun
            #include "MasterScript.jsx"
// Below gives "app.doScript is not a function. 
            app.doScript("MasterScript.jsx");
//Below works, but I'd prefer something automated:
            alert("Active Document Changed. Please run Master Script.)
             }
        }
     }
   return TemplateValid;
}

function Win_Reopen() 
{
    var doc = app.ActiveDoc;
    CreateMainMenu(doc);
}
Translate
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 ,
Jun 23, 2025 Jun 23, 2025

I can get around this with a Switch statement - i.e. instead of:

 if (varFmt.Fmt === "Doc A") {
                alert("Active Document Changed. Re-opening Window. Please Re-click your selection.")
                Win_Reopen();
            }
            else
            {
// Below gives Stack Overun
            #include "MasterScript.jsx"
}

Change to:

switch (varFmt.Fmt)
{
   case "Doc A":
       alert("Active Document Changed. Re-opening Window. Please Re-click your selection.")
       Win_Reopen();
       break;
    case "Doc B":
       #include "Script_B.jsx";
       break;
    case "Doc C";
       #include "Script_C.jsx";
}

Not nearly as elegant, but it works!!!

Translate
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 ,
Jun 24, 2025 Jun 24, 2025

Hi @Marshall_Brooks

 

Aside: I'm actually shocked that the #includes in your switch code above actually work! It does work though—I tested it in simplified form. I always thought those directives were evaluated before the code is run, but your code proves this is not the case. 🤯

 

But here's my opinion. I strongly prefer to use included script files to load or instantiate objects, rather to perform actual operations. So my include files are like this:

/** @file MyWindows.js */

function MyWindowA(settings) {

    var w = new Window ( /* ... */ )

    // ... 

    // return the window closed value
    return w.show();

    function only_MyWindowA_Needs_Me () {
        // ... do something here that only MyWindowA needs
    };

};

function MyWindowB(settings) {

    var w = new Window ( /* ... */ )

    // ... 

    // return the window closed value
    return w.show();

    function only_MyWindowB_Needs_Me () {
        // ... do something here that only MyWindowB needs
    };

};

function i_Am_Used_By_Both_MyWindows() {

   // ... do something here that both MyWindows want

};

function populateListBox(listbox, data) {

   // ... example of a function used by both MyWindows

};

 

It defines a bunch of functions that I will then invoke in my actual script (or in other functions in other include files!). The thing is, if you run this script file, it will do nothing, because all it does is define functions.

Personally I think this is a much safer and cleaner approach to using multi-file scripts. Just my opinion.

- Mark

Translate
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 ,
Jun 24, 2025 Jun 24, 2025

What I'm finding is that pretty much anything scriptUI essentially becomes a global property, so everything needs a unique name - i.e.

unique variables

unique controls

unique window names

unique function names

...

The exception being functions that are generic and repeated word-for-word in multiple procedures.

Translate
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 ,
Jun 24, 2025 Jun 24, 2025

Hi @Marshall_Brooks 

 

You *are* defining all your variables in the global space but it has nothing to do with ScriptUI. It is just what you are doing.

 

(It is also bad programming. I think maybe you don't know how to *not* define all your variables in the global space?)

 

The answer is: define almost everything inside functions—because ExtendScript scopes by function, not blocks like modern Javascript. You can then control which functions have access to which variables. This can avoid problems of exactly the sort that this entire thread is presenting.

 

It is too long a job for me to explain variable scoping in detail, but one approach you could take it to go to my profile and look at any script I have posted in the last 3 years and try to look at the structures I use. For Indesign I usually put all my code inside a main() function or sometimes an IIFE. I can then define functions inside or outside of that, depending on where I want them. In the global scope I only have #includes (which only define functions and never perform actual operations) and a single call to the main() function.

- Mark

Translate
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 ,
Jun 24, 2025 Jun 24, 2025

What I found in another thread is that when you use an #include (which would be a javascript which contains functions), those functions become global, so to have your functions not be global, essentially, you would have to have one huge script instead of medium sized scripts with include functions ...

Translate
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 ,
Jun 24, 2025 Jun 24, 2025

Hi @Marshall_Brooks , I'm not sure if this helps—ignore if it doesn’t. The #include file could have any number of public functions, constants, and variables, which may or may not be run from your script.

 

So this MyLibrary.jsxinc example has 2 public functions:

 

/**
* Simple PDF Prest dialog 
* @ return the chosen dialog 
*/

function exportPDFDialog(){
    var pp;
    var theDialog = app.dialogs.add({name:"Choose a Preset", canCancel:true});
    with(theDialog.dialogColumns.add()){
        pp = dropdowns.add({stringList:app.pdfExportPresets.everyItem().name, selectedIndex:3, minWidth:80});
    }
    if(theDialog.show() == true){
        pp = app.pdfExportPresets.item(pp.selectedIndex);
        theDialog.destroy();
        return pp;
	}
}

/**
* Makes a new named Layer 
* @ param the document to add the layer to 
* @ param new layer name 
* @ return the new layer 
*/

function makeLayer(d, n){
    if (d.layers.itemByName(n).isValid) {
        return d.layers.itemByName(n);
    } else {
        return d.layers.add({name:n});
    }
}

/**
* A read only constant
*/
const MAGIC_NUMBER = 1.045;


/**
* A read write variable
*/
var vNum = 5

 

I can include and run them from a jsx file including a dialog function which returns the results:

 

#include "MyLibrary.jsxinc";

//run the exportPDFDialog() function from MyLibrary.jsxinc
alert("Chosen Export Preset: " + exportPDFDialog().name)


//run the makeLayer() function from MyLibrary.jsxinc
var ns = makeLayer(app.activeDocument, "MyNewLayer");
alert("New Layer Named: " + ns.name);

 

 

On run:

 

Screen Shot 27.png

 

Screen Shot 28.png

 

Screen Shot 29.png

 

 

 

Translate
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 ,
Jun 24, 2025 Jun 24, 2025

Ran into a problem and now I'm not sure how to resolve it.

As I said above:

In Script A:

switch (varFmt.Fmt)
{
   case "Doc A":
       alert("Active Document Changed. Re-opening Window. Please Re-click your selection.")
       Win_Reopen();
       break;
    case "Doc B":
       #include "Script_B.jsx";
       break;
    case "Doc C";
       #include "Script_C.jsx";
}

Works!

But when I create Script B with:

switch (varFmt.Fmt)
{
   case "Doc A":
       #include "Script_A.jsx"
        break;
    case "Doc B":
//       #include "Script_B.jsx";
       alert("Active Document Changed. Re-opening Window. Please Re-click your selection.")
       Win_Reopen();
       break;
    case "Doc C";
       #include "Script_C.jsx";
}

If I try to run Script_B, it highlights the "#include Script_B.jsx" line in the Script_A.jsx file and gives a Stack Overrun error.

 

How do I avoid this? 

Translate
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 ,
Jun 24, 2025 Jun 24, 2025

@Marshall_Brooks I'm sorry to say that you are creating a horrible architecture. I strongly suggest you put your overall control code into the main script and include (at the start of the script—not using predicate logic) just library functions and objects.

 

As for the stack overrun, have a look in the debugger and see which function is filling the stack. For example I created a stack overrun by making a function call another function which then called the other function back...

Screenshot 2025-06-25 at 10.50.07.png

- Mark

Translate
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