How to get contents string from itemByRange?

Guru ,
Oct 03, 2012 Oct 03, 2012

Copy link to clipboard

Copied

Dear all,

Here is what I am trying to achieve:

I selected a word and want to get the contents of the 1st word in the string (the name of a person).

1.png

In fact, the selected text is the source* of a hyperlink and my goal is to get the person’s name it points to.

*selection[0] is the same as hyperlink.source.sourceText

Since I can’t get the paragraph or line where the selected word is (or simply don't know how to do this), I am trying to get it from the story: starting from the 1st character of the selected word and moving backwards character by character comparing its contents. When it hits “\r”, I know that’s the beginning of the line. This way I can get the part of the line I am interested in with itemByRange() method which returns “Array of Character”.

Main();

function Main() {

    var doc = app.activeDocument;

    var sel = app.selection[0];

    GetName(sel);

}

function GetName(txt) {

    var lastCharacter = txt.characters[0];

    var character = txt.characters[0];

    var story = txt.parentStory;

    var index = lastCharacter.index;

    while (character.contents != "\r") {

        character = story.characters[index];

        index--;

    }

    // Array of Character itemByRange (from: varies, to: varies)

    // Returns the Characters within the specified range.

    var arr = story.characters.itemByRange(character, lastCharacter);

    var str1 = arr.contents[0];

    var str2 = str1.match(/^\S+/);

    return str2;

}

My problem is that I can’t get the contents -- str1 -- by script. However, I can see in Data Browser that it’s there. If I click str1, it shows up:

2.png

If I type str1 in Console, I get it too:

3.png

I also tried to use:

arr.getElements()

arr.getElements()[0]

arr.getElements()[0].contents

etc.

but it didn’t work either.

I must be missing something very obvious, but I am stuck. Can anybody help me, please?

Regards,

Kasyan

TOPICS
Scripting

Views

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

Mentor , Oct 03, 2012 Oct 03, 2012
Hi,Did I misunderstand something orapp.selection[0].lines[0].words[0].contentsis a 1st word, you are looking for?hope...

Likes

Translate

Translate
Mentor ,
Oct 03, 2012 Oct 03, 2012

Copy link to clipboard

Copied

Hi,

Did I misunderstand something or

app.selection[0].lines[0].words[0].contents

is a 1st word, you are looking for?

hope...

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
Guru ,
Oct 03, 2012 Oct 03, 2012

Copy link to clipboard

Copied

Ah! Oh! Sometimes I make such stupid mistakes!

Yes, that's what I was looking for.

I suspected that I was missing something evident. The solution is so simple! How could I look through the "lines" property?!

Thank you very much.

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 ,
Oct 03, 2012 Oct 03, 2012

Copy link to clipboard

Copied

Hi Kasyan,

I don't clearly understand your code. You seem to want:

lastCharacter = txt.characters[-1]; // instead of zero [?]

don't you?

Anyway, take note that Characters.itemByRange() returns a plural Character specifier. The array (of strings) is produced only when you send:

Characters.itemByRange().contents

however it is usually a better idea to use texts[0] as follows:

var charSpec = story.characters.itemByRange(index0, index1);

var str1 = charSpec.texts[0].contents; // no need to deal with an array

When possible, texts[0] converts a plural specifier into a singular Text specifier.

Hope that helps,

[Apart from that, Jump_Over's suggestion sounds good to me.]

@+

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
Guru ,
Oct 03, 2012 Oct 03, 2012

Copy link to clipboard

Copied

I don't clearly understand your code. You seem to want:

lastCharacter = txt.characters[-1]; // instead of zero [?]

don't you?

Hi Marc,

No, lastCharacter is the 1st character in the selection but the last character in the text range.

My GetName function is unnecessary complex way to get the 1st word in the line.

Jump_Over's suggestion works for me perfectly, but for pure academic interest I want to solve this problem.

I tried to do what you suggested, but it didn't work:

var charSpec = story.characters.itemByRange(217, 240);

var str1 = charSpec.texts[0].contents;

var str2 = str1.match(/^\S+/);

The last line throws an error: str1.match is not a function.

And str1 is not string, but array.

4.png

5.png

Kasyan

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 ,
Oct 03, 2012 Oct 03, 2012

Copy link to clipboard

Copied

Indeed! I seem to remember that something has changed in the latest ID versions regarding:

Texts.itemByRange(…).texts[0].contents

I think this now returns a singleton Array —while it was a String in CS4 or something. This is a very critical issue, by the way.

Sorry for the mistake.

@+

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
LEGEND ,
Oct 03, 2012 Oct 03, 2012

Copy link to clipboard

Copied

I make a practice to always use getElements()[0] when using itemByRange(). This normalizes the results. Trying to remember what every use of itemByRange() returns is too much overhead for me. It also helps avoid issues like this where the return type changes...

Harbs

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
Guru ,
Oct 03, 2012 Oct 03, 2012

Copy link to clipboard

Copied

LATEST

With .getElements()[0] it works as expected.

Thank you,  Harbs, Marc and Jump_Over.

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