skip to Main Content

I have keywords or keyphrases that each occur one or more times in a multi-page document. For each keyphrase, how do I find the page number of each page that it occurs it?

2

Answers


  1. Chosen as BEST ANSWER

    This script takes the currently selected text, uses it as a search phrase, loops through all pages, collects the page numbers of those that contain the search phrase, formats the resulting array as "1, 2, 3, 4", prints it on an alert dialog, and copies it into the clipboard, so the user can paste the resulting string where he wants.

    Note, I found InDesign's scripting engine to be incompatible with any non-ancient Javascript feature, hence the C-style for loops. InDesign's scripting environment also has something called findText and findGrep, which may have been useful, but I failed to find their documentation and I failed to get them to do what I wanted. Your mileage might vary.

    // Used to let the user define what text to search for by selecting text
    function getSelectedText() {
        return app.selection[0].contents
    }
    
    // Used to give user access to the result of the script via the clipboard
    function copyToClipboard(text) {
        var frame = app.activeDocument.pages[0].textFrames.add();
        frame.geometricBounds = [0,0,200,100];
        frame.contents = text;
        frame.parentStory.texts.everyItem().select();
        app.copy();
        $.sleep(300); // just in case
        frame.remove();
    }
    
    // Used for deduplicating the results
    Array.prototype.contains = function(obj) {
        var i = this.length;
        while (i--) {
            if (this[i] === obj) {
                return true;
            }
        }
        return false;
    }
    
    // Given a targetPhrase, returns an array containing every page number it
    // occurs in, in ascending order.
    function findPageNumbersOfOccurancesOfText(targetPhrase) {
      // Create an array to store results
      var results = [];
      // Loop through each spread in the document
      for (var s = 0; s < app.activeDocument.spreads.length; s++) {
          var spread = app.activeDocument.spreads[s];
          
          // Loop through each page within the spread
          for (var p = 0; p < spread.pages.length; p++) {
              var page = spread.pages[p];
              
              // Loop through all text frames on the page
              for (var i = 0; i < page.textFrames.length; i++) {
                  var textFrame = page.textFrames[i];
    
                  // Check if the target phrase exists in the content of the
                  // text frame
                  if (textFrame.contents.indexOf(targetPhrase) !== -1) {
                      // The phrase exists in this text frame
                      pageNumber = page.name
                      // Make sure the result array does not contain duplicates
                      if (!results.contains(pageNumber)) {
                          results.push(pageNumber)
                      }
                  }
              }
          }
      }
    }
    
    
    // The phrase we're searching for is defined as whatever the user has selected
    var targetPhrase = getSelectedText();
    
    var results = findPageNumbersOfOccurancesOfText(targetPhrase);
    
    // Format the result array as something like `1, 2, 3, 4`
    var resultsJoined = results.join(', ')
    
    // Print the formatted results on an alert dialog, for instant feedback
    alert(resultsJoined)
    
    // Copy the formatted results into clipboard, so that the user can paste it
    // where he needs it
    copyToClipboard(resultsJoined)
    

  2. Yepp, it can be done much easier with the findText() method:

    app.findTextPreferences = NothingEnum.NOTHING;
    app.findTextPreferences.findWhat = app.selection[0].contents;
    
    var founds = app.activeDocument.findText(); // get all founds
    
    // get page numbers from the founds without duplicates
    var obj = {}, numbers = [];
    while (f = founds.shift()) {
        var num = f.parentTextFrames[0].parentPage.name;
        if (!(num in obj)) {
            obj[num] = '';
            numbers.push(+num);
        }
    }
    
    numbers.sort(function (a,b) {return a-b}); // sort the numbers
    
    log(numbers.join(', ')); // result
    

    As for the documentation, you can see a lot of examples of Extendscript scripts on Stackoverflow. Good description of the InDesign API is here:

    https://www.indesignjs.de/extendscriptAPI/indesign-latest

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search