Script to import partial filename

Learn / Forums / InDesign Add-ons (Scripts, Scripting, and Plug-ins) / Script to import partial filename

Viewing 20 reply threads
  • Author
    Posts
    • #71683

      I have a scripting question. Which is tricky since I don’t know scripting. So bear with me…

      I know InDesign can import a full filename as variable text. We want it just to import the first 4-5 characters of its filename and have it automatically change every time the doc is saved with a new filename.

      Our filenames are in this format:
      XXXXX_Name1_Name2_Name3.indd

      Everything before the first underscore is what we want to place into a document. (The ‘XXXXX’ portion of the filename). So the text variable will just display as ‘XXXXX’.

      The document will be a template, so it will always open with ‘Untitled-1.indd’ (or 2 or whatever, depending on how many files I forgot to close).

      Is this even possible?

      Thanks.

    • #71696
      Oleh Melnyk
      Member

      I don’t understand what you want to do exactly, but try this:

      1) go to Type > Text Variables > Define
      2) create new varialbe, and give it name “myVariable”, and type – “Custom Text”
      3) paste this variable to your document
      4) create .jsx file, and copy/past there this code:

      #target indesign;
      #targetengine "myCustomGetFileNameHandler";
      
      myHandler = function(ev)
      {
          fileNameVariable = app.activeDocument.name.split("_")[0]; // get XXXXX from XXXXX_Name1_Name2_Name3.indd file name
          alert(fileNameVariable); // show XXXXX
          app.activeDocument.textVariables.item ("myVariable").variableOptions.contents = fileNameVariable;
          // ...do what you need here...
      }
      
      app.activeDocument.addEventListener("beforeSave", myHandler);
      

      5) save this .jsx script file, and run it before saving your document – it should get XXXXX part from document name and set it as your text variable value
      6) if you want this script to load automatically – you can put it to “startup scripts” folder

    • #71698

      You already asked this on other forums: https://graphicdesign.stackexchange.com/questions/42328/how-do-i-automatically-insert-a-partial-filename-in-indesign, https://forums.adobe.com/thread/1633660

      It is not considered polite to make several different groups of people work independently for you.

    • #71793
      Oleh Melnyk
      Member

      @Jongware why not? firstly it’s always a chance not to get the answer to question you asked.. the only thing is that it’s a good idea to cross-reference those questions and update them all if someone in one of those forums has found the full or partial solution

    • #71797

      Oleh: because you would make several groups of people read and think about it INDEPENDENTLY.

      That means that on one forum, someone could ask for a clarification (which then would be given in that forum only; or, the OP would need to visit all of these forums and add it everywhere). If someone has a partial solution or suggestion, the people of the other forums cannot enhance or suggest further options based on it. Finally, if a working solution gets posted in one forum, the readers of all the others may not be aware of this and continue to work on it.

    • #92446
      Omar Khatib
      Member

      Is this working? I posted earlier and my post hasn’t showed up?

    • #92449
      Omar Khatib
      Member

      Okay I guess I need to try it again.

      I am trying the same thing but the filename is structured like this: page#_CatCode NotSoRandomNameVersion#.indd (i.e. 203_DS CouldBeAnything04.indd)

      I want to capture the “CatCode” which could be 2-5 uppercase characters located after the first underscore and before the first space.

      In the script above…

      “fileNameVariable = app.activeDocument.name.split(“_”)[0]; // get XXXXX from XXXXX_Name1_Name2_Name3.indd file name
      alert(fileNameVariable); // show XXXXX”

      The split(“_”) splits the name with the underscore but how does it know to show the first instance? Can I split the name with and underscore and a space?

      Can I do a grep find in Javascript?

      Thank you in advance for the help!

    • #92453
      Oleh Melnyk
      Member

      – how does it know to show the first instance?
      fileNameVariable = app.activeDocument.name.split(“_”)[0] // < [0] means “first instance”

      – Can I split the name with and underscore and a space?
      sure, you can write any pattern to split: .split(” _”) or .split(“_ “) or whatever fits your needs

      – Can I do a grep find in Javascript?
      almost! you can do a regexp, which is simplified version of grep

      – I want to capture the “CatCode” which could be 2-5 uppercase characters located after the first underscore and before the first space.
      try this:
      “page#_ABCDE NotSoRandomNameVersion#.indd”.match(/[A-Z]{2,5}(?=\s)/)[0] // should return “ABCDE”

    • #92460
      Omar Khatib
      Member

      I found some local help! This is the script that is working for my situation:

      #target indesign;
      #targetengine “myCustomGetFileNameHandler”;

      var myHandler = function(ev)
      {
      fileNameVariable = app.activeDocument.name.split(“_”)[1];
      // alert(fileNameVariable);
      fileNameVariable1 = fileNameVariable.split(” “)[0];
      app.activeDocument.textVariables.item (“SlugArea”).variableOptions.contents = fileNameVariable1;
      }

      app.eventListeners.add(“beforeSave”, myHandler);

      I wish I could spend more time learning how to script.

    • #92490
      Omar Khatib
      Member

      The new tidier script with Oleh’s input:

      #target indesign;
      #targetengine “myCustomGetFileNameHandler”;

      var myHandler = function(ev)
      {
      fileNameVariable = app.activeDocument.name.match(/[A-Z]{2,5}(?=\s)/)[0];
      // alert(fileNameVariable);
      app.activeDocument.textVariables.item (“SlugArea”).variableOptions.contents = fileNameVariable;
      }

      app.eventListeners.add(“beforeSave”, myHandler);

      Love the help, thanks again Oleh! I can’t say I am ready to create my own scripts but this helps a lot in learning how to manipulate them.

    • #92526
      Omar Khatib
      Member

      One more issue I can’t figure out. I added an if statement to account for document that don’t have the “SlugArea” text variable. the new script looks like this:

      #target indesign;
      #targetengine “mysession”;

      var myHandler = function(ev)
      {
      if(app.activeDocument.textVariables.item (“SlugArea”).isValid)
      {
      fileNameVariable = app.activeDocument.name.match(/[A-Z]{2,5}(?=\s)/)[0];
      // alert(fileNameVariable);
      app.activeDocument.textVariables.item (“SlugArea”).variableOptions.contents = fileNameVariable;
      }
      }

      app.eventListeners.add(“beforeSave”, myHandler);
      app.eventListeners.add(“beforeSaveAs”, myHandler);

      When this runs the first time on a fresh new template I get an error message…

      null is not an object
      Do you want to disable this event handler?
      Check Box Don’t Show Again No Yes

      When you choose “No” this script continues and works but it makes me feel like something bad is happening that I am not aware of.

      What could be causing this error? Is it hurting anything? Is there a way to make it go away without checking that box?

      • #92529
        Oleh Melnyk
        Member

        there are a lot of things that might cause the problems:
        1) you are getting SlugArea variable from the file name, but you are getting this BEFORE file is saved (so there might be wrong file name)
        2) you are trying to save document while script are working (getting and setting SlugArea variable) so saving is locked, which might cause the problem
        3) you create 2 new event handlers every time you run the script, and they ALL keep working till you remove them manually or till you restart InDesign (!!!) – so if you, for example, started script 5 times – on each “Save” or “Save As” 5 event handlers try to execute…at the same time…
        4) maybe something else I am not aware of

        try this:


        #target indesign;
        #targetengine “mysession”;

        // https://creativepro.com/topic/script-to-import-partial-filename#post-92526

        // every time you run the script you add 2 new event handlers - we need to remove the old ones
        try{
        if(app.eventListeners.length > 0){
        app.removeEventListener("afterSave", myHandler);
        app.removeEventListener("afterSaveAs", myHandler);
        }
        }catch(e){
        $.writeln(e);
        }

        // create "SlugArea" text variable (if it missing)
        if(!app.activeDocument.textVariables.item("SlugArea").isValid){
        app.activeDocument.textVariables.add({ variableType: VariableTypes.CUSTOM_TEXT_TYPE, name: "SlugArea"});
        }

        // set default value if varible is empty
        if(app.activeDocument.textVariables.item("SlugArea").isValid && app.activeDocument.textVariables.item("SlugArea").variableOptions.contents.length == 0){
        app.activeDocument.textVariables.item("SlugArea").variableOptions.contents = "SlugArea (default value)";
        }

        var myHandler = function(ev){
        var fileNameVariable = app.activeDocument.name.match(/[A-Z]{2,5}(?=\s)/)[0];

        // if we found what we were looking for
        if(typeof fileNameVariable == "string" && fileNameVariable.length > 2) {
        // set proper value for text variable...
        app.activeDocument.textVariables.item("SlugArea").variableOptions.contents = fileNameVariable;
        }
        }

        // since we generate SlugArea varibale from the file name - we need to do that AFTER file is saved, and its name was changed...
        app.eventListeners.add("afterSave", myHandler);
        app.eventListeners.add("afterSaveAs", myHandler);

        but you will have to re-save document (Ctrl + S / Cmd + S) manually after slug area is set

    • #92569
      Omar Khatib
      Member

      I tried the script as is and it didn’t work. Openning InDesign got:
      Error Number: 90884
      Error String: No documents are open

      The variable did not change as expected.

      In our workflow the template we are using for this project will always have the “SlugArea” variable. We want the script to simply ignore any other document.

      I was able to take parts of the new script and got something working, it looks like this:

      #target indesign;
      #targetengine “mysession”;

      var myHandler = function(ev)
      {
      try{
      if(app.eventListeners.length > 2){
      app.removeEventListener(“afterSave”, myHandler);
      app.removeEventListener(“afterSaveAs”, myHandler);
      }
      }catch(e){
      $.writeln(e);
      }

      if(app.activeDocument.textVariables.item(“SlugArea”).isValid){
      fileNameVariable = app.activeDocument.name.match(/[A-Z]{2,10}(?=\s)/)[0];
      // alert(fileNameVariable);
      app.activeDocument.textVariables.item(“SlugArea”).variableOptions.contents = fileNameVariable;
      }
      else{
      //…
      };
      }

      app.eventListeners.add(“afterSave”, myHandler);
      app.eventListeners.add(“afterSaveAs”, myHandler);

      I am going to keep testing but it seems to be working.

      On line 7 “if(app.eventListeners.length > 2){“:

      In your script you had it set as “> 0”. When that was the case the script only worked on the first page that was opened, so I changed to “> 2” and it works continuously.

      Thanks again Oleh! Do you have a donation page or something?

      • #92570
        Oleh Melnyk
        Member

        Strange, how the variable can be changed if “No documents are open” and script should execute after save?
        But I don’t know your workflow, maybe I am missing something…

        As for “if(app.eventListeners.length > 0)” – length should be 0 – we check if there are 2 event listeners – if so – we remove the old ones and then add 2 new listeners… After you changed it to 2 – there might be 2-4 listeners (2 old and 2 new), but if it works – let it be, lol

        No donation page, at least for now (still can’t accept PayPal in my country)

    • #92573
      Omar Khatib
      Member

      Thanks again for all your help Oleh!

    • #112601
      Scott Rudy
      Participant

      I have a start on a different way but do not know how to get it to actually work….

      the below script will insert the beginning of the filename up to that underscore into the document at the point where you have the text insertion point.

      #target indesign;
      #targetengine “myCustomGetFileNameHandler”;

      fileNameVariable = app.activeDocument.name.split(“_”)[0]; // get XXXXX from XXXXX_Name1_Name2_Name3.indd file name
      // app.activeDocument.textVariables.item (“myVariable”).variableOptions.contents = fileNameVariable;

      myTextFrame = app.selection[0];
      firstInsertionPoint = myTextFrame.insertionPoints[-1].index;
      myTextFrame.contents += fileNameVariable;
      myAddedText =
      myTextFrame.characters.itemByRange(myTextFrame.insertionPoints[firstInsertionPoint],
      myTextFrame.insertionPoints[-1]);

      what i’m thinking is can i replace the insertion point with a grep find/change that will search the entire document for \<[\l\u]+[\d+]_
      which will find my file name format that is ABC123456 (sometimes i have a few extra letters at the beginning)
      and replace it with the “file name variable”

      ideally i would like it to call up an alert if they are different in case there was a reason for the difference

      scott

    • #112747
      Scott Rudy
      Participant

      AMAZING!!!!!!
      you understood exactly what i needed. I am adding this to a larger script that does a simple preflight, metatag, collect for output, and makes a high and low res PDF all saved in the proper folders. this is just another part of keeping my designers consistent in how they are saving the final art for our projects.

      the only issue is it finds abc123456_
      and returns abc123456 without the underscore

      what line do i need to change to keep the underscore?

      scott

    • #112752
      Oleh Melnyk
      Member
    • #112794
      Scott Rudy
      Participant

      what would need to be changed so it does not ask if you want to change the “job code” if it is matching the file name

      currently it always asks even if it does not need replacing

      scott

    • #112796
      Oleh Melnyk
      Member

      line 35 – change:
      if (confirm(“Do you want to replace ” + foundContents + ” with ” + fileNameVariable, false, “Replace?”)) {

      to:
      if (foundContents !== changeTo && confirm(“Do you want to replace ” + foundContents + ” with ” + fileNameVariable, false, “Replace?”)) {

      https://gist.github.com/olehmelnyk/57ef6cc65801329c22ec3c91b53cfe01

    • #112981
      Scott Rudy
      Participant

      I just wanted to say thank you for helping me with this, it now works great!!!!!
      I added it to a larger script that i run when the file is approved. the script preflights the job (including the job code slug line), does a collect, makes a high and low res PDF and a few other archiving type of operations. no more projects going out with an incorrect job code!!!!

      scott

    • #14323308

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

    • #14323304
      Oleh Melnyk
      Member

      app.activeDocument.name[2] // should return 3rd character of the file name (zero-based index)
      app.activeDocument.name[4] // should return 5th character of the file name

Viewing 20 reply threads
  • You must be logged in to reply to this topic.
>