Skip to main content
Inspiring
January 24, 2014
Answered

How to find index marks

  • January 24, 2014
  • 1 reply
  • 4263 views

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

This topic has been closed for replies.
Correct answer Peter Kahrel

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.pageReferences.everyItem().getElements();

        for (var j = pRefs.length-1; j >= 0; j--){

            if (pRefs.sourceText.parentStory == mStory && pRefs.sourceText.index == mIndex) {

                return pRefs.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).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.contents == '\uFEFF') {  // myChar is probably an index marker

      var topic = (findTopic (myChars).name);

      if (topic != "") {

          $.writeln (topic);

      }

   }

}

Peter

1 reply

Community Expert
January 24, 2014

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

LeftHeadAuthor
Inspiring
January 24, 2014

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

Community Expert
January 27, 2014

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


@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