8 Replies Latest reply on Jan 27, 2014 12:32 AM by Peter Kahrel

    How to find index marks

    LeftHead Level 1

      Hi

       

      I'm trying to managed "index" for my simple Indesign to html conversion tool and I'm totaly confused on how to do it and with the extendscript managment of that "index". So here are (alot of) questions about it:

       

      1. When I'm looping through all the characters of a paragraph, how can I identify "index marks" ? RegExp, specialCharacter...? ** Reply to myself ** Work with Grep search of "\~I"
      2. After finding an "index mark" how can if find the associated "topic" ?
      3. If there can be only one "index" in a document, why is there an "indexes" property ?
      4. What is an "indexSection" ?

       

      Hope there will be somebody to clear my mind

       

      Thanks alot

        • 1. Re: How to find index marks
          Peter Kahrel Adobe Community Professional & MVP

          1. Don't loop: see point 2.

           

          2. You can't. When you find a pageReference object (what you call an index mark), you end up with an object of type Character, and that's not going to tell you anything about topics or anything else related to indexes: it's just a character. Instead, start with topics. Topics have page references (items of type pageReference). A pageReference object has a property sourceText, which is an insertion point. And insertion points have . . . Anyway, you take it from there.

           

          3. An artefact of object models. The collection is in the plural, instances are in the singular. Even if you have just one document open, you address it by app.documents[0]

           

          4. indexSections are sections by letter:

           

          A

          agnostic

          ape

           

          B

          baffled

          bummer

           

          etc.

           

          Peter

          1 person found this helpful
          • 2. Re: How to find index marks
            LeftHead Level 1

            Hi Peter,

             

            I've found your free script for index notes (really precious, here is the link if others are looking for it - http://www.kahrel.plus.com/indesign/lists_indexes.html) and your answer confirm what I was afraid of.

             

            My problem is that my process is based on looping through all characters from all paragraphs from all stories (a sweet hope from a designer who try to code his own way ;-). Of course your script (index-to-text) is a solution ("the" solution ?) but it means to change my way just for this index and there is something that I still don't understand:

             

            By using the index panel, in one way, I can use the button at the bottom of the panel to "go to selected pageReference" (translation from my french version, sorry if it's not exactly the same) but, in the other way, I can select my pageReference in the textFrame and the related pageReference is highlighted in the index panel. So even it's not implemented in extendscript the "way back" exist ?! Or am I completly wrong with the index concept ?

             

            Sebastien

             

            PS: Sorry if I look a little bit stubborn, it's just that I try to understand the concepts behind extendscript, not just going to the result withouth understanding

            • 3. Re: How to find index marks
              Peter Kahrel Adobe Community Professional & MVP

              Sebastien,

               

              If script writers aren't stubborn they'll never get their script problems solved! A note on terminology: ExtendScript, by the way is just JavaScript. What you mean is InDesign's object model.

               

              It's true that when you select an index marker  in a text and you have the Index panel open, the referenced topic is highlighted in the panel. But that's not exposed to scripting, that is, the Character object doesn't have a property 'topic'. However, you can determine the selected marker's topic, even if it's a pretty laborious method. Index markers are characters in the text, so they have a parent story and an index. pageReferences have a property sourceText, which is an insertion point. To find an index marker's topic, you need to compare the marker's insertion point with the insertion points of all pageReferences.

               

              The functionality that you miss -- selecting an index marker so that its parent topic is selected in the Index panel -- can be scripted as follows:

               

              $.writeln (findTopic (app.selection[0]).name);
              
              function findTopic (marker) {
                  var topics = app.documents[0].indexes[0].allTopics;
                  var mStory = marker.parentStory;
                  var mIndex = marker.insertionPoints[0].index;
                  var pRefs;
                  for (var i = topics.length-1; i >= 0; i--) {
                      pRefs = topics[i].pageReferences.everyItem().getElements();
                      for (var j = pRefs.length-1; j >= 0; j--){
                          if (pRefs[j].sourceText.parentStory == mStory && pRefs[j].sourceText.index == mIndex) {
                              return pRefs[j].parent;
                          }
                      }
                  }
                  return "";
              }
              

               

              Select an index marker in a text and run the script (this doesn't select anything in the panel, of course). Now, if you've many index markers, then looping through them to find their topic names could in principle be done as follows:

               

              app.findGrepPreferences = null;
              app.findGrepPreferences.findWhat = '~I';
              markers = app.documents[0].findGrep();
              for (var i = markers.length-1; i >= 0; i--) {
                  $.writeln (findTopic (markers[i]).name);
              }
              

               

              But that would be horribly inefficient (though accurate). Better first to build a lookup table of the pageReferences and their story IDs and sourceText indexes so that you can find topic names quickly.

               

              Your particular approach -- looping through all characters -- needs a bit of a modification in that you need to compare every character with the index.

              Something like this:

               

              for (var i = 0; i < myChars.length; i++) {
                 if (myChars[i].contents == '\uFEFF') {  // myChar is probably an index marker
                    var topic = (findTopic (myChars[i]).name);
                    if (topic != "") {
                        $.writeln (topic);
                    }
                 }
              }
              

               

              Peter

              • 4. Re: How to find index marks
                LeftHead Level 1

                Great !

                 

                I don't understand everything right now but will take some time this week to do it and adapt to my code flow.

                 

                Many thanks for your help

                • 5. Re: How to find index marks
                  Laubender Adobe Community Professional & MVP

                  @Peter – just another idea:
                  Why not duplicating a found <FEFF> character to a new, temporary document?

                   

                  The temp doc would consist of a text frame with the duplicated character, one single index with one single topic. It would be very easy to analyze this topic.

                   

                  A text search could be the start for accessing all <FEFF> characters in a document.

                   

                  Here a sketch that illustrates this idea:

                   

                  var myScope = app.documents[0];
                  
                  app.findTextPreferences = app.changeTextPreferences = null;
                  app.findTextPreferences.findWhat = "<FEFF>";
                  
                  var myResults = myScope.findText();
                  
                  for(var n=0;n<myResults.length;n++){
                  
                      var tempDoc = app.documents.add();
                      var whereToDuplicate = tempDoc.textFrames.add({geometricBounds:tempDoc.pages[0].bounds}).insertionPoints[0];
                  
                      myResults[n].duplicate(LocationOptions.AT_BEGINNING, whereToDuplicate);
                  
                      //Check, if an index is present in the temp document:
                      //If not, drop the rest of the loop, otherwise procede.
                      if(tempDoc.indexes.length === 0){continue};
                  
                      //The name of the topic to the JS console of the ESTK:
                      $.writeln(tempDoc.indexes[0].allTopics[0].name);
                  
                      //Some other things we could do; a for in loop etc.pp.
                      // . . .
                  
                      //Then close the temp doc without saving:
                  
                      tempDoc.close(SaveOptions.NO);
                  
                      };
                  
                  app.findTextPreferences = app.changeTextPreferences = null;
                  

                   

                  Uwe

                  • 6. Re: How to find index marks
                    Peter Kahrel Adobe Community Professional & MVP

                    Hi Uwe,

                     

                    The is that not all FEFF characters are index markers. XML tags too are FEFF, for instance (hence my comment "myChar is probably an index marker", and I thought that there were some others still. Socondly, your approach doesn't allow you to pinpoint the marker's page number. Sebastien didn't exactly ask for that, but what's an index without a page reerence...?

                     

                    Peter

                    • 7. Re: How to find index marks
                      Laubender Adobe Community Professional & MVP

                      @Peter – true.

                       

                      That's the reason I test for the length of indexes in the temp document.
                      No index there? We'll possibly catched a special character for XML tags.
                      Another indication would be an empty text frame in the temp doc.

                       

                      I forgot one thing in my snippet: to close the temp document in case we hit that possibility.

                       

                      However the page name or document offset could be retrieved directly from the <FEFF> character by its "parentTextFrames[0].parentPage.name" or "parentPage.documentOffset".

                       

                      Uwe

                       

                      Message was edited by: Laubender

                      • 8. Re: How to find index marks
                        Peter Kahrel Adobe Community Professional & MVP

                        Well, if there's an index, so that FEFFs could be index markers, you'll have to test that, and the test tells you all you want to know. Besides, if you need to know page numbers, then copying FEFFs to a temp doc is probably not helpful.

                         

                        Peter