D.S..
Explorer
D.S..
Explorer
Activity
‎Feb 29, 2024
04:11 PM
1 Upvote
Okay, I've brought a bigger gun this time—my `getItems` function—and sorry it's a long script—it has evolved over many years. I've just modified to also collect Layers so hopefully I didn't introduce any bugs.
I've configured the script below to apply the titleCase to every unlocked, visible page item and layer in the document. I'm interested how it goes with your complex-document, so please let me know. (I'd also like to know if it still crashed even if you set getLockedItems and getHiddenItems both to true.)
- Mark
/**
* Page item and layer names to title case.
* NOTE: sometimes you must refresh the layers panel to see the changes.
* @author m1b
* @discussion https://community.adobe.com/t5/illustrator-discussions/can-someone-share-script-that-changes-figure-name-inside-layer-from-quot-all-caps-quot-to-quot-small/m-p/14453811
*/
(function () {
var counter = 0;
// I'm using my `getItems` function just as
// an engine for applying the titleCase to
// every visible, unlocked page item and layer
getItems({
from: app.activeDocument,
getLayers: true,
getGroupItems: true,
getLockedItems: false,
getHiddenItems: false,
filter: function (item) {
if (item.name) {
item.name = titleCase(item.name);
counter++;
}
return false;
},
});
app.redraw();
alert('Examined ' + counter + ' items.');
})();
/**
* Formats string as title case.
* @Param {String} str
* @Returns {String}
*/
function titleCase(str) {
return str
.toLowerCase()
.replace(/\b\w/g, function (ch) {
return ch.toUpperCase();
});
};
/** ------------------------------------------------------------------- *
* GET ITEMS *
* -------------------------------------------------------------------- *
* @author m1b *
* @version 2024-03-01 *
* -------------------------------------------------------------------- *
* Collects page items from a `from` source, eg. a Document, Layer, *
* GroupItem, or Array. Will look inside group items up to `maxDepth`. *
* Search can be filtered using `filter` function. Note that the *
* filter function is evaluated last in the filtering process. *
* -------------------------------------------------------------------- *
* Example 1. Get all items in document: *
* *
* var myItems = getItems({ from: app.activeDocument }); *
* *
* -------------------------------------------------------------------- *
* Example 2. Get all selected items except groups: *
* *
* var myItems = getItems({ *
* from: app.activeDocument.selection, *
* getGroupItems: false, *
* }); *
* *
* -------------------------------------------------------------------- *
* Example 3. Using `filter` function to choose item type: *
* *
* var myItems = getItems({ *
* from: app.activeDocument, *
* filter: function (item) { *
* return ( *
* 'PathItem' === item.typename *
* || 'CompoundPathItem' === item.typename *
* ); *
* } *
* }); *
* *
* -------------------------------------------------------------------- *
* Example 4. Using `filter` function: *
* *
* var myItems = getItems({ *
* from: app.activeDocument, *
* filter: onlyPngLinks *
* }); *
* *
* function onlyPngLinks(item, depth) { *
* return ( *
* 'PlacedItem' === item.typename *
* && '.png' === item.file.name.slice(-4).toLowerCase() *
* ); *
* }; *
* *
* -------------------------------------------------------------------- *
* Example 4. Using the `filter` function for custom collecting: *
* *
* This example bypasses the normal returned array and instead *
* captures items in an "external" array `itemsByDepth`. *
* *
* var itemsByDepth = []; *
* *
* function getItemsByDepth(item, depth) { *
* if (undefined == itemsByDepth[depth]) *
* itemsByDepth[depth] = []; *
* itemsByDepth[depth].push(item); *
* }; *
* *
* getItems({ *
* from: app.activeDocument, *
* filter: getItemsByDepth *
* }); *
* *
* -------------------------------------------------------------------- *
* @Param {Object} options - parameters
* @Param {PageItem|Array<PageItem>|Document|Layer} options.from - the thing(s) to look in, eg. a selection.
* @Param {Function} [options.filter] - function that, given a found item, must return true (default: no filtering).
* @Param {Boolean} [options.getPageItems] - whether to include page items in returned items (default: true).
* @Param {Boolean} [options.getGroupItems] - whether to include GroupItems in returned items (default: true).
* @Param {Boolean} [options.getLayers] - whether to include Layers in returned items (default: false).
* @Param {Boolean} [options.getHiddenItems] - whether to include hidden items in returned items (default: true).
* @Param {Boolean} [options.getLockedItems] - whether to include locked items in returned items (default: true).
* @Param {Boolean} [options.getGuideItems] - whether to include guide items in returned items (default: false).
* @Param {Number} [options.maxDepth] - deepest folder level (recursion depth limit) (default: 99).
* @Param {Boolean} [options.returnFirstMatch] - whether to return only the first found item (default: false).
* @Param {Number} [depth] - the current depth (private).
* @Returns {Array|PageItem} - all the found items in a flat array, or the first found item if `returnFirstMatch`.
*/
function getItems(options, depth) {
// defaults
options = options || {};
var found = [],
depth = depth || 0,
items = options.from;
if (!options.initialized)
// once-off initialization
if (!initialize())
return [];
itemsLoop:
for (var i = 0, item, len = items.length; i < len; i++) {
item = items[i];
if (
false === excludeFilter(item)
&& true === includeFilter(item)
) {
// item found!
found.push(item);
if (options.returnFirstMatch)
break itemsLoop;
}
if (
'GroupItem' !== item.constructor.name
&& 'Layer' !== item.typename
)
// only items with children from here
continue itemsLoop;
if (
excludeHidden(item)
|| excludeLocked(item)
)
// don't look into excluded containers
continue itemsLoop;
if (depth >= options.maxDepth)
// don't go deeper
continue itemsLoop;
// set up for the next depth
options.from = item.pageItems;
// look inside
found = found.concat(getItems(options, depth + 1));
}
// this level done
if (true == options.returnFirstMatch)
return found[0];
else
return found;
/**
* Returns true when the item should be not be found.
* @Param {PageItem|Layer} item
* @Returns {Boolean}
*/
function excludeFilter(item) {
return (
isAlreadyFound(item)
// is hidden
|| excludeHidden(item)
// is locked
|| excludeLocked(item)
// is guide
|| (
false === options.getGuideItems
&& true === item.guides
)
// is layer
|| (
false === options.getLayers
&& 'Layer' === item.typename
)
// is group item
|| (
false === options.getGroupItems
&& 'GroupItem' === item.typename
)
// is page item
|| (
false === options.getPageItems
&& 'GroupItem' !== item.typename
&& undefined != item.uuid
)
);
};
/**
* Returns true when the item should be included.
* @Param {PageItem|Layer} item
* @Returns {Boolean}
*/
function includeFilter(item) {
return (
undefined == options.filter
|| options.filter(item, depth)
);
};
/**
* Returns true when the item should
* be excluded because it is hidden.
* @Param {PageItem|Layer} item
* @Returns {Boolean}
*/
function excludeHidden(item) {
return (
false === options.getHiddenItems
&& (
true === item.hidden
|| false === item.visible
)
);
};
/**
* Returns true when the item should
* be excluded because it is locked.
* @Param {PageItem|Layer} item
* @Returns {Boolean}
*/
function excludeLocked(item) {
return (
false === options.getLockedItems
&& true === item.locked
);
};
/**
* Returns true if item was already
* found, and marks item as found,
* to avoid finding same item twice.
* @Param {PageItem|Layer} item
* @Returns {Boolean}
*/
function isAlreadyFound(item) {
var uuid = item.hasOwnProperty('uuid')
? item.uuid
: item.typename + item.zOrderPosition,
isFound = !!options.isFound[uuid];
options.isFound[uuid] = true;
return isFound;
}
/**
* Returns the initialised `options` object.
* @Returns {Object}
*/
function initialize() {
// make a new object, so we don't pollute the original
options = {
initialized: true,
depth: 0,
isFound: {},
filter: options.filter,
getPageItems: false !== options.getPageItems,
getGroupItems: false !== options.getGroupItems,
getLayers: true === options.getLayers,
getHiddenItems: false !== options.getHiddenItems,
getLockedItems: false !== options.getLockedItems,
getGuideItems: true === options.getGuideItems,
maxDepth: options.maxDepth,
returnFirstMatch: options.returnFirstMatch,
};
if (
undefined == options.maxDepth
|| !options.maxDepth instanceof Number
)
options.maxDepth = 99;
// items is a single layer
if ('Layer' === items.typename)
items = [items];
// items is a document
else if ('Document' === items.constructor.name) {
var layers = items.layers;
items = [];
for (var i = 0; i < layers.length; i++)
items.push(layers[i]);
}
else if ('Array' !== items.constructor.name)
items = [items];
return items.length > 0;
};
};
... View more
‎Feb 28, 2024
03:22 AM
3 Upvotes
@CarlosCanto 's script here should do what you need:
https://community.adobe.com/t5/illustrator-discussions/how-to-divide-all-textframes-in-one-character-per-textframe/m-p/10699910#M150144
... View more
‎Apr 20, 2022
02:19 AM
1 Upvote
It does the job perfecrly! Thank you again. 🙂
... View more
‎Apr 18, 2022
12:51 AM
Deffinetly helpfull!
... View more
‎Apr 15, 2022
04:16 AM
1 Upvote
Pf you blew my mind. It works perfectly. I am amazed by your skills honestly! Thank you for your time. I really apreciate it!
... View more
‎Apr 15, 2022
04:00 AM
1 Upvote
Amazing! It does the job perfectly! 🙂
... View more
‎Apr 15, 2022
02:34 AM
1 Upvote
It does the job perfectly! Thank you so much! 🙂
... View more
‎Apr 15, 2022
02:25 AM
1 Upvote
Exactly what I needed. I am aware of the rearange you mentioned. Thank you! 🙂
... View more
‎Apr 14, 2022
08:26 AM
Yes, that's possible, of course.
See: Connector 2
... View more