• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Script to remove the word 'copy' from layer text

Explorer ,
Dec 30, 2019 Dec 30, 2019

Copy link to clipboard

Copied

I use very specific titles for my illustrator files and do a lot of duplicating layers, which in many cases creates the word 'copy' after the layer. 

For example:

Layer 1

 - Sublayer 1

 - Sublayer 2

Layer 1 copy

 - Sublayer 1 copy

 - Sublayer 2 copy

 

It's easy enough to remove from a few layers, but sometime's I need to remove it from hundereds of layers. Is there either: an option to turn that off, or a script that either removes the word copy or allows me to rename layers easily?

I've looked around for quite a bit and can't seem to find anything related.

I use a script to rename individual objects, but can't seem to make it work for layers.

TOPICS
Scripting , Tools , Type

Views

2.0K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

LEGEND , Dec 31, 2019 Dec 31, 2019

Edited:
This function will update main and sublayer names. Still working to incorporate possible "copy 2" names, etc.

 

 

 

updateLayerNames();

function updateLayerNames() {
  var aDoc = app.activeDocument;
  var i;
  var ii;
  for (i = 0; i < aDoc.layers.length; i++) {
    aDoc.layers[i].name = aDoc.layers[i].name.replace(" copy", "");
    for (ii = 0; ii < aDoc.layers[i].layers.length; ii++) {
      aDoc.layers[i].layers[ii].name = aDoc.layers[i].layers[ii].name.replace(" copy", "");
    }
  
...

Votes

Translate

Translate
Adobe
LEGEND ,
Dec 31, 2019 Dec 31, 2019

Copy link to clipboard

Copied

Edited:
This function will update main and sublayer names. Still working to incorporate possible "copy 2" names, etc.

 

 

 

updateLayerNames();

function updateLayerNames() {
  var aDoc = app.activeDocument;
  var i;
  var ii;
  for (i = 0; i < aDoc.layers.length; i++) {
    aDoc.layers[i].name = aDoc.layers[i].name.replace(" copy", "");
    for (ii = 0; ii < aDoc.layers[i].layers.length; ii++) {
      aDoc.layers[i].layers[ii].name = aDoc.layers[i].layers[ii].name.replace(" copy", "");
    }
  }
}

 

 

 

 

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 31, 2019 Dec 31, 2019

Copy link to clipboard

Copied

This is awesome, thank you!

Getting 'copy' out of the sublayers would be incredible, it's such a time consuming process by hand.

 

If removing 'copy #' is too much, it's not a big deal.  I use an action to duplicate layers, so I can easily add the 'remove copy' script as part of the action, so it'll remove it as I go. Otherwise I can just duplicate your script down and change (" copy", ""); to (" copy 2", "");, (" copy 2", "");, ect.

 

Edit: Updated while I was responding. This is exactly what I was looking for, you're a lifesaver.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 31, 2019 Dec 31, 2019

Copy link to clipboard

Copied

See update. Still does not address # suffixes when a layer is copied multiple times. I'll see if I can figure that out. Glad it helps.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 31, 2020 Aug 31, 2020

Copy link to clipboard

Copied

Could you please provide an explanation on how to enter the above code to remove "copy" from Ai layers?  It's very frustrating to have to remove "copy" from each layer.  If there is another way to avoid / remove "copy", I would love to hear it. Thanks

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Aug 31, 2020 Aug 31, 2020

Copy link to clipboard

Copied

LATEST

If you're asking how to run the code:  Copy and paste it in a jsx file. (You can create a txt file and change the extension to jsx.)  Then, while your document is open in Illustrator, go to File > Scripts > Other Script (Ctrl+F12). Find your script and open it.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 31, 2019 Dec 31, 2019

Copy link to clipboard

Copied

@joer74233125

I'm sure there's a more elegant way, but this will take care of 3 levels of copied layer names. Add a " copy 4" line if you think you need it.

 

Edit: Forgot to add lines for "Main Layers" as well.

updateLayerNames();

function updateLayerNames() {
  var aDoc = app.activeDocument;
  var i;
  var ii;
  for (i = 0; i < aDoc.layers.length; i++) {
    aDoc.layers[i].name = aDoc.layers[i].name.replace(" copy 3", "");
    aDoc.layers[i].name = aDoc.layers[i].name.replace(" copy 2", "");
    aDoc.layers[i].name = aDoc.layers[i].name.replace(" copy", "");
    for (ii = 0; ii < aDoc.layers[i].layers.length; ii++) {
      aDoc.layers[i].layers[ii].name = aDoc.layers[i].layers[ii].name.replace(" copy 3", "");
      aDoc.layers[i].layers[ii].name = aDoc.layers[i].layers[ii].name.replace(" copy 2", "");
      aDoc.layers[i].layers[ii].name = aDoc.layers[i].layers[ii].name.replace(" copy", "");
    }
  }
}

 

 

This could be made more editable with the use of a few variables. 🙂

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 31, 2019 Dec 31, 2019

Copy link to clipboard

Copied

This is perfect, and much more elegant that what I was thinking, of just running a version of the script for each layer. I'll just edit the script with 'copy n' each time I run up against more layers.

 

Thank you so much!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Dec 31, 2019 Dec 31, 2019

Copy link to clipboard

Copied

Hi @rcraighead, you could use Regex to handle the copy suffixes and recursion to handle the depth:

 

updateLayerNames()

function updateLayerNames() {
  var aDoc = app.activeDocument;
  for (var i = 0; i < aDoc.layers.length; i++)
    updateLayerName(aDoc.layers[i])
}

function updateLayerName(layer) {
  layer.name = layer.name.replace(/\scopy(\s\d{1,})?$/g, "");
  for (var i = 0; i < layer.layers.length; i++)
    updateLayerName(layer.layers[i])
}

 

This will handle any " copy" no matter the depth or number, see RegEx example here.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 31, 2019 Dec 31, 2019

Copy link to clipboard

Copied

Thank you! I knew there was a regex solution I was missing. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 01, 2020 Jan 01, 2020

Copy link to clipboard

Copied

@Inventsable, one question: Is there any difference between using {1,} and + as a Quantifier for \d or is it personal preference?

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jan 01, 2020 Jan 01, 2020

Copy link to clipboard

Copied

Hi @rcraighead, good question but as far as I know in this context there wouldn't be any difference and you could say it's personal preference. I tend to lean towards bracket syntax so I can control the number of matches (as I normally need between 1 and some other digit), but so long as + immediately follows \d they should behave identically here. Since we know that an optional digit will always follow " copy" and should match even if it doesn't exist, any of the following should be functionally identical:

 

/\scopy(\s\d{1,})?$/
/\scopy(\s\d+)?$/
/\scopy(\s\d*)?$/

 

If we needed more flexible matching, like not needing the ? quantifier for the optional digit suffix, these would start producing different results. * would match even if zero matches, whereas the greedy and {} syntax would not. This happens to be a pretty straightfoward pattern with strict enough expectations that we wouldn't need to worry about that though.

 

Also, we could further refactor my original function to be recursive itself, rather than needing two functions:

 

updateLayerNames()

function updateLayerNames(list = []) {
    list = list.length ? list : app.activeDocument.layers;
    for (var i = 0; i < list.length; i++) {
        list[i].name = list[i].name.replace(/\scopy(\s\d{1,})?$/g, "");
        if (list[i].layers.length) updateLayerNames(list[i].layers)
    }
}

 

Notice that the parameter is set to have an empty array by default, so if the function is called without any parameters, it will start at the top-level `document.layers` object but otherwise will bubble down to layer.layers and recall the function with that as the new list. There's no need to iterate through a static value as an array like activeDocument.layers when we know we can expect a Layer item from multiple sources and we act on them the same way -- so instead, we can use the iterable list itself as a variable and just assign a different value when needed.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jan 01, 2020 Jan 01, 2020

Copy link to clipboard

Copied

This forum keeps marking me as spam for making more than two edits to my posts! Super pedantic, I really dislike that.

 

There should be no difference in this context, but only because we know exactly the format of our intended string. The following would be identical:

 

/\scopy(\s\d{1,})?$/
/\scopy(\s\d+)?$/
/\scopy(\s\d*)?$/

 

Sorry, I had a much more detailed response earlier. Maybe it's still in the email notification if you've gotten it?

 

Btw, the original function I used could be further refactored so that the iterable list itself is a variable and using a single function. Notice that the function will call itself if layer.layers has length, has list = [] as a default param, and will assign app.activeDocuments.layers as the list if the function is called with no param (which should only happen at the first time). Since we know all iterable lists will be similar and we act on them the same, there's no reason not to try and use a single loop (but just change what we're looping through):

 

updateLayerNames()

function updateLayerNames(list = []) {
    list = list.length ? list : app.activeDocument.layers;
    for (var i = 0; i < list.length; i++) {
        list[i].name = list[i].name.replace(/\scopy(\s\d{1,})?$/g, "");
        if (list[i].layers.length) updateLayerNames(list[i].layers)
    }
}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 01, 2020 Jan 01, 2020

Copy link to clipboard

Copied

Yes, I read your earlier post. I was trying to retrieve it.
Your explanations are so helpful! I'm new to recursion so digging into that.

FYI… I'm getting an error when running the latest version: "Expected: )".
Haven't been able to determine the cause.

image.png

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jan 01, 2020 Jan 01, 2020

Copy link to clipboard

Copied

Hmmm, are default parameters not supported in JSX? I tend to write in Typescript and compile down so occasionally I'm prone to throw in some unsupported syntax. Try this:

updateLayerNames()

function updateLayerNames(list) {
    if (arguments.length < 1) list = app.activeDocument.layers;
    for (var i = 0; i < list.length; i++) {
        list[i].name = list[i].name.replace(/\scopy(\s\d{1,})?$/g, "");
        if (list[i].layers.length) updateLayerNames(list[i].layers)
    }
}

 

Or this:

 

updateLayerNames([])

function updateLayerNames(list) {
    list = list.length ? list : app.activeDocument.layers;
    for (var i = 0; i < list.length; i++) {
        list[i].name = list[i].name.replace(/\scopy(\s\d{1,})?$/g, "");
        if (list[i].layers.length) updateLayerNames(list[i].layers)
    }
}

 

Why not use VSCode instead of the very old ESTK? It's a very beautiful experience to code in VSCode especially alongside your panel JS code, I also have a few tools you're welcome to use like Scriptopia which handles all of the setup for Typescript to allow you to see the Illustrator DOM and autocomplete as you type alongside compiling ES6 methods down to their JSX counterparts. If you'd like an example of how this works, here's an online code editor specific to Illustrator, I have a panel version of this as well so you can write and run code directly inside Illustrator and even use ES6 methods for scripting.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 01, 2020 Jan 01, 2020

Copy link to clipboard

Copied

Those both work. Thanks.

"Why not use VSCode instead of the very old ESTK?"
Because I don't know how to set it up. 😕 Can I test the script directly from VSCode?
I'll work on that this afternoon (after a good, long New Year's walk).

So much to learn!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jan 01, 2020 Jan 01, 2020

Copy link to clipboard

Copied

VSCode is free and open source, backed by Microsoft. No setup required, just install and you have my personal favorite code editor -- comes with a lot of features out of the box like integrated terminal, intellisense (auto-completion of code and hints as you type), configurable themes, tons of extensions and more. Just fyi, Adobe officially deprecated the ESTK in favor of a new VSCode extension so it's actually what they r... too. You can read about the switch to VSCode here.

 

Can I test the script directly from VSCode?

 

Sure, either through the ESTK extension or through other extensions like Adobe Script Runner or anything that allows you to run terminal commands, where you can see required commands here. You lose the ESTK autocompletion as you type in making the switch, but that's solved if you were to use Scriptopia like I linked earlier (and you'd get way more benefits like ES6 support in writing in Typescript). Basically, you write in Typescript (.ts) and think of it as your dev file, and this compiles every time you save to a Production file (.jsx) which you'd then use Adobe Script Runner on or link to in a CEP panel to actually run the script.

 

Make sure you have nodeJS installed on your computer though prior to using Scriptopia since it relies on npm.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 01, 2020 Jan 01, 2020

Copy link to clipboard

Copied

Got VSCode running! Installed Adobe Script Runner and can test the scripts directly. Lots more to learn. Thanks for the help!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jan 01, 2020 Jan 01, 2020

Copy link to clipboard

Copied

Nice! Try Typescript next! Promise it's easier than it seems and works exactly like Javascript, no need to write any TS specific syntax (though you're free to if needed). Try opening your terminal in VSCode, installing node if needed, creating a new folder and running 'npm init -y', then 'npm install -g scriptopia', then 'scriptopia', then hit control + shift + b and select 'tsc: watch (path to tsconfig)'. Then you'll be coding in the future

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 02, 2020 Jan 02, 2020

Copy link to clipboard

Copied

@Inventsable,

I've tried to follow the instructions for installing "Scriptopia" but am getting these errors near the end of the install. Can you tell what I'm doing wrong? I do have admin rights.

image.png

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jan 02, 2020 Jan 02, 2020

Copy link to clipboard

Copied

What's your operating system?

 

Did you install node as administrator?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jan 02, 2020 Jan 02, 2020

Copy link to clipboard

Copied

This might be related to your issue

 

You could also potentially skip the install step entirely with something like:

 

npx scriptopia

 

Though I suspect if node/VSCode doesn't have write privileges this may still fail. If you give me your OS details I'll look into it

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 02, 2020 Jan 02, 2020

Copy link to clipboard

Copied

Thanks for all your help.

MacOS 10.13.6

 

I DID install NodeJS.

 

Errors attempting to install with: 

npx scriptopia

image.png

I'm afraid this is all a little beyond me. 😕

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines