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).
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:
If I type str1 in Console, I get it too:
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
Hi,
Did I misunderstand something or
app.selection[0].lines[0].words[0].contents
is a 1st word, you are looking for?
hope...
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...
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.
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
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.
Kasyan
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
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
Copy link to clipboard
Copied
With .getElements()[0] it works as expected.
Thank you, Harbs, Marc and Jump_Over.