Activity › Forums › Adobe After Effects Expressions › Text color without ponctuation
-
Text color without ponctuation
Posted by Franck Michel on September 18, 2024 at 10:10 pmI am doing a simple thing, control the color of words in a text layer using another text layer.
Thanks to a 2017 thread with a great expression by Dan Ebberts it works very well.
The only problem I have is that I would like the ponctuation to keep the original color.
As with a text like “box,” I want the word box to get the new color red but the comma to stay black.
Is there a way to add a condition for characters like , ; . ? ! which are always attached to a word to never take the overiding color?
I will add the original expression from Dan and a screen capture of my exemple.
Sorry for my approximate English I am not a native.
Thanks to those reading this.
Bonus point if someone can explain to me the “i” reference in Dan’s expression.
hilite = thisComp.layer(“hilite”).text.sourceText.split(“+”);
result = 0;
for (i = 0; i < hilite.length; i++){
if (textIndex == parseInt(hilite[i],10)){
result = 100;
break;
}
}
resultBrie Clayton replied 2 weeks, 5 days ago 3 Members · 9 Replies -
9 Replies
-
Andrei Popa
September 19, 2024 at 7:55 amI cant think of a different way but to count the characters instead of words.
So if you want to use this solution, you need to change the “Based on” from “words” to “characters” and use this expression instead.
You can add/remove characters you don’t want to be highlighted in the “punctuation” variable;
function getCharIndicesFromWordIndices(str, wordIndices) {
var words = str.split(/\s+/);
var charIndices = [];
var currentCharIndex = 0;
var punctuation = ",.!?;:'";
for (var i = 0; i < words.length; i++) {
if (wordIndices.indexOf(i) !== -1) {
for (var j = 0; j < words[i].length; j++) {
if (punctuation.indexOf(words[i][j]) == -1) charIndices.push(currentCharIndex + j);
}
}
currentCharIndex += words[i].length + 1; // +1 for the space
}
return charIndices;
}
wordIndices = thisComp.layer("hilite").text.sourceText.split("+");
var x = getCharIndicesFromWordIndices(text.sourceText, wordIndices.map(x => parseInt(x)));
x.indexOf(textIndex - 1) != -1 ? 100 : 0; -
Franck Michel
September 19, 2024 at 9:09 amAndrei, thank you so much for having taken the time to find a perfect solution to my problem.
I can’t even begin to understand the expression (I will try though) but it works so well I want to hug you.
What should I change so when I type 1 in the control layer it highlights the first word and not the second?
It’s just a luxury for my poor brain when I have loads of texts to process and it’s 2 AM 😉
Thanks again
-
Andrei Popa
September 19, 2024 at 12:56 pmSorry for the oversight. We can fix that by subtracting 1 from each value in the index of words (which I did in the .map() function towards the end of the expression), since arrays start at zero, and our word counting at one.
Here is the updated code.function getCharIndicesFromWordIndices(str, wordIndices) {
var words = str.split(/\s+/);
var charIndices = [];
var currentCharIndex = 0;
var punctuation = ",.!?;:'";
for (var i = 0; i < words.length; i++) {
if (wordIndices.indexOf(i) !== -1) {
for (var j = 0; j < words[i].length; j++) {
if (punctuation.indexOf(words[i][j]) == -1) charIndices.push(currentCharIndex + j);
}
}
currentCharIndex += words[i].length + 1; // +1 for the space
}
return charIndices;
}
wordIndices = thisComp.layer("hilite").text.sourceText.split("+");
var x = getCharIndicesFromWordIndices(text.sourceText, wordIndices.map(x => parseInt(x) - 1));
x.indexOf(textIndex - 1) != -1 ? 100 : 0;In short, we used the “getCharIndicesFromWordIndices” function to get the index of each character present in your words, except punctuation. So instead of highlighting the word entirely, we highlight each character that is a part of that word.
-
Franck Michel
September 19, 2024 at 2:32 pmOnce again thank you so much Andrei!
It’s perfect and my brain will not trip in the middle of the night.
With your explanations I am going to try to reconstruct it from scratch to learn some mechanics in play here. It will be great for my learning experience.
-
Franck Michel
September 22, 2024 at 9:19 pmHello Andrei,
I have worked integrating your great expression in my project. As I previously said it works very well.
There is only one exception that blocked me, and maybe it’s not possible to accommodate for it.
When I want to highlight a word like “that’s”, as you can imagine I would like all the letters and the ‘ to be red but as of now, the letters, even the “s” turns red but the ‘ stays black.
Do you think there is a way to tell After Effects to check that the ponctuation is at the end of word with a space after it to let it be black, but if it’s followed by a letter to integrate it and turn it red?
This might be a little too much but if you have an idea I am all ears.
Thanks again.
-
Andrei Popa
September 23, 2024 at 3:54 pmI see 2 solutions for this problem.
1. Just remove the ‘ character from the group of characters to ignore. (row 5 becomes var punctuation = “,.!?;:”;)
2. I will alter a bit the expression to ignore punctuation that does not have a space after it. Keep in mind that this will also alter “2.3” for example, and the dot will be highlighted.
function getCharIndicesFromWordIndices(str, wordIndices) {
var words = str.split(/\s+/);
var charIndices = [];
var currentCharIndex = 0;
var punctuation = ",.!?;:'";
for (var i = 0; i < words.length; i++) {
if (wordIndices.indexOf(i) !== -1) {
for (var j = 0; j < words[i].length; j++) {
if (!((punctuation.indexOf(words[i][j]) != -1) && j == words[i].length - 1)) charIndices.push(currentCharIndex + j);
}
}
currentCharIndex += words[i].length + 1; // +1 for the space
}
return charIndices;
}
wordIndices = thisComp.layer("hilite").text.sourceText.split("+");
var x = getCharIndicesFromWordIndices(text.sourceText, wordIndices.map(x => parseInt(x) - 1));
x.indexOf(textIndex - 1) != -1 ? 100 : 0; -
Franck Michel
September 24, 2024 at 12:33 pmAndrei, once again you hit the bulls eye!
Your second solution works perfectly for what I have to do.
And for the occasional 2.3 case, I think it would be logical to have the . highlighted as well as the numbers.
Again, thank you so much for taking the time to help me with this expression trickery.
Reply to this Discussion! Login or Sign Up