Search code examples
javascriptfor-loopadobe-indesign

Indesign Javascript - Make an array from grep query


I have a very long list of entries and I can select the individual entries I need via a GREP query but what I want to do is, each time a GREP query finds a match, I want it to add that selection to an array. The point being, that if I have all of the items from a particular search in an array I can then find the first instance of my query and put in a heading before any of the returned entries.

It might help to have an example of what I am exactly trying to achieve. Below is an example of the list of information I have and you can see on the left is how the text is supplied. The words "Subject Exhibition" appear at the start of each entry. I want to remove the words from the start of each line and instead place one subhead before the first entry.

Indesign text example

What I want help with is figuring out how should I structure the Javascript so that I can figure out what is the first instance of the Subject Exhibition entries.

I figure it will involve a for loop that each time it loops it will perform the grep find and add it to an array but I am not certain if that is the best way of tackling the problem?

Thanks


Solution

  • After finding a similar problem here: JavaScript + InDesign: Find a word in a .indd document and write a .txt file with page number locations I took that code as a starting point and reworked it.

    The first issue I had was that I didn't know how to access the contents of the find function. What InDesign returns from the Find is actually an Array of Text Objects (http://jongware.mit.edu/idcs6js/pc_Array.html).

    So the first step was to put the first result from the Find into a variable.

    var found_txt = app.activeDocument.findGrep ()[0];
    

    As mentioned above, the contents of the Array is a collection of Text Objects and that is all Indesign will return by accessing the first entry of the Array. Next I had to convert the Text Object into a String so I had access to the actual contents of the found text. I got a tip-off from this post here How to store $2 value to variable in InDesign GREP find / change using javascript

    var firstResult = found_txt.contents;
    

    By applying the .contents and putting it in a new variable I now have access to the String of text from the search result. Below is the full code that performed the task I originally posted the question about. Hopefully it it might be useful to someone else.

    main ();
    
    function main() {
    var grepQuery = "Subject Exhibition:.+$";
    
    //Clear any existing Grep preferences
    app.findGrepPreferences = NothingEnum.nothing;
    app.changeGrepPreferences = NothingEnum.nothing;
    
    // set some options, add any that are needed
    app.findChangeGrepOptions.includeLockedLayersForFind = true;
    app.findChangeGrepOptions.includeLockedStoriesForFind = true;
    app.findChangeGrepOptions.includeHiddenLayers = true;
    app.findChangeGrepOptions.includeMasterPages = false;
    app.findChangeGrepOptions.includeFootnotes = true;
    
    //Put the search term into the query
    app.findGrepPreferences.findWhat = grepQuery;
    
    //Put the first result of the find into a variable
    var found_txt = app.activeDocument.findGrep ()[0];
    //the find operation will return an Array of Text Objects.
    //by using Javascripts CONTENTS it takes the reult and converts it into a regular String rather than a Text Object.
    var firstResult = found_txt.contents;
    
    //clear the preferences
    app.findGrepPreferences = NothingEnum.nothing;
    app.changeGrepPreferences = NothingEnum.nothing;
    
    //For the lookahead to work it needs something in front of it so I have told it to look for the return.
    var newQuery = "\\r(?=" + firstResult + ")"
    app.findGrepPreferences.findWhat = newQuery;
    
    
    //and add in the Section Header and Subject Exhibiton header above the found instance
    app.changeGrepPreferences.changeTo = "\\rSubject Exhibition\\r$0";
    app.changeGrepPreferences.appliedParagraphStyle = "Award Header";
    
    //Run the find\Change
    app.activeDocument.changeGrep ();
    
    //Clear Grep preferences
    app.findGrepPreferences = NothingEnum.nothing;
    app.changeGrepPreferences = NothingEnum.nothing;    
    
    alert("Finished");
    return;
    }