Copy link to clipboard
Copied
Hello.
I have read through all the forums and cannot find a current working script of what we are after.
I have an InDesign document that has an alphanumeric code in the slug. I name all our files with an alphanumeric code at the start.
Example: ABC1234 Presentation 1
I'd like to be able to create a text variable that pulls in only the ABC1234 part of the filename. (First 7 characters)
Any help would be greatly appreciated.
Hi Michael,
this one by Loic.Aigon will be a very good starting point for you:
Re: Custom text variable from javascript
Instead of using word or character count as contents of the variable you could use the name of the document that is truncated by a little regular expression.
Just before line 28 add this. The regular expression returns the first 7 characters of the name of the active document:
var truncatedName = doc.name.match(/^.{7}/)[0];
And change line 28 to that:
...tv.variableOptions.contents = t
Copy link to clipboard
Copied
Hi Michael,
this one by Loic.Aigon will be a very good starting point for you:
Re: Custom text variable from javascript
Instead of using word or character count as contents of the variable you could use the name of the document that is truncated by a little regular expression.
Just before line 28 add this. The regular expression returns the first 7 characters of the name of the active document:
var truncatedName = doc.name.match(/^.{7}/)[0];
And change line 28 to that:
tv.variableOptions.contents = truncatedName;
The return value of variable truncatedName is now assigned to the contents of the text variable.
Remove the whole function starts with:
var countWords = function F(/*Story|Cell|Footnote*/every)
You will not need it.
You have to run this script as startup script if you want full automation; means that it will run on every document you have open.
You may also change the name of the text variable the script creates and perhaps the name of the idleTask and the functions…
Regards,
Uwe
Copy link to clipboard
Copied
Thank you thank you thank. This worked great!
For anyone else wanted the script I've copied it below:
#targetengine "session"
main();
//Will add a custom idleTask listener to count current document words
function main()
{
var myIdleTask = app.idleTasks.item("countWords");
if ( !myIdleTask.isValid ) {
myIdleTask = app.idleTasks.add({name:"countWords", sleep:100});
var onIdleEventListener = myIdleTask.addEventListener(IdleEvent.ON_IDLE, onIdleEventHandler, false);
}
}
//Idke task listener
function onIdleEventHandler(myIdleEvent)
{
var doc = app.properties.activeDocument,
tv;
if ( !doc ) return;
tv = doc.textVariables.item("jobCode");
!tv.isValid && tv = doc.textVariables.add({name:"countText", variableType:VariableTypes.CUSTOM_TEXT_TYPE});
var truncatedName = doc.name.match(/^.{7}/)[0];
tv.variableOptions.contents = truncatedName;
}
//Snippet from indiscripts.com = http://www.indiscripts.com/post/2011/09/what-exactly-is-a-word
//with minor modification to exclude textVariable instances.;
Copy link to clipboard
Copied
Hi Michael,
just a note on this:
You will see that after saving your document in a split second your document is unsaved again. Reason: The event listener will check and its handling function will change the contents of the text variable constantly in idle moments.
You could prevent that, if the name of the document has not changed since the last time the contents of the text variable has changed. It's another if statement in the onIdleEventHandler function.
Oh, and please rename your #targetengine in case you are running more event driven scripts or if you plan to run them.
Best find a unique name and not "session" .
Regards,
Uwe
Copy link to clipboard
Copied
Thank you.
TBH I really don't know what i'm doing in the script / code world.
Would you please be able to ad the 'It's another if statement in the onIdleEventHandler function.' statement to the code for me?
and let me know what I should change 'session' to? or just copy what you think the code should be below?
Sorry I have no idea what i'm doing.
Copy link to clipboard
Copied
Hi Michael,
for the if statement:
You have this statement:
var truncatedName = doc.name.match(/^.{7}/)[0];
Variable named truncatedName now has the value you want to assign as contents of the text variable.
Now the goal is to see if the value that the text variable already has in this moment is absolutely the same you want to apply.
If yes, you do not want to apply it again, because this means your document's state will be changed. From perhaps saved to not-saved.
That in effect means, that you want to do the following statement only if the first 7 characters of your document name have changed:
tv.variableOptions.contents = truncatedName;
So you could do the following to test that:
if( truncatedName == tv.variableOptions.contents ){ return };
The == statement compares the two values and if true—the values are the same—executes the code that comes next between the two { }. That code above ends the function, in effect the function will do nothing. That's the simple return statement.
The three lines together:
var truncatedName = doc.name.match(/^.{7}/)[0];
if( truncatedName == tv.variableOptions.contents ){ return };
tv.variableOptions.contents = truncatedName;
Now for the name "session" of the #targetengine statement at the beginning of the script.
The main purpose of a #targetengine statement is to shield code from other code that is running by other scripts.
Or to make available code from one script to another that share the same targetengine.
My concern was that a targetengine that is named "session" is perhaps not unique enough, if you are running code snippets from other scripters who may use the same name and perhaps the same function names or variable names.
To be on a safer side you could use the following notation:
#targetengine "com.yoursecondname.yourfirstname.purposeofthisscript"
No blanks allowed and no digits at the beginning of the name.
Regards,
Uwe
Copy link to clipboard
Copied
Thank you Uwe.
I think you're underestimating my naivety here.
Where should I put "the three lined together in the code"
and for:
#targetengine "com.yoursecondname.yourfirstname.purposeofthisscript"
Do you mean an example like:
#targetengine "com.longton.michael.insertjobnumber"
The script would be used by multiple users in our office so would need to be more general
would this work?:
#targetengine "com.tcyk.insertjobnumber"
Is there any way you can copy the whole code below for me as you'd recommend using it? not just individual lines?
Copy link to clipboard
Copied
Hi Michael,
just add the new line of code—that's the if statement—between the two lines that are already there.
Both examples of your targetengine statement will work.
Regards,
Uwe
Copy link to clipboard
Copied
Worked beautifully thank you!
Copy link to clipboard
Copied
Hello Uwe,
I read all the text on this subject Partial filename text variable.
I'm not experienced in editing scripting files. But from what I have read, this looks like what I need:
I have multiple Indesign documents (simultaneously open). They all use the standard Indesign-text variabele Filename. But now I'd like to show only the first 12 chararcters of the filename. When I save the documents with a new filename, of course the text variabele shown with 12 characters should change also.
I tried to show only the first 12 characters using a grep-style, but that doesn't seem to work for text variables. It does work voor plain text.
I tried the script shown in your answer, but I get a Indesign-error message: (translated from dutch)
script has generated error:
item with same name is already existing
shut down.....?
Copy link to clipboard
Copied
Hi erwine7220 ,
please post the code you are working with.
And also format the code with forum's option Use advanced editor.
Select the code when in advanced mode and do Syntax Highlighting > javascript
Thanks,
Uwe
Copy link to clipboard
Copied
#targetengine "art_nr_12"
main();
//Will add a custom idleTask listener to count current document words
function main()
{
var myIdleTask = app.idleTasks.item("countWords");
if ( !myIdleTask.isValid ) {
myIdleTask = app.idleTasks.add({name:"countWords", sleep:100});
var onIdleEventListener = myIdleTask.addEventListener(IdleEvent.ON_IDLE, onIdleEventHandler, false);
}
}
//Idke task listener
function onIdleEventHandler(myIdleEvent)
{
var doc = app.properties.activeDocument,
tv;
if ( !doc ) return;
tv = doc.textVariables.item("jobCode");
!tv.isValid && tv = doc.textVariables.add({name:"countText", variableType:VariableTypes.CUSTOM_TEXT_TYPE});
var truncatedName = doc.name.match(/^.{12}/)[0];
tv.variableOptions.contents = truncatedName;
}
//Snippet from indiscripts.com = http://www.indiscripts.com/post/2011/09/what-exactly-is-a-word
//with minor modification to exclude textVariable instances.;
Copy link to clipboard
Copied
Hello Laubender,
I posted the code I'm working with some time ago. Can you take a look at it?
Thank you.
Erwin
Copy link to clipboard
Copied
What's the problem with it? Is there an error message? And if yes, what does it tell?
Best,
Uwe
Copy link to clipboard
Copied
Hello Uwe,
I tried the script shown in your answer (shown above), but I get a Indesign-error message: (translated from dutch)
script has generated error:
item with same name is already existing
shut down.....?
Copy link to clipboard
Copied
Hi Erwin,
make sure that you do the same name in:
tv = doc.textVariables.item("jobCode");
and:
!tv.isValid && tv = doc.textVariables.add({name:"countText", variableType:VariableTypes.CUSTOM_TEXT_TYPE});
That should be the same.
To remember this it would be better to write:
tv = doc.textVariables.itemByName("jobCode");
which is the long form of:
tv = doc.textVariables.item("jobCode");
Regards,
Uwe
Copy link to clipboard
Copied
Hi Uwe,
It works!
Thank you very much.
Shall I post it on the forum? Or are most visitors to the forum more experienced in Javascript?
Met vriendelijke groeten | With kind regards | Mit freundlichen Grüßen | Sincères salutations,
Erwin Eijsink | Technical Documentation | VB-Airsuspension B.V. The Netherlands
Copy link to clipboard
Copied
Hello,
Thanks to Uwe and everyone else for workshopping this, it's been super helpful! I've been trying to implement this script to automate partial file names within my inDesign doc, however I've run into 2 issues:
e.g. Current file naming structure is JOBCODE_TASK_SUBTASK_R01, where I'd like to automatically extract "R01".
See below for my current code for the Job Code part 1. Struggling to get my head around the inDesign scripts!
#targetengine "com.joske.InsertJobCode"
main();
//Will add a custom idleTask listener to count current document words
function main()
{
var myIdleTask = app.idleTasks.item("countWords");
if ( !myIdleTask.isValid ) {
myIdleTask = app.idleTasks.add({name:"countWords", sleep:100});
var onIdleEventListener = myIdleTask.addEventListener(IdleEvent.ON_IDLE, onIdleEventHandler, false);
}
}
//Idke task listener
function onIdleEventHandler(myIdleEvent)
{
var doc = app.properties.activeDocument,
tv;
if ( !doc ) return;
tv = doc.textVariables.itemByName("JobCode");
!tv.isValid && tv = doc.textVariables.add({name:"JobCode", variableType:VariableTypes.CUSTOM_TEXT_TYPE});
var truncatedName = doc.name.match(/^.{7}/)[0];
if( truncatedName == tv.variableOptions.contents ){ return };
tv.variableOptions.contents = truncatedName;
}
//Snippet from indiscripts.com = http://www.indiscripts.com/post/2011/09/what-exactly-is-a-word
//with minor modification to exclude textVariable instances.;
Copy link to clipboard
Copied
Hi Lauren,
please show a typical InDesign name you want to use. Plus the one you like to see in your text variable.
Then it would be easier to do a regular expression that will return the truncated and changed name.
Regards,
Uwe
Copy link to clipboard
Copied
good morning community,
I hope I can reopen this thread...
this script is very good for me, I really need to use a partial filename variable in my document.
...but I'm not able to run the script at the startup nor to update the variable content every time I change the filename.
the variable content is correct the first time I (manually) run the script and remain the same although I change filename.
I'm not skilled enough to modify the script as I need.
thankyou for your help.
Copy link to clipboard
Copied
The above snippert runs perfectly fine. Is the targetengine instruction added in the script that you tried to use? This line makes the script persistent so it reacts to later changes.
//IMPORTANT
#targetengine "com.joske.InsertJobCode"
//IMPORTANT
main();
//Will add a custom idleTask listener to count current document words
function main()
{
var myIdleTask = app.idleTasks.item("countWords");
if ( !myIdleTask.isValid ) {
myIdleTask = app.idleTasks.add({name:"countWords", sleep:100});
var onIdleEventListener = myIdleTask.addEventListener(IdleEvent.ON_IDLE, onIdleEventHandler, false);
}
}
//Idke task listener
function onIdleEventHandler(myIdleEvent)
{
var doc = app.properties.activeDocument,
tv;
if ( !doc ) return;
tv = doc.textVariables.itemByName("JobCode");
!tv.isValid && tv = doc.textVariables.add({name:"JobCode", variableType:VariableTypes.CUSTOM_TEXT_TYPE});
var truncatedName = doc.name.match(/^.{7}/)[0];
if( truncatedName == tv.variableOptions.contents ){ return };
tv.variableOptions.contents = truncatedName;
}
Copy link to clipboard
Copied
really thanks for your time.
works!
I'm very happy for this Christmas gift 😄
avanzi una birra 😉
Copy link to clipboard
Copied
sorry if I reopen this thread:
after the latest updates of indesign 2024 it seems that the variable no longer updates automatically.
does this happen to you too?
Copy link to clipboard
Copied
Hi Michael,
did you try anything following my suggestions?
Regards,
Uwe
Copy link to clipboard
Copied
Hi Uwe,
A typical name I'd use would be something like this:
PSCP72_MIRRORS_PRES_R2
Where "PSCP72" is the Job Code and "R2" is the round of changes.
Thanks,
L