Copy link to clipboard
Copied
Sorry for reposting, but i did so in the wrong forum.
I found this script for adding Job Numbers using Indesign Variables, but i was wondering if anyone knows how to get it to read the first 9 characters (numbers and letters) of the filename instead of just the first 2? Any help would be greatly appreciated.
Here's what i'm trying to acheive:
I have an indesign slug with job information in it. I want the script/variable to update a "JobNumber" text field based on the first 9 characters in the filename. Eg. 12ABC1234_client_description
Thanks in advance.
app.addEventListener("afterSaveAs", updateJobNumber, false);
function updateJobNumber ()
{
if (app.activeDocument.saved)
{
varRef = app.activeDocument.textVariables.item("JobNumber");
if (varRef.isValid)
{
fileId = app.activeDocument.fullName.name.match(/^\d+/);
if (fileId)
{
if (varRef.variableOptions.contents != fileId[0])
{
varRef.variableOptions.contents = fileId[0];
app.activeDocument.save();
}
}
}
}
}
Copy link to clipboard
Copied
Hello,
The line you want to change is this one:
fileId = app.activeDocument.fullName.name.match(/^\d+/);
The .match method at the end of the line is looking only for digits at the moment.
So, you want to change it so it matches the first 9 digits and uppercase letters?
Try using this grep:
^[\d\u]{9}
You might need to use the findGrep() method.
Copy link to clipboard
Copied
Thank you for your response. I must be missing something because nothing happens when i run the script.
Copy link to clipboard
Copied
Do you keep the first and last forward slash?
.match(/put your grep here/);
Copy link to clipboard
Copied
Ok, i tried this and i no longer get the error, but still nothing happens. Here's the script:
app.addEventListener("afterSaveAs", updateJobNumber, false);
function updateJobNumber ()
{
if (app.activeDocument.saved)
{
varRef = app.activeDocument.textVariables.item("JobNumber");
if (varRef.isValid)
{
fileId = app.activeDocument.fullName.name.match(/^[\d\u]{9}/);
if (fileId)
{
if (varRef.variableOptions.contents != fileId[0])
{
varRef.variableOptions.contents = fileId[0];
app.activeDocument.save();
}
}
}
}
}
Copy link to clipboard
Copied
Also, do you have a text variable called "JobNumber"?
Try doing:
app.activeDocument.textVariables.itemByName("JobNumber");
Copy link to clipboard
Copied
Yes, i have a text variable called JobNumber. See attached.
Copy link to clipboard
Copied
fileId = app.activeDocument.fullName.name.match("^[\\d\\u]{9}");
Copy link to clipboard
Copied
Hey, Jake. Thanks again for all the help, but still nothing is happening. So i tried the script on another mac and i got this error message:
Copy link to clipboard
Copied
Hi Attil,
I think it's got something to do with the EventListener.
When I test your script it works for me.
Just run this:
function updateJobNumber () {
if (app.activeDocument.saved) {
varRef = app.activeDocument.textVariables.itemByName("JobNumber");if (varRef.isValid) {
fileId = app.activeDocument.fullName.name.match("^[\\d\\u]{9}");
alert(fileId);
if (fileId) {if (varRef.variableOptions.contents != fileId[0]) {
varRef.variableOptions.contents = fileId[0];
app.activeDocument.save();
}
}
}
}
}
updateJobNumber ();
Copy link to clipboard
Copied
Still nothing. Just FYI, i'm running Indesign CC 2017 on a Mac OS X Yosemite 10.10.5.
Copy link to clipboard
Copied
Do you get an alert?
Copy link to clipboard
Copied
function updateJobNumber () {
varRef = app.activeDocument.textVariables.itemByName("JobNumber");
if (varRef.isValid) {
fileId = app.activeDocument.fullName.name.match("^[\\d\\u]{9}");
alert(fileId);
if (fileId) {
if (varRef.variableOptions.contents != fileId[0]) {
varRef.variableOptions.contents = fileId[0];
app.activeDocument.save();
}
}
}
}
updateJobNumber ();
Copy link to clipboard
Copied
This is the only alert i get upon restarting Indesign:
Copy link to clipboard
Copied
There are a number of interesting issues here.
⢠First, as you are using a startup script purposed to set an event listener, you usually need a #targetengine directive (to keep the function available in memory.)
⢠The updateJobNumber function is designed as an event handler, that is, it is only triggered by a save-as event and won't work if called directly from the script. In particular, a startup script won't find any document available, of course. (Which explains the very last error you've encountered.)
⢠To me, there is no reason to attach the process to 'afterSaveAs' (which occurs once the document file has been saved on disk.) Regarding the task of updating a text variable before saving the doc, 'beforeSaveAs' seems the way to go. The problem with save-as events is that you can't use doc.save() commands within the handler, as InDesign is already committed in saving the file! 'beforeSaveAs' allows you to provide final refinements to the document just before the system actually writes the fileābut the process is already underway, so you don't need doc.save() at all in that context.
⢠Last point: the metacharacter \u is GREP-specific and has no meaning in JS RegExp syntax. Use the class [A-Z] instead (at least, as a first approximation.)
Now, the really interesting question is the following:
From within a beforeSaveAs handler, how can we identify the final file name of the document which, at this specific moment, still owns its previous fullName property (including invalid cases where the doc hasn't be saved yet) ?
The answer is, you cannot retrieve the incoming file name from the document itself
BUT
save-as events expose a (hidden?) property that fills the gap: event.fullName
Here we go:
// The present code can be used as a startup script.
#targetengine 'UpdateJobNumber'
const updateJobNumber = function(/*Event*/ev, doc,m,t)
// -------------------------------------
// BEFORE_SAVE_AS event handler.
// Reset the `JobNumber` 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 'beforeSaveAs' (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 `JobNumber` TextVariable...
// 6. ...of the kind 'Custom text.'
// 7. No need to rewrite the variable if already set as expected.
{
( 'beforeSaveAs' == ev.eventType )
&& ( m=ev.properties.fullName )
&& ( m=m.name.match(/^[A-Z\d]{9}/) )
&& ( (doc=ev.target) instanceof Document )
&& ( (t=doc.textVariables.itemByName('JobNumber')).isValid )
&& ( (t=t.variableOptions) instanceof CustomTextVariablePreference )
&& ( m[0] != t.contents )
&& ( t.contents=m[0] );
};
app.addEventListener('beforeSaveAs', updateJobNumber);
Hope that helps.
@+
Marc
Copy link to clipboard
Copied
WOW! This is awesome. Thank you to both of you for all your help! Just one more question. Is there a way to have the script run as soon as you open an existing document without having to use the "save as" command? Most of my jobs are already created and just need updated by a regular "save" command.
Copy link to clipboard
Copied
Actually i got this error when i restarted the application:
Offending Text: ^