Welcome Dialog

Welcome to the Community!

We have a brand new look! Take a tour with us and explore the latest updates on Adobe Support Community.


How to insert text at specific position?

Explorer ,
May 06, 2019 May 06, 2019

Copy link to clipboard

Copied

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();

        }

    }

}

TOPICS
Scripting

Views

1.3K

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Adobe Community Professional , May 07, 2019 May 07, 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

Likes

Translate

Translate
Adobe Community Professional ,
May 06, 2019 May 06, 2019

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 06, 2019 May 06, 2019

Copy link to clipboard

Copied

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].

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 07, 2019 May 07, 2019

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 07, 2019 May 07, 2019

Copy link to clipboard

Copied

REVERSE...

ok something about looping in reverse makes sense. I'm about this close to needing a new keyboard over getting this to work—its so frustrating. The lack of online information available on insertionPoints doesn't help either.

Basically, everything works perfect until i add in the insertion point, then things go crazy. The following 2 lines of code work great, the tab is selected 100% of the time.

//locate second tab

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

//select tab

myParagraphs.characters[secondTab].select();

Here's where the wackiness begins. From what I've read, an InsertionPoint is the space between characters. so I've used the Data Browser to surmise that, with a tab selected, I have an InsertionPoints.length of 2, one before the tab, one after the tab I assume. So, naturally I would want the first index—[0]. So i fire this line off and things go haywire.

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

So instead of: (^ = thinspace)

A     B^     C     D

A     B^     C     D

It starts going in reverse as indicated below. The first iteration works as intended, then the thinspace starts moving backwards one character . Needless to say this caused me a literal headache.

I'll adjust the for loop to run backwards and give it a go. But I'd love to know why in the world is this happening?

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 07, 2019 May 07, 2019

Copy link to clipboard

Copied

spicyDoge  a écrit

I'll adjust the for loop to run backwards and give it a go. But I'd love to know why in the world is this happening?

This is happening because in looping forward within the paragraphs you change the actual character indices while not updating paragraph specifiers. A Paragraph is basically a text range within a story, something like (235,457). Two numbers, as simple as that. When you add some text upstream, the range (235,457) no longer points out to what you think is your original paragraph. The paragraph specifier should be updated to, say, (236,458) if you added one character upstream. But your code does not re-resolve the specifier, so you get a shift, as shown in your screenshot (line 2.) Looping backward solves the problem.

Marc

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 07, 2019 May 07, 2019

Copy link to clipboard

Copied

Thank you for this explanation, This makes perfect sense.

As I was vehemently pacing outside last night, racking my brain as to what could be causing this, I realized that somehow the addition of the thinspace character to the total char. count had to be causing the movement of the thinspace itself. It had not dawned on me until uwe's answer that a reverse loop could remedy this. I was going so far as to subract the loop counter from the insertion point which was working 1% better but not correct at all—i had the right idea, just not the correct execution.

The reverse loop actually solved the issue for me. However, i like the absolute simplicity of your approach and will give that a go the next time I write a loop. I've always been hesitant to use the old while loop as i sometimes create an infinite loop, but its high-time i bit the bullet and learned how to handle that.

You used array.pop, and iirc, it pops off the end of the array which is a reverse loop in itself. Brilliant approach sir.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 07, 2019 May 07, 2019

Copy link to clipboard

Copied

I'm marking this comment as correct as it solved the issue i was having—looping forward instead in reverse—but Marc's approach and explanation is equally as valid and possibly the best way to handle it. It's a little bit out of my 'comfort' zone at the moment, but it makes perfect sense when analyzed.

If you arrived here at a later date, be sure to read Marc's reply Re: How to insert text at specific position? to get a handle on whats happening if your insertions points start bouncing backwards.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 17, 2021 Jul 17, 2021

Copy link to clipboard

Copied

@spicyDoge

 

Can you share the code snippet which you did for tab replacement using GREP. with looping forward approach

 

Thanks.

 

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 18, 2021 Jul 18, 2021

Copy link to clipboard

Copied

LATEST

Can you please share the code snippet which you did for tab replacement using GREP.

As I have the hidden character in my code as ~a ... And I want to replace it ..so probabely I can't use@Mark s suggestions for string replacement..as it finds that character as 

-----

obj 

----while searching with index of..and not the exact word, so using GREP it may work.

 

Thanks.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 07, 2019 May 07, 2019

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 07, 2019 May 07, 2019

Copy link to clipboard

Copied

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?

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 07, 2019 May 07, 2019

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines