Skip to main content
October 5, 2009
Answered

[JS][CS3]Applying Character Style to First Word

  • October 5, 2009
  • 1 reply
  • 1110 views

I am a noob as far as Javascript  is concerned, and I was hoping for a little guidance.

Here's my scenario: I have a book that has been typeset all in one file; the main content is all in one story. I want to select the first word of every text frame on each page and apply a character style. My goal is to utilize this character style to indicate page breaks in the XML--I'll map the style to a specific tag.

So far I have this poor specimen:

var myDocument = app.activeDocument;
var myPage = myDocument.pages.item(1);
var myTextFrame = myPage.textFrames.item(0);


if( app.activeDocument.stories[0].paragraphs[0].words[0] != null )
myTextFrame.paragraphs.item(0).words.item(0).appliedCharacterStyle =
myDocument.characterStyles.item('foo');

I know, I haven't set up any sort of loop yet (which will be trickier given the fact that there will be blank versos, etc). What I'm trying to do in this is to select the first word in the first paragraph on the second page--which it does in fact do. Problem is, the first paragraph on the second page starts on the first page, so I'm selecting that a word on the first page, not the second page.

As I said, lots of work to do but a little help on getting to the right word would be most appreciated.

This topic has been closed for replies.
Correct answer Jongware

Well, you were on the right track, but testing 'myText' fails if there is no text frame on a page because it fails one line earlier

>var myTextFrame = myPage.textFrames.item(0);

just before this, you should test the number of text frames:

if (myPage.textFrames.length > 0)

{

  ... your stuff ..

}

Only use this if you are absolutely positive there is just a single text frame on each page! A slightly better way would be to always loop over each textframe:

for (frames=0; frames<myPage.textFrames.length; frames++)

{

  var myTextFrame = myPage.textFrames.item(frames);

  ..etc.
}

in which case you also don't have to test its length first (the loop will not be executed if there are zero text frames).


[Techy] Since you have only one continuous story, an even better way would be to loop over the textframes of that story alone. You have to identify the story somehow, and I usually click the text cursor in the one I need:

myStory = app.selection[0].parentStory;

or you can rely on the fact that the story starts in the only text frame on page 1:

myStory = app.activeDocument.pages[0].stories[0];

(I think that oughta work.) Then, each frame of this story up till the end can be found in the array

myStory.textContainers

which are usually text frames. You can loop over these using

for (frame=0; frame<myStory.textContainers.length; frame++)

{

  myTextFrame = myStory.textContainers[frame];

..etc.

}

1 reply

Jongware
Community Expert
Community Expert
October 5, 2009

You don't have to refer to paragraphs, you can immediately use words:

alert ("["+app.selection[0].parentTextFrames[0].words[0].contents+"]");

always shows the first word in your current text frame. Do note, however, that a word may be split due to hyphenation (it shows the entire word). An additional, eh, 'feature' (?) is that blank lines are ignored. A good solution, however, would be to go one step down and use characters:

alert ("["+app.selection[0].parentTextFrames[0].characters[0].contents+"]");
October 5, 2009

Excellent, thank you. I take your point about hyphenation, and I'm working with just the first character.

Now to work through the looping; should be straightforward enough.

Jongware
Community Expert
Community Expert
October 5, 2009

It's as straightforward as anything in InDesign. Well, up to a certain point

Every document has a Pages array so you can use .length to loop over all. The pages do not correspond to 'page numbers', as these are fleety things. The array starts at '0' for the first page and continues to the end of the doc.

Similarly, each page can immediately refer to its contents -- in this case you want just the TextFrames. Do not use PageItems, as this holds "all" items, including graphics, lines, circles and whatnot. You can loop over all of these text frames inside the pages loop.

Wanna have a go at it yourself?