Copy link to clipboard
Copied
Hi eveyone,
Using the code below I can see the name of the character style is applied to a word.
var mySelection = app.selection[0];
alert(mySelection.words[6].appliedCharacterStyle.name)
The code above seems to pick up the character style applied to the first part of it.
What I'm trying to do is check if there is more that 1 character style applied to a single word but, as yet I've not managed.
For example, 'posted', has 2 character styles applied - plain and bold. I'm trying to get that count in InDesign via a script.
Is it possible?
Thanks in advance.
Hi @Nick37129562ryen, the object you are looking for is TextStyleRange. You can use it in your example like this:
var mySelection = app.selection[0];
var myWord = mySelection.words[6];
var textStyleRanges = myWord.textStyleRanges;
for (var i = 0; i < textStyleRanges.length; i++) {
var tsr = textStyleRanges[i];
alert(tsr.appliedCharacterStyle.name);
}
Does that make sense? TextStyleRanges are ranges of text that have exactly the same character attributes and styles applied.
- Mark
Copy link to clipboard
Copied
Hi @Nick37129562ryen, the object you are looking for is TextStyleRange. You can use it in your example like this:
var mySelection = app.selection[0];
var myWord = mySelection.words[6];
var textStyleRanges = myWord.textStyleRanges;
for (var i = 0; i < textStyleRanges.length; i++) {
var tsr = textStyleRanges[i];
alert(tsr.appliedCharacterStyle.name);
}
Does that make sense? TextStyleRanges are ranges of text that have exactly the same character attributes and styles applied.
- Mark
Copy link to clipboard
Copied
Hi Mark,
Brilliant! Thanks for your speedy help.
textStyleRanges.length gives me exactly what I was looking for.
Thanks again 🙂
Copy link to clipboard
Copied
Happy to help!
Copy link to clipboard
Copied
Cheers Mark! :beer_mug::clinking_beer_mugs:
Copy link to clipboard
Copied
beer mugs dont work!
Copy link to clipboard
Copied
:clink!:
Copy link to clipboard
Copied
Hi Mark,
Just another quick question, please.
Is it possible to get the page position coordinates of a word, that may have more than one style applied to it, from my initial selection?
Thanks.
Copy link to clipboard
Copied
Hi Nick, have a look at the Character object, particularly these properties:
With these you can piece together a bounds based on the current font's metrics. It isn't the bounds of the glyph's actual paths though; for that you'll something more elaborate.
- Mark
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi Mark,
Thanks for your reply and help.
Sorry, I wasn't very clear with my last question. I was talking about the x,y coordinates of the word on the page. Knowing this would allow me to add a marker on the side of the page to indicate words with multiple character styles applied to them. I'll have a dig around in the properties of a word and see if I can find what I need.
Thanks again.
Copy link to clipboard
Copied
Hi Nick, no, it seems like I wasn't very clear, haha! Those properties literally return coordinates of the character; for example the `ascent` and `descent` of the first character = the top and bottom, and the `horizontalOffset` of the first character of the word and the `endHorizontalOffset` of the last character of the word that is the left and right. So you have a bounding box. Make sense?
In your case you only need, say the `baseline` value and you can put your marker at that height. Or halfway between `ascent` and `descent`.
- Mark
P.S. I like to work in points for jobs like these that don't need a specific unit so I add this line early in my script:
app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
Copy link to clipboard
Copied
Hi Mark,
Thanks for the help regarding word positions etc.
Using info from one of your previous posts I wrote this script:
var mySelection = app.selection[0];
var myWords = mySelection.words;
var errWords = 0;
for (var i = 0; i < myWords.length; i++) {
if (myWords[i].textStyleRanges.length > 1) {
errWords = errWords+1 ;
}
}
alert("errWords = " + errWords)
The script does what I want however, there's one slight problem.
When looking at each word, and the textStyleRanges linked to it, characters like '. , ( )' are included. This throws the results off.
As mentioned previously, I'm trying to write a script that looks at each word, in a selection, to see if that word has 2 character styles applied to it, for example - sample
If the script comes a word like this 'sample.' with a plain full point after the bold copy, the fullpoint is seen as part of the word sample which generates 2 textStyleRanges associated with it.
Is the only way round this to check the contents of each textStyleRange, associated with the word, so check for '. , ( )' ?
Hope that makes sense 🙂
Thanks in advance.
Copy link to clipboard
Copied
Hi Nick, I understand. It comes down to what you mean by "word". Indesign has a particular meaning, which is not our usual one because it includes punctuation, as you noticed. So you can't use this line:
var myWords = mySelection.words;
Instead, you have to decide what a word is for yourself. Something like this, perhaps, using findGrep to match words:
(function () {
var doc = app.activeDocument,
text = doc.selection[0];
if ('function' !== typeof text.findGrep)
return alert('Please select some text and try again.');
// reset grep prefs
app.findGrepPreferences = NothingEnum.NOTHING;
// this is how we could define "a word", but you may need
// to refine because, for example, it won't find "didn't"
// because of the apostrophe
app.findGrepPreferences.findWhat = '[A-Za-z]+';
// find all the "words" in the text
var words = text.findGrep();
if (0 === words.length)
return alert('Please select some words and try again.');
var errWords = 0;
// go backwards here so that if you decide to alter the extent
// of a word, it won't spoil your other references
for (var i = words.length - 1; i >= 0; i--) {
$.writeln('words[' + i + '].contents = ' + words[i].contents);
if (words[i].textStyleRanges.length > 1) {
errWords++;
}
}
alert("errWords = " + errWords)
})();
Sorry that things got a bit more complicated now. Do you know Grep (regular expressions)? If so, you can adjust the `findWhat` in my script above to suit your needs.
- Mark
Edit 2025-03-14: added better documentation to script.
Copy link to clipboard
Copied
Hi Mark,
Brilliant!!! 🙂
Thanks for your help and showing me a different way to approach it.
Your solution works great and does what I was trying to do 🙂
I'm going to try and take it one step further and draw a triangle just off the page to indicate found instances but,
what you've done will already be a big help!
Yes, I'm familiar with Grep thanks. I use it every week in some of my find/replace presets but previously, BBEdit!
Thanks again for all your help.
Cheers Mark 🙂
P.S. Just curious, would my approach of checking the textStyleRange contents have worked or could you forsee issues?
Copy link to clipboard
Copied
I'm going to try and take it one step further and draw a triangle just off the page to indicate found instances
By @Nick37129562ryen
In that case - there is an easier solution - Anchor an object just before your word - or after - with applied ObjectStyle, so you can easily reposition / format all those "highlighters".
Another bonus - they'll flow with the text.
Copy link to clipboard
Copied
Great! Nice idea! 🙂
Thanks for the help.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Only formatting, thanks.
I already have a Grep find/replace I can use to search for a list of words.
Copy link to clipboard
Copied
Only formatting, thanks.
I already have a Grep find/replace I can use to search for a list of words.
By @Nick37129562ryen
Then you don't have to work on the selection - but process this list of found items.
OR... If you copy your graphic into the clipboard - with a "special" GREP expression - you could just do F/C - without the need to analyse anything...
Copy link to clipboard
Copied
Thanks for the help and idea 🙂
Copy link to clipboard
Copied
Great! Yes your approach would have worked too and would have been fine. My way is slightly better in terms of being easier to understand the code (I think!) because it gets the issue out of the way early and we don't have to worry about it ever again. I also used BBEdit back in the day!
Good luck with your script!
- Mark
Copy link to clipboard
Copied
Thanks for the reply, Mark.
I see what you mean about getting the 'issue' out of the way earlier and, therefore, taking it out of the equation.
That must make things quicker too.
Thanks again for all the help.