Copy link to clipboard
Copied
I am populating 2 lists to form a numbered list. For example the following text items are on the artboard.
Apples
Bananas
Oranges
Apples
Bananas
Oranges
These will all be pushed to a single list called rePop and then sorted like this:
Apples
Apples
Bananas
Bananas
Oranges
Oranges
Next the code will split the text frames into 2 list like so
listOne : listTwo :
Apples Apples
Bananas Bananas
Oranges Oranges
Now I want to compare and number the 2 lists so the final text frames would look like this
(1) Apples
(2) Bananas
(3) Oranges
(1) Apples
(2) Bananas
(3) Oranges
Here is my current code....any help would be appreciated!
#target illustrator
var rePop = [];
var listOne = [];
var listTwo = [];
var oddCount = 0;
var evenCount = 1;
for (var i = 0; i < allText.length; i++) {
rePop.push(allText.contents);
}
rePop.sort();
for (var i = 0; i < rePop.length; i++) {
listOne.push(rePop[(oddCount)]);
listTwo.push(rePop[(evenCount)]);
oddCount += 2;
evenCount += 2;
}
var z = 0;
for (var i = 0; i < listOne.length; i++) {
var checkContents = listOne;
alert(listOne + " " + listTwo
); if (listOne == listTwo
) { var changeText = "(" + (i + 1) + ") " + checkContents;
listOne = listOne.replace(checkContents, changeText);
z++;
} else {
alert("Not a match");
}
}
I know, this is not really the best way, but quick and dirty:
...// required: only matching pairs of textFrames with same contents
// eg 111, 111, apple, apple, Banana, Banana // no other (single) textFrames allowed
// result (1) 111, (1) 111, (2) apple, (2) apple, (3) Banana, (3) Banana
var aDoc = app.activeDocument;
var allText = aDoc.textFrames;
var rePop = [];
for (var i = 0; i < allText.length; i++) {
allText.name = allText.contents;
rePop.push(allText.contents);
}
rePop.sort();
var listOne = [];
/
Copy link to clipboard
Copied
Not sure i fully understand what the goal is, or what problem you're having. But I can say that you never actually take anything from the array and put it into a text frame. You only split contents into arrays and sort and then replace contents of the arrays.
If you can give more information about what you're trying to do, we can give better help. For now i made a brief assumption.
Assuming you want a single text frame to hold all of the resulting items of each array, preceded by a number, add this to the end of your code:
//choose one of the following:
//get an existing text frame you want to add this text to
var destTextFrame = app.activeDocument.textFrames["My Text Frame"];
//create a text frame
var destTextFrame = app.activeDocument.textFrames.add();
destTextFrame.name = "My Text Frame";
//now update the contents
//if the arrays are always the same as you showed in your example,
//you could merge these into a single loop. but i'll assume that's not the case
//and we'll use two separate loops
for(var x=0;x<listOne.length;x++)
{
destTextFrame.contents += listOne
}
for(var x=0;x<listTwo.length;x++)
{
destTextFrame.contents += listTwo
}
Copy link to clipboard
Copied
So the goal is to have a numbered list to reference items that are spaced out on a large artboard.
They are all individual textFrame items. My issue is I don't know how to get the formatting I want of (#) inserted back into the textFrame when it finds an array item. The list will ALWAYS match. The reason for splitting and sorting them is to find out how many items there are so that a number can be assigned. Here are 2 screen shots of a file before the script would be run and my goal for after the script
Hope this helps clarify some. Thank you for your reply!
Copy link to clipboard
Copied
So at the beginning of your script, you're saving the contents of the text frames to variables using the 'contents' property. This property is gettable and settable.
You'll have to figure out how to get the correct text frame, but once you have it, you can just do something like this:
var currentSequenceNumber = 1;
var myTextFrame = app.activeDocument.textFrames[0]; //this just gets the first text frame. you'll have this variable set equal to the desired text frame
myTextFrame.contents = "(" + currentSequenceNumber + ") " + myTextFrame.contents;
The key is to use the assignment operator to set a new value to the contents property of the desired text frame.
For kicks.. here's a regex implementation as well, though whether it's any 'better', i don't know.
var pattern = /^/;
var replacement = " (" + currentSequenceNumber + ")
myTextFrame.contents = myTextFrame.contents.replace(pattern,replacement);
Copy link to clipboard
Copied
Ah, i think i've got it. When you populate your arrays, push the array object itself instead of the text. that way you can update the contents of a given array without having to find a text frame that matches the text of the current array index. I suppose you'll need to re-work your sorting though.. perhaps even write your own sort function.. but this way you could just do:
for(var x=0;x<listOne.length;x++)
{
listOne
}
Copy link to clipboard
Copied
williamadowling schrieb
Ah, i think i've got it …
Sorry, but I think your code doesn't work. Furthermore I think you need a more circuitous solution - like "a shoot from behind through the chest to the eye". Or the rocky way: you sort the text layers hierarchy in the same order as your array has.
Copy link to clipboard
Copied
What doesn't work? It should certainly work to rename the text frames in a sorted array. I grant you i didn't handle any of the sorting, but the question was how to update the contents of a given text frame. my snippet should certainly add "([index]) " to the beginning of each text frame in the array..
Copy link to clipboard
Copied
Can you show me the code completely which works for you, please?
Copy link to clipboard
Copied
Again, this does not include the sorting of the array or comparing contents of arrays, but as i said the question was how to update the contents of the text frames. Here's a test snippet that accurately updates the contents of each text frame in an array (for this test it's just all of the text frames in the document). One update i did make while testing is putting [index] + 1 into parentheses to evaluate the addition before concatenating. (otherwise you end up with:
(01) Apples
instead of
(1) Apples
function test()
{
var docRef = app.activeDocument;
var frames = docRef.textFrames;
if(frames.length>0)
{
for(var x=0;x<frames.length;x++)
{
var thisFrame = frames
thisFrame.contents = "(" + (x+1) + ") " + thisFrame.contents;
}
}
else
{
alert('No text frames available!');
}
}
test();
Copy link to clipboard
Copied
Thx for your answer.
It seems you missunderstood the question of the TE.
You have a file eg like this:
Your code does the following changes:
Instead of this result (this is what I did understand)
Hope the TO answeres in time
Copy link to clipboard
Copied
You are correct. the code i posted would have to be duplicated for the other array. There are two parallel arrays that contain the text frames. my code only handles one of them and, as previously stated, assumes the sorting has already been completed.
So you would run my loop twice (or better yet, change one text frame from each array within each execution of the loop, like so):
function test()
{
var docRef = app.activeDocument;
var listOne = []; //sorted array of text frames;
var listTwo = []; //sorted array of text frames;
if(listOne.length>0)
{
var length = listOne.length;
for(var x=0;x<length;x++)
{
listOne
listTwo
}
}
else
{
alert('No text frames available!');
}
}
test();
My previous responses addressed the fact that the sorting would need to be revisited because you cannot sort an array of text frame objects with a simple array.sort() like wolfEdition has in his/her original snippet.
The question i was attempting to answer is in the title of the post, and was clarified here in the initial response to my first answer:
My issue is I don't know how to get the formatting I want of (#) inserted back into the textFrame when it finds an array item.
So my answer became more long winded than it needed to, but all i was trying to convey is that in order to update the contents of the text frame, OP simply needs to re-assign the contents of the given text frame like so:
myTextFrame.contents = "(" + (index + 1) + ") " + myTextFrame.contents
The way i understand it, this is the question at hand. OP used the string.replace() method but never assigned the return value to the text frame at hand, it was simply updated in the array which is not associated with the text frame.
Copy link to clipboard
Copied
I know, this is not really the best way, but quick and dirty:
// required: only matching pairs of textFrames with same contents
// eg 111, 111, apple, apple, Banana, Banana // no other (single) textFrames allowed
// result (1) 111, (1) 111, (2) apple, (2) apple, (3) Banana, (3) Banana
var aDoc = app.activeDocument;
var allText = aDoc.textFrames;
var rePop = [];
for (var i = 0; i < allText.length; i++) {
allText.name = allText.contents;
rePop.push(allText.contents);
}
rePop.sort();
var listOne = [];
//var listTwo = []; // only need if you want to create a better error handling as in this snippet
for (var i = 0; i < rePop.length; i+=2) {
listOne.push ( rePop );
//listTwo.push ( rePop[(i+1)] );
}
if (rePop.length % 2 == 0) {
for (var i = 0; i < listOne.length; i++) {
try {
changeTextframes ( listOne );
changeTextframes ( listOne );
} catch (e) { alert ("missing pairs"); }
}
} else { alert ("different lists.length") };
function changeTextframes ( x ) {
var tf = aDoc.textFrames.getByName ( x );
tf.contents = "(" + (i+1) + ") " + x;
tf.name = tf.contents;
}
wolfeEdition​ and williamadowling​
Have fun
Copy link to clipboard
Copied
Thank you both for your help! I'll take the quick and dirty code anytime!