Change text color in tables! …
Copy link to clipboard
Copied
Hi Scripters,
I'm trying to change color of the text in some rows but not all! As:
… with this code:
var
myDoc = app.activeDocument,
myTables = myDoc.stories.everyItem().tables.everyItem().getElements();
for ( var t = 0 ; t < myTables.length; t++ )
{
var myRows = myTables
.rows; for ( var r = 1 ; r < myRows.length; r += 2 )
{
var myCells = myRows
.cells; for ( var c = 0 ; c < myCells.length; c++ )
{
myCells
.contents.fillColor = myDoc.colors.itemByName("Blue"); }
}
}
… But, of course, it doesn't work!
As usual, thanks for your help!
(^/)
Copy link to clipboard
Copied
… Apparently, my error is at line 13. To be corrected as:
myCells
.texts[0].fillColor = myDoc.colors.itemByName("Blue");
… But I find this script very slow!
Is there a different writing to make it faster!
Thanks again!
(^/)
Copy link to clipboard
Copied
This is probably quicker (it's certainly quicker to type):
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.fillColor = 'Black';
app.changeGrepPreferences.fillColor = 'Blue';
app.documents[0].stories.everyItem().tables.everyItem().changeGrep();
Peter
Copy link to clipboard
Copied
Hi Peter,
Totally right! [ ] … if I wanted to change all "Red" text in "Blue"! …
But it's more complex: To simplify, I've not included a header row, but here I want to change only the "even" rows.
That's why I used 3 "for" loops [see the second one especially]! … surely the reason of the script slowness.
(^/)
Copy link to clipboard
Copied
Hi Obi-wan,
what does slow mean? How many seconds for how many tables with how many rows?
There is an faster approach, but you'll need in advance to know the maximum number of rows of all the tables of your document.
Getting that value needs some time for calculation. That would be the "overhead" so to speak. But from then on its much faster than looping every row of every table.
On an old MacBook Pro from late 2008 with only 4 GB of RAM and InDesign CS6 with about 1200 rows in total—maximum rows of one table was: 1000—the script below took about 34 seconds to finish:
var startTime = Date.now();
var rowsMax = 0;
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
app.doScript
(
colorTextOfEverySecondRow,
ScriptLanguage.JAVASCRIPT,
[],
UndoModes.ENTIRE_SCRIPT,
"Color text of every second row in document"
);
var endTime = Date.now();
var elapsedTimeInSeconds = ((endTime - startTime)/1000);
$.writeln(elapsedTimeInSeconds+"\t"+"Sec."+" with rowsMax: "+rowsMax);
function colorTextOfEverySecondRow()
{
var doc = app.documents[0];
var color = doc.colors.itemByName("Blue");
// Some preprocessing of the maximum number of rows:
var tables = doc.stories.everyItem().tables.everyItem().getElements();
var tablesLength = tables.length;
for(var n=0;n<tablesLength;n++)
{
var currentRowsLength = tables
.rows.length; if(currentRowsLength > rowsMax){rowsMax = currentRowsLength};
};
// And here a demonstration of the power of everyItem()
tables = doc.stories.everyItem().tables.everyItem();
for(var n=1;n<rowsMax;n=n+2)
{
tables.rows
.cells.everyItem().texts.everyItem().fillColor = color; };
return rowsMax;
};
Note: No header or footer rows were defined in the tables.
I tested your code with my sample.
It took about 192 seconds to finish.
See also Marc Autret on everyItem() :
Indiscripts :: On ‘everyItem()’ – Part 1
Indiscripts :: On ‘everyItem()’ – Part 2
Regards,
Uwe
Copy link to clipboard
Copied
Uwe,
To speed things up with everyItem() you'd do it on the rows as well -- something like this:
tables = doc.stories.everyItem().tables.everyItem();
for (i = tables.length-1; i >= 0; i--) {
rows = tables.rows.everyItem().getElements();
for (j = rows.length-1; j >= 0; j--) {
cells = rows
.cells.everyItem().getElements(); for (k = cells.length-1; k >= 0; k--) {
// do something
}
}
}
P.
Copy link to clipboard
Copied
Hi Peter,
yes, that would benefit Obi Wan's version of the script.
In my script I'd like to access the rows by index for every table in the document directly.
And by index I mean the individual index of the row in context with the individual table.
If I'd used getElements() I needed to loop every table individually.
And since every second row of a single table should be accessed starting with the second row of every table—we cannot know if a table has an even or an odd number of rows—I cannot loop through an array like that:
doc.stories.everyItem().tables.everyItem().rows.everyItem().getElements();
Instead I do it with:
doc.stories.everyItem().tables.everyItem().rows[ n ]
Example:
Have a document with three tables. One with 2 rows, one wih 7 rows and one with 5 rows.
I want to access the seventh row of all tables, I could do it like that:
doc.stories.everyItem().tables.everyItem().rows[6]
Regardless if there are any tables in the document with less than 7 rows.
Regards,
Uwe
Copy link to clipboard
Copied
Yes, ok. Anyway, the message is to use everyItem().getElements() wherever you can, especially in tables.
P.
Copy link to clipboard
Copied
Hi Obi,
May the below code also useful for you,
myDoc = app.activeDocument, | ||
myTables = myDoc.stories.everyItem().tables.everyItem().getElements(); | ||
for ( var t = 0 ; t < myTables.length; t++ ) | ||
{ | ||
var myRows = myTables | ||
for ( var r = 1 ; r < myRows.length; r = r +2 ) | ||
{ | ||
var myCells = myRows | ||
for ( var c = 0 ; c < myCells.length; c++ ) | ||
{ | ||
myCells | ||
} | ||
} | ||
} |
Thanks in Advance
Siraj
Copy link to clipboard
Copied
Hi Uwe,
Laubender napisał(-a):
...And since every second row of a single table should be accessed starting with the second row of every table—we cannot know if a table has an even or an odd number of rows—I cannot loop through an array like that:
- doc.stories.everyItem().tables.everyItem().rows.everyItem().getElements();
....
I think you can ==> checking row's index which is related to a parent (table), so
mDoc = app.activeDocument,
mRows = mDoc.stories.everyItem().tables.everyItem().rows.everyItem().getElements(),
cRow, mColor = mDoc.swatches.item("Blue");
while (cRow = mRows.pop())
if(cRow.index%2)
cRow.cells.everyItem().texts.everyItem().fillColor = mColor;
Jarek
Copy link to clipboard
Copied
Hi Jarek,
very good.
Just tested your idea on my sample document.
Surprisingly it was a bit slower than my script, but not much:
41 vs 37 seconds
Did more than one test with both ideas.
The values are on average.
Thanks,
Uwe
Copy link to clipboard
Copied
> while (cRow = mRows.pop())
This is one of the most expensive ways to go through an array. Really.
Copy link to clipboard
Copied
Hi all,
I made some test based on my code and Uwe's timer ==> changing loops inside function.
A few tables in 1 story - total 2k rows, max 1500).
4 tests (repeated few times to average) where loops are alike:
1. while(cRow = mRows.pop()) ==> time ~8,3 s
2. while(len--) // ==> time ~8,25 s
3. for (var k = 0; k < len; k++) ==> time ~43 s
4. for (var k = len-1; k >=0; k--) ==> time ~8,3 s
It looks like - in this case - most important is backward or forward direction of changes
Jarek
Copy link to clipboard
Copied
Hi Jarek,
interesting…
I did my sample document with several stories and used a for loop with my first tests on your idea.
Don't know if you did that, but I think it's important to restart InDesign before starting a new test.
Unfortunately I did not do that with my first tests.
I tested again on CS6 v8.1.0 on Mac OSX 10.6.8 with 4GB RAM.
So here are some new figures:
1. Direct accessing the rows with my script in answer # 4:
~31.0 s
2. Your index method and a for-loop forward through the rows array gathered by getElements() :
~29.3 s
3. Your index method and a for-loop backward through the rows array gathered by getElements() :
~27.8 s
It's not as dramatic as your figures are showing, but the main difference in my tests is that I used several stories and not just one. We should exchange test documents to get better insight.
And I should repeat my tests on a machine with more RAM.
Thanks,
Uwe
Copy link to clipboard
Copied
Forgot to mension the new figure with running Obi-Wan's script after restarting InDesign:
~182.8 s
Speaking of Obi-Wan:
How are your speed results, Obi-Wan?
Are you still following?
Regards,
Uwe
Copy link to clipboard
Copied
Aha! Of course I'm here and read all your comments!
Too glad to see your answers and learn such a lot!
As you see, i'm able to write scripts that work sometimes but the more interesting for me is to know and understand (so learn great) how you think and write and why my script time is x 5!
i'll test all your ways this afternoon!
(^/)

