Skip to main content
Inspiring
March 5, 2013
Answered

How do I add a two word phrase to index

  • March 5, 2013
  • 2 replies
  • 1179 views

I’m trying to speed up the process of adding Latin names of plants and animals to an index using Indesign CS4. These consist of two word phrases (genus + species) which need to be put into the topic level 1 and topic level 2 boxes of the New Page Reference (Index) dialog. Using Ctrl 7 to invoke the dialog just puts whatever is selected into Topic1 and using Shift+Ctrl+Alt+] adds a ‘proper name’ index entry (Surname, forename) which is no good. When the information has been entered, a simple nested index can be produced, sorted by  genus and then species.

I’m used to programming using vb in MS Office but am totally new to javascript and this has taken two days to get this far. The first problem is that if the user only puts an insertion point into the first word (genus) I can’t figure out how to move to the second word (species) in order to save it to a variable.

So I have:

var myTopic1 = "" ; // topic level 1, i.e. genus

var myTopic2 = "" ; // topic level 2, i.e. species

myIP = app.selection[0] ;

myTopic1 = myIP.words[0].contents ;

This works on a insertion point in any word, or if a phrase is highlighted will take the first word.

Is there a simple way of copying the second word after the insertion point to myTopic2? I’ve tried various methods but can’t get anything to work. I thought it would be a simple matter of adding 1 to the index of the containing paragraph or story.

I’ve got round this in a very long-winded way by asking the user to select the whole genus+species string, then working out the position of the dividing space and reconstructing the genus and species character by character:

var myString = "" ; // user-selected string: genus + species

myString = myIP.contents

myStringlen = myIP.contents.length

var xposn = myString.indexOf(" "); // gives posn of the (first) space character within selected string

var yposn = 0 ; // start of the string

myTopic1 = myString.charAt(yposn) ;

while (yposn < (xposn-1))

{

myTopic1 = myTopic1 + myString.charAt(yposn+1) ;

yposn++ ;

}

while (xposn < myStringlen)

{

myTopic2 = myTopic2 + myString.charAt(xposn+1) ;

xposn++ ;

}

// show results:

alert("Topic1 = " + myTopic1 + ". Topic 2 = " +myTopic2) ;

So at this point I need to figure how to invoke the New Page Reference dialog with Topic1 and Topic 2 filled in? I would like the option of overriding the character format of the page reference ‘Number Style Override’, so would prefer to conclude the script with the dialog left open. Can this be done using script, or do I need a custom dialog? Alternatively it would also be good to just automatically save Topic1 and Topic2 and insert the index marker at the selection point without invoking any dialogs. I’m really struggling to get anywhere with this, can someone please help! Many thanks. Sorry for the long post.

This topic has been closed for replies.
Correct answer Jongware

Jump, that's horribly slow in most cases (i.e., text with more than a couple of thousands of characters)!

This is way faster. The "index" of a word is its offset from the start of its story. Similarly, the "index" of its containing paragraph is the offset from the first character in the paragraph. Subtract them, and you have the position of the word inside that paragraph. Knowing that and the length of the original word, and adding '1' for the next space, you can use 'match' to grab the word right after that:

word1 = app.selection[0].words[0].contents;
par = app.selection[0].paragraphs[0];
word2 = par.contents.substr(app.selection[0].words[0].index-par.words[0].index+word1.length+1).match(/\w+/);

alert ('['+word1+' '+word2+']');

2 replies

Peter Kahrel
Community Expert
Community Expert
March 5, 2013

John,

It can be confusing initially, but JavaScript and InDesign's object model will soon make sense. What you want to do can be done with this script:

w1 = app.selection[0].words[0].contents;

w2 = app.selection[0].words[1].contents;

doc = app.activeDocument;

if (doc.indexes.length == 0){

    doc.indexes.add();

}

species = doc.indexes[0].topics.add (w1).topics.add (w2);

species.pageReferences.add (app.selection[0], PageReferenceType.currentPage);

Select genus and species, then run the script.

It's not possible (I don't think) to open the New page Reference dialog. Do you want to apply the number style override to all page references? If that's the case, don't. Apply the character style to the page numbers after the index has been generated, or better, set it in the index paragraph style.

If you want to apply the number style override only to some pages, you can do as follows. Before selecting genus+species, prefix the genus name with e.g. #. That symbol tells the script to add an override. The script will strip the #, create the page reference, and add the override. You need to tell the script somehow which character style to use for the override.

Peter

Edit: Jump beat me to it, and gives you a different method to get your two words. Spoilt for choice! P.

Inspiring
March 5, 2013

Many thanks to Jump_Over and Peter. I knew it would be simple! I will go through the solutions later tonight. Peter: by the way, I had already seen your web site and tried out some of your indexing scripts, e.g. 'topic and page references from character styles' - which worked a treat. Fantastic resource. Thanks again for you help. John.

Jump_Over
Legend
March 5, 2013

Hi,

In case of catching the next word (which is a part of your goal):

if app.selection[0].words[0] is your 1st word, i.e:

my1stWord = app.selection[0].words[0];

your 2nd word will be:

my2ndWord = my1stWord.parent.words.nextItem(my1stWord);

so use my1stWord.contents and my2ndWord.contents to collect strings for New Page Reference.

rgds

Jongware
Community Expert
JongwareCommunity ExpertCorrect answer
Community Expert
March 5, 2013

Jump, that's horribly slow in most cases (i.e., text with more than a couple of thousands of characters)!

This is way faster. The "index" of a word is its offset from the start of its story. Similarly, the "index" of its containing paragraph is the offset from the first character in the paragraph. Subtract them, and you have the position of the word inside that paragraph. Knowing that and the length of the original word, and adding '1' for the next space, you can use 'match' to grab the word right after that:

word1 = app.selection[0].words[0].contents;
par = app.selection[0].paragraphs[0];
word2 = par.contents.substr(app.selection[0].words[0].index-par.words[0].index+word1.length+1).match(/\w+/);

alert ('['+word1+' '+word2+']');

Inspiring
March 5, 2013

Jongware. Thanks! that works. I had fiddled around with the indexes of the words, but couldn't get anywhere with the complex syntax.