Skip to main content
Participant
March 6, 2018
Answered

Partial Filename Text Variable

  • March 6, 2018
  • 6 replies
  • 8260 views

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.

This topic has been closed for replies.
Correct answer Laubender

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

6 replies

Participant
October 20, 2020

Hello. I am trying to use this script but keep getting the same job number, even when i resave the document to a new name. It also doesn't seem to be recognizing the if statement to stop if the name hasn't changed- as the document keeps showing that it is unsaved. Can you help?

 

 

Here is the script i am trying to use in the startup scripts folder.

 

#targetengine "com.kv.getkmjobnumber"

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:"KMJobNumber9", variableType:VariableTypes.CUSTOM_TEXT_TYPE});

var truncatedName = doc.name.match(/^.{9}/)[0];

if(truncatedName == tv.variableOptions.contents){return};

tv.variableOptions.contents = truncatedName;

 

}

Known Participant
January 10, 2020

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?

Community Expert
January 13, 2020

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 )

 

Known Participant
January 13, 2020

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

laurenb92964320
Participant
June 13, 2019

Yes, that is correct!

Community Expert
June 13, 2019

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

laurenb92964320
Participant
June 17, 2019

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!

laurenb92964320
Participant
June 3, 2019

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

Community Expert
June 3, 2019

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

Community Expert
March 7, 2018

Hi Michael,

did you try anything following my suggestions?

Regards,
Uwe

LaubenderCommunity ExpertCorrect answer
Community Expert
March 6, 2018

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

Participant
March 7, 2018

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

Community Expert
March 8, 2018

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