Highlighted

Partial Filename Text Variable

Community Beginner ,
Mar 05, 2018

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.

Adobe Community Professional
Correct answer by Laubender | Adobe Community Professional

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

TOPICS
Scripting

Views

2.6K

Likes

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

Partial Filename Text Variable

Community Beginner ,
Mar 05, 2018

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.

Adobe Community Professional
Correct answer by Laubender | Adobe Community Professional

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

TOPICS
Scripting

Views

2.6K

Likes

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
Mar 05, 2018 0
Adobe Community Professional ,
Mar 06, 2018

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

Likes

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
Reply
Loading...
Mar 06, 2018 1
Community Beginner ,
Mar 07, 2018

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.; 

Likes

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
Reply
Loading...
Mar 07, 2018 1
Adobe Community Professional ,
Mar 08, 2018

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

Likes

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
Reply
Loading...
Mar 08, 2018 0
Community Beginner ,
Mar 08, 2018

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.

Likes

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
Reply
Loading...
Mar 08, 2018 0
Adobe Community Professional ,
Mar 09, 2018

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

Likes

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
Reply
Loading...
Mar 09, 2018 0
Community Beginner ,
Mar 12, 2018

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?

Likes

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
Reply
Loading...
Mar 12, 2018 0
Adobe Community Professional ,
Mar 12, 2018

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

Likes

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
Reply
Loading...
Mar 12, 2018 0
Community Beginner ,
Mar 12, 2018

Copy link to clipboard

Copied

Worked beautifully thank you!

Likes

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
Reply
Loading...
Mar 12, 2018 0
New Here ,
Apr 06, 2018

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.....?

Likes

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
Reply
Loading...
Apr 06, 2018 0
Adobe Community Professional ,
Apr 07, 2018

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

UsingSyntaxHighlighting-AdvancedEditing.png

Thanks,
Uwe

Likes

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
Reply
Loading...
Apr 07, 2018 0
New Here ,
Apr 10, 2018

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.;

Likes

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
Reply
Loading...
Apr 10, 2018 0
New Here ,
Jun 04, 2018

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

Likes

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
Reply
Loading...
Jun 04, 2018 0
Adobe Community Professional ,
Jun 04, 2018

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

Likes

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
Reply
Loading...
Jun 04, 2018 0
New Here ,
Jun 04, 2018

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.....?

Likes

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
Reply
Loading...
Jun 04, 2018 0
Adobe Community Professional ,
Jun 04, 2018

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

Likes

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
Reply
Loading...
Jun 04, 2018 0
New Here ,
Jun 04, 2018

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

Likes

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
Reply
Loading...
Jun 04, 2018 0
New Here ,
Jun 02, 2019

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:

  1. I would like to remove the underscore at the end of the Job Code
              e.g. "PSCP73" not "PSCP73_"
  2. I'd like to add the last digits to indicate version number

                 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.;

Likes

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
Reply
Loading...
Jun 02, 2019 0
Adobe Community Professional ,
Jun 02, 2019

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

Likes

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
Reply
Loading...
Jun 02, 2019 0
Adobe Community Professional ,
Mar 07, 2018

Copy link to clipboard

Copied

Hi Michael,

did you try anything following my suggestions?

Regards,
Uwe

Likes

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
Reply
Loading...
Mar 07, 2018 0
New Here ,
Jun 02, 2019

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

Likes

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
Reply
Loading...
Jun 02, 2019 0
Adobe Community Professional ,
Jun 03, 2019

Copy link to clipboard

Copied

So you have a INDD document name like:

PSCP72_MIRRORS_PRES_R2.indd

And you want it to shorten to:

PSCP72R2.indd

Right?

Regards,
Uwe

Likes

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
Reply
Loading...
Jun 03, 2019 0
New Here ,
Jun 12, 2019

Copy link to clipboard

Copied

Yes, that is correct!

Likes

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
Reply
Loading...
Jun 12, 2019 0
Adobe Community Professional ,
Jun 13, 2019

Copy link to clipboard

Copied

Then you could do something like this:

var s = "PSCP72_MIRRORS_PRES_R2.indd";

var a = s.split("_");

var truncatedName = a[0] + a[a.length-1]; // returns PSCP72R2.indd

Here I assume the following rule:

The first chunk before the first occurance of "_" should always be added to the last chunk that begins after the last occurance of  "_" in the name.

To make that work for all names you need at least two occurences of "_".

Regards,
UWe

Likes

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
Reply
Loading...
Jun 13, 2019 0
New Here ,
Jun 16, 2019

Copy link to clipboard

Copied

Thanks for your help Uwe, and please excuse my ignorance... where exactly does this rule go? Is it within the current code I have such as in the 'Function' rule on line 6? I'm very new to scripts and trying to wrap my head around it!

Likes

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
Reply
Loading...
Jun 16, 2019 0
New Here ,
Jan 10, 2020

Copy link to clipboard

Copied

What if you wanted to extract certain characters from the filename. For example, if i wanted to get the 3rd to 5th characters of the filename?

Likes

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
Reply
Loading...
Jan 10, 2020 0
Adobe Community Professional ,
Jan 13, 2020

Copy link to clipboard

Copied

Hi,

if you have a string like that:

var name = "MyName.indd";

 

and you want to get the 3rd, the 4th and the 5th character of the name, you can simply do a concatenation of single characters where numbering starts with 0 as the first item:

 

var name = "MyName.indd";
var thirdToFithChar = name[2] + name[3] + name[4] ;

 

Or do it with method slice().

 

Quoting documentation:

String.slice( startSlice , endSlice ) extracts a substring of the given string and returns it as a new string. The substring begins at startSlice, and includes all characters up to, but not including the character at the index endSlice.

 

var name = "MyName.indd";
var thirdToFithChar = name.slice(2,5) ;

 

But first check the value of length of the string. Could be your file name is not five characters long.

 

Regards,
Uwe Laubender

( ACP )

 

Likes

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
Reply
Loading...
Jan 13, 2020 0
New Here ,
Jan 13, 2020

Copy link to clipboard

Copied

Thank you for the response, Uwe. I don't have much experience coding so i was wondering how i would add this to the code below. It was using this to find the text variable for the version number in the filenmame, but now i need to zero in on the Client Name "IRV" (eg. 19IRV1234_filename.indd).

 

UpdateClientName// The present code can be used as a startup script.

#targetengine 'UpdateClientName'

const UpdateClientName = function(/*Event*/ev, doc,m,t)
// -------------------------------------
// AFTER_OPEN event handler.
// Reset the `ClientName` text variable to the 9 first characters of the
// doc file name iff they are formed of uppercase letters and/or digits.
// ---
// Tested conditions:
// 1. The event type MUST be 'afterSave' (prevent wrong listener.)
// 2. The event MUST provide a valid `fullName` prop (File),
// since one can't rely on document.fullName yet!
// 3. The save-as File name MUST match /^[A-Z\d]{9}/.
// 4. The target MUST be a Document instance (who knows!)
// 5. It MUST have a `ClientName` TextVariable...
// 6. ...of the kind 'Custom text.'
// 7. No need to rewrite the variable if already set as expected.
{
( 'afterSave' == ev.eventType )
&& ( m=ev.properties.fullName )
&& ( m=m.name.match(/^[A-Z\d]{9}/) )
&& ( (doc=ev.target) instanceof Document )
&& ( (t=doc.textVariables.itemByName('ClientName')).isValid )
&& ( (t=t.variableOptions) instanceof CustomTextVariablePreference )
&& ( m[0] != t.contents )
&& ( t.contents=m[0] );
};

app.addEventListener('afterSave', UpdateClientName);

Likes

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
Reply
Loading...
Jan 13, 2020 0