Copy link to clipboard
Copied
Hello!
I'm trying to organize my layers in Illustrator aphabetically, and I can't find a script for it. I've found several potential scripts here but I couldn't get them to work, and since my coding knowledge is extremely basic I can't really make one on my own. Is there a script I can use to sort layers?
I found a script to sort layers alphabetically https://gist.github.com/KennyRedman/b8582079dabc1be17b05
Copy link to clipboard
Copied
please post a link to the potential scripts and let us know why they're not working for you, and/or post the error codes you're getting.
Copy link to clipboard
Copied
For the simplest case, based on Unicode order (9 before A, Z before a and 10 before 2):
function alphabetise(a) {
for (var i = 1; i < a.length; i++) {
for (var j = i; j > 0; j--) {
if (a[j].name < a[j-1].name) {
a[j].moveBefore(a[j-1]);
}
}
}
}
alphabetise(app.activeDocument.layers);
Copy link to clipboard
Copied
I found a script to sort layers alphabetically https://gist.github.com/KennyRedman/b8582079dabc1be17b05
Copy link to clipboard
Copied
KennyRedman's script will prodoce the same result as the snippet I posted. It's based on a Unicode alphabetical comparison using the > operator. As I said, you'll get "Zoo" before "aardvark".
Copy link to clipboard
Copied
You can use String.prototype.localeCompare while sorting to get the correct results:
var yourLayerNameArray = ["tiny", "Zoo", "aardvark"];
yourLayerNameArray.sort(function (a, b) {
return a.localeCompare(b);
});
console.log(yourLayerNameArray);
// Returns as ["aardvark", "tiny", "Zoo"]
Copy link to clipboard
Copied
It didn't work for me. But I can have the names converted to lower case when sorting. If the author has enough to sort alphabetically case-insensitive.
yourLayerNameArray.sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
Or in @femkeblanco version
function alphabetise(a) {
for (var i = 1; i < a.length; i++) {
for (var j = i; j > 0; j--) {
if (a[j].name.toLowerCase() < a[j-1].name.toLowerCase()) {
a[j].moveBefore(a[j-1]);
}
}
}
}
Or modify the algorithms so that first there are lowercase or uppercase letters "a_name", "A_name", "b_name", "B_name"
Copy link to clipboard
Copied
Hmmm, String.localeCompare gives different results when run in Node compared to ESTK. You're right about it, though. Here's a recursive solution that should handle any depth:
Copy link to clipboard
Copied
I was pretty curious about this so I ran some tests. From what I can tell, String.localeCompare in ESTK may be custom code, a very simplified polyfill, or a very old version that existed before the options parameters. It doesn't accept any optional parameters and definitely sorts differently than run in Node / V8 or modern browsers. The method should have explicit case-insensitive options going back to Chromium V1 and original ECMAScript, like so:
var test = ["zoo", "Zoo", "aardvark", "tiny", "Aardvark"];
test.sort(function (a, b) {
return a.localeCompare(b, 'en', {
sensitivity: "base"
});
});
alert(test) // Incorrectly returns ["Aardvark", "Zoo", "aardvark", "tiny", "zoo"] in ESTK
This runs much differently (and correctly) in Node:
let test = ["zoo", "Zoo", "aardvark", "tiny", "Aardvark"];
test.sort((a, b) => a.localeCompare(b, "en", { "sensitivity": "base" }));
console.log(test); // ["aardvark", "Aardvark", "tiny", "zoo", "Zoo"]
When you run this inside ESTK you get false results, it's still case sensitive. If you use explict case flags which should mean certain cases are valued higher than the other or tell it to ignore all punctuation (similar to sensitivity base but base is more for accent characters in non-English languages), you still get the same results:
var test = ["zoo", "Zoo", "aardvark", "tiny", "Aardvark"];
test.sort(function (a, b) {
return a.localeCompare(b, "en", {
ignorePunctuation: true
});
});
alert(test) // ["Aardvark", "Zoo", "aardvark", "tiny", "zoo"]
test.sort(function (a, b) {
return a.localeCompare(b, "en", {
caseFirst: "upper"
});
});
alert(test) // ["Aardvark", "Zoo", "aardvark", "tiny", "zoo"]
test.sort(function (a, b) {
return a.localeCompare(b, "en", {
caseFirst: "lower"
});
});
alert(test) // ["Aardvark", "Zoo", "aardvark", "tiny", "zoo"]
// Always same result, the options parameter isn't implemented
I tried rearranging the arguments, thinking that maybe locale and options are flipped or locale isn't supported, etc., but I never produce a different result from the original ESTK sort. So unfortunately this means that we would have to call toLowerCase() like Sergey says, but that really isn't an ideal solution if you specifically want to prefer uppercase appears before lowercase or vice versa, you'd have to write an additional comparator in the sort.
Just another one of those weird "well this doesn't work like I expected" Adobe scripting things.