Skip to main content
spicyDoge
Known Participant
May 6, 2019
Answered

How to insert text at specific position?

  • May 6, 2019
  • 2 replies
  • 4003 views

In a nutshell, i know exactly where my tab is by using indexOf to get the position of the tab I want.

The problem is I simply cannot find a way to replace the text at that point. Id like to replace "/t" (tab) with "~<\t" (thin space + tab).

Ive tried slicing and joining but it removes all my anchored images.

Ive tried selecting the tab location then using app.selection[0].changeGrep to replace the text but it only works on the first occurance. I'm stumped, what am I missing here?

var myFrames = app.activeDocument.textFrames;

//loop through frames

for (i=0; i < myFrames.length; i++) {

        

    // get all paragraphs

    var myParagraphs = myFrames.paragraphs.everyItem().getElements();

    //loop through paragraphs

    for (n=0; n < myParagraphs.length; n++) {

        //get contents of paragraph

        var myLine = myParagraphs.contents;

        //find first tab

        var tablocation=myLine.indexOf('\t');

        //find next tab

        var tablocation=myLine.indexOf('\t', tablocation+1);

        //select this second tab

        myParagraphs.characters.itemByRange(tablocation,tablocation).select(SelectionOptions.REPLACE_WITH);

        // if tablocation is -1 skip it

        if (tablocation > 1 ) {

            app.findGrepPreferences = app.changeGrepPreferences = null; 

            app.findGrepPreferences.findWhat = "\\t";

            app.changeGrepPreferences.changeTo= "~<\\t";

            app.selection[0].changeGrep();

        }

    }

}

This topic has been closed for replies.
Correct answer Laubender

You can find the tab character by e.g. using GREP Find.

When found the thing that is found is a text. And text has insertion points.

resultsByGREPFind.insertionPoints[0].contents = SpecialCharacters.THIN_SPACE ;

Be careful when assigning new contents.

Do that in reverse order ( from back to forth ) inside a story.

Regards,
Uwe

2 replies

Marc Autret
Legend
May 7, 2019

Hi spicyDoge,

As Uwe wrote, insertionPoints is the way to go. I would add three basic ideas:

  1. Work on Stories rather than TextFrames (unless you really know what you're doing.) Stories allow to access and manage overset text.
  2. Do not `select` things that don't require to be selected. Just send the right command to the destination object.
  3. Avoid both GREP and SpecialCharacters API when the task can be done by simple JS string operations. In your example, the THIN SPACE is just "\u2009".

Here is a possible implementation:

// YOUR SETTINGS

const SEARCH = '\t';       // TAB

const PREFIX = '\u2009';   // THIN SPACE

var from = app.activeDocument.stories.everyItem(),

    a = from.paragraphs.everyItem().texts.everyItem().getElements(),

    t,s,p;

while( t=a.pop() )

{

    // Get the location of the 2nd match in that paragraph.

    // ---

    p = (s=t.contents).indexOf(SEARCH);

    if( -1 == p ) continue;

    p = s.indexOf(SEARCH, 1+p);

    if( -1 == p ) continue;

   

    // No need to redo what is already done!

    // ---

    if( s.charAt(p-1) == PREFIX ) continue;

    // Prepend the prefix.

    // ---

    t.insertionPoints

.contents = PREFIX;

}

@+

Marc

spicyDoge
spicyDogeAuthor
Known Participant
May 7, 2019

Thanks Marc, what you said makes sense and is a new way for me to look at what I'm doing. By looking at it, I understand your approach. Would using while instead of the for loop have the same problem as I've indicated above in my post I made a few minutes ago? Does using while negate the need to loop in reverse?

Marc Autret
Legend
May 7, 2019

spicyDoge  a écrit

Thanks Marc, what you said makes sense and is a new way for me to look at what I'm doing. By looking at it, I understand your approach. Would using while instead of the for loop have the same problem as I've indicated above in my post I made a few minutes ago? Does using while negate the need to loop in reverse?

What is important is not while, but pop().

Thanks to myArray.pop() I get the paragraphs in reverse order.

@+

Marc

Community Expert
May 6, 2019

Hi spicyDoge ,

work with the insertionPoint before your tab.

Assign contents to it like that:

insertionPointBeforeTab.contents = SpecialCharacters.THIN_SPACE ;

Try this with a selection of text.

app.selection[0].insertionPoints[0].contents = SpecialCharacters.THIN_SPACE ;

Here a list of special character enumerators:

Adobe InDesign CS6 (8.0) Object Model JS: SpecialCharacters

Regards,
Uwe

spicyDoge
spicyDogeAuthor
Known Participant
May 6, 2019

Thank you so much for your response.

So basically use the tab position to set the insertion point location, correct? I'm not the most familiar with insertionPoints, so im not sure how to assign a value to the insertionPoint[0].

LaubenderCommunity ExpertCorrect answer
Community Expert
May 7, 2019

You can find the tab character by e.g. using GREP Find.

When found the thing that is found is a text. And text has insertion points.

resultsByGREPFind.insertionPoints[0].contents = SpecialCharacters.THIN_SPACE ;

Be careful when assigning new contents.

Do that in reverse order ( from back to forth ) inside a story.

Regards,
Uwe