Skip to main content
Inspiring
August 12, 2022
Answered

Sort sublayers numerically in ai

  • August 12, 2022
  • 4 replies
  • 1116 views

Good Morning Vietnam (and to everyone else)

 

Is there a way to sort sublayers ? If its a script i need , anyone know if there is one online available? Many thanks for any help.

This topic has been closed for replies.
Correct answer Sergey Osokin

Fixed

var isLowerFirst = false; // Set it to false if you want to place the layers with the first uppercase letter above
var isReverse = false;  // Set it to false if you want to sort names in reverse order

// Convert ILST collection into standard Array so we can use Array methods
function get(type, parent) {
  if (arguments.length == 1 || !parent) parent = app.activeDocument;
  var result = [];
  if (!parent[type]) return result;
  for (var i = 0; i < parent[type].length; i++) result.push(parent[type][i]);
  return result;
}

// Polyfill for Array.forEach
Array.prototype.forEach = function (callback) {
  for (var i = 0; i < this.length; i++) callback(this[i], i, this);
};

// Check string
function isEmpty(s) {
  return s.replace(/\s/g, '').length == 0;
}

// Get pageItem name
function getName(e) {
  if (e.typename === "TextFrame" && isEmpty(e.name) && !isEmpty(e.contents)) {
    return e.contents;
  } else if (e.typename === "SymbolItem" && isEmpty(e.name)) {
    return e.symbol.name;
  } else {
    return e.name;
  }
}

function sortLayerItems(parent, isReverse) {
  if (arguments.length == 1 || !isReverse) isReverse = false;

  function isUpperCase(text) {
    return /[A-Z]/.test(text.charAt(0))
  }

  function isLowerCase(text) {
    return /[a-z]/.test(text.charAt(0))
  }

  function hasMixedCase(a, b) {
    if (a.charAt(0).toLowerCase() !== b.charAt(0).toLowerCase()) return false;
    return isUpperCase(a) && isLowerCase(b) ? true : isLowerCase(a) && isUpperCase(b);
  }

  function handleMixedCase(a, b) {
    var result = a === b ? 0 : isUpperCase(a) ? 1 : -1;
    return isLowerFirst ? result : result * -1;
  }

  get("pageItems", parent)
    .sort(function (a, b) {
      var aName = getName(a);
      var bName = getName(b);
      if (!isNaN(aName) && !isNaN(bName)) {
        return 1 * aName - 1 * bName;
      } else {
        return hasMixedCase(aName, bName) ?
          handleMixedCase(aName, bName) :
          aName.toLowerCase().localeCompare(bName.toLowerCase())
      }
    })
    .forEach(function (e) {
      e.zOrder(isReverse ? ZOrderMethod.BRINGTOFRONT : ZOrderMethod.SENDTOBACK);
    });
}

sortLayerItems(activeDocument.activeLayer, isReverse);

4 replies

Sergey Osokin
Inspiring
August 12, 2022

I used Tom Scharstein's (@Inventsable) layer sorting code and made objects in the active layer sort with textFrame content and custom names. The default names (not really real names) <rectangle>, <group> are not sorted

 

var isLowerFirst = false; // Set it to false if you want to place the layers with the first uppercase letter above
var isReverse = false;  // Set it to false if you want to sort names in reverse order

// Convert ILST collection into standard Array so we can use Array methods
function get(type, parent) {
  if (arguments.length == 1 || !parent) parent = app.activeDocument;
  var result = [];
  if (!parent[type]) return result;
  for (var i = 0; i < parent[type].length; i++) result.push(parent[type][i]);
  return result;
}

// Polyfill for Array.forEach
Array.prototype.forEach = function (callback) {
  for (var i = 0; i < this.length; i++) callback(this[i], i, this);
};

// Check string
function isEmpty(s) {
  return s.replace(/\s/g, '').length == 0;
}

// Get pageItem name
function getName(e) {
  if (e.typename === "TextFrame" && isEmpty(e.name) && !isEmpty(e.contents)) {
    return e.contents;
  } else if (e.typename === "SymbolItem" && isEmpty(e.name)) {
    return e.symbol.name;
  } else {
    return e.name;
  }
}

function sortLayerItems(parent, isReverse) {
  if (arguments.length == 1 || !isReverse) isReverse = false;

  function isUpperCase(text) {
    return /[A-Z]/.test(text.charAt(0))
  }

  function isLowerCase(text) {
    return /[a-z]/.test(text.charAt(0))
  }

  function hasMixedCase(a, b) {
    if (a.charAt(0).toLowerCase() !== b.charAt(0).toLowerCase()) return false;
    return isUpperCase(a) && isLowerCase(b) ? true : isLowerCase(a) && isUpperCase(b);
  }

  function handleMixedCase(a, b) {
    var result = a === b ? 0 : isUpperCase(a) ? 1 : -1;
    return isLowerFirst ? result : result * -1;
  }

  get("pageItems", parent)
    .sort(function (a, b) {
      var aName = getName(a);
      var bName = getName(b);
      return hasMixedCase(aName, bName) ?
        handleMixedCase(aName, bName) :
        aName.toLowerCase().localeCompare(bName.toLowerCase())
    })
    .forEach(function (e) {
      e.zOrder(isReverse ? ZOrderMethod.BRINGTOFRONT : ZOrderMethod.SENDTOBACK);
    });
}

sortLayerItems(activeDocument.activeLayer, isReverse);

 

Inspiring
August 12, 2022

This is amazing Sergey - works perfectly. A huge thank you !!!! HAve a great day ahead. You are my hero today. 

Sergey Osokin
Inspiring
August 12, 2022

I wanted to clarify. "Sublayers" - do you mean objects inside layer? Because objects and sublayers are different terms. Do you want to sort objects by name inside active layer?

Inspiring
August 12, 2022

yes , sorry my wrong lingo - items inside a layer

Charu Rajput
Community Expert
Community Expert
August 12, 2022
Inspiring
August 12, 2022

Many thanks

Charu Rajput
Community Expert
Community Expert
August 12, 2022

Hi,

By looking at your image, it does not seems like these are sublayers. I am not sure on what conditions do you want to sort. A question for you :  Do items inside the Layer 1 has name with numbers?

 

If you are looking to sort layers, may be following link will be helpful. Following is using alphabets to sort.

https://gist.github.com/KennyRedman/b8582079dabc1be17b05

 

Best regards
Inspiring
August 12, 2022

oh yes, i guess sublayers are different. these are numbers / fonts i have on my designs. i guess i can put them into differnt layers and sort the layers . Thanks a lot for your time and have a good day ahead