Copy link to clipboard
Copied
I'm a designer looking to create an illustrator script similar to the video link below which I'm intending to use as a way of numbering pieces that will be later referenced in an assembly manual. I'm hoping if someone can either guide me or help me write a script as I don't have any experience doing so.
Similar to the script used in the video I would like it to have a functinality of being able to specify a prefix, then a number, and a suffix with each mouse click it places the text with those number & incremental increase in the number followed by additional clicks. (ex. A1b, A2b, A3b, A4c, and so on...)
I've tried contacting the original uploader of the video through their blog but no response from them so
any guidance is greatly appreciated!
Here's a try. I'm sure some of the gurus here will have a good laugh, but it's late and it's the best I could come up with tonight.
makeLabel()
function makeLabel() {
var aDoc = app.activeDocument;
var prefix, increment, suffix;
var sel = selection[0];
if (sel.typename == "TextFrame") {
var label = sel.contents;
var i = sel.contents.length;
prefix = label.charAt (0);
dash = /-/.exec(label);
increment = /\d+/.exec(label);
if (i > 2)
...
Here's my take:
incrementNumberInTextFrame(selection[0]);
function incrementNumberInTextFrame(item) {
if (item != undefined && item.typename == "TextFrame") {
var copyOfItem = item.duplicate();
copyOfItem.translate(0, -item.height);
var regex = /\d+/;
var numberString = item.contents.match(regex)[0];
copyOfItem.contents = copyOfItem.contents.replace(regex, Number(numberString) + 1);
selection = [copyOfItem];
redraw();
}
}
This wi
...Copy link to clipboard
Copied
I used your request as a learning exercise. The script does not have all the functionality you are looking for (I don't know how to trigger a script directly from a mouse click without using a 3rd-party app). It might help though.
/*
by Ray Craighead
Works in Adobe Illustrator CC 2015 (only one tested)
• Type the first label using "PrefixIncrementSuffix" format
• With the label selected rigger the script
It will duplicate the selection and update the content
• Reposition the new label and trigger the script again, etc, etc,
• Assign a keyboard shortcut to the script for easier use
*/
makeLabel();
function makeLabel() {
var aDoc = app.activeDocument;
var prefix, increment, suffix, d;
var sel = selection[0];
if (sel.typename == "TextFrame") {
var label = sel.contents;
prefix = /\b\w/.exec(label);
increment = /\d+/.exec(label);
suffix = /\w\b/.exec(label);
}
// prefix = nextChar(prefix.toString());
increment = (increment * 1) + 1;
// suffix = nextChar(suffix.toString());
function nextChar(c) {
return String.fromCharCode(c.charCodeAt(0) + 1);
}
label = (prefix + increment + suffix);
sel.duplicate();
redraw();
aDoc.selection[1].selected = false;
selection[0].translate(0,(selection[0].height * -1));
selection[0].contents = label;
}
I realized after creating the video you did not intend for the "prefix" and "suffix" to update sequencially. Those lines have been disabled in the script. It was great to learn how to do that though.
Copy link to clipboard
Copied
Hi Ray, Hope it's ok, just for learning myself, I've made a couple of versions of your script to show different uses of regular expressions. Version 2 uses match and version 3 uses replace methods of String. Using the RegExp exec method has advantages better seen when used in a loop I think.
function makeLabel2() {
var anItem = selection[0];
var label;
if (anItem != undefined && anItem.typename == "TextFrame") {
label = anItem.duplicate();
label.translate(0, -selection[0].height);
// match returns the found strings, in an array
var prefix = anItem.contents.match(/^[A-Z]/)[0];
var index = anItem.contents.match(/\d+/)[0];
var suffix = anItem.contents.match(/[a-z]/)[0];
label.contents = nextChar(prefix) + (Number(index)+1) + nextChar(suffix);
selection = [label];
redraw();
}
function nextChar(c) {
return String.fromCharCode(c.charCodeAt(0) + 1);
}
}
function makeLabel3() {
var anItem = selection[0];
if (anItem != undefined && anItem.typename == "TextFrame") {
var label = anItem.duplicate();
label.translate(0, -anItem.height);
// regex replace method can take a function as 2nd parameter!
label.contents = anItem.contents.replace(/^([A-Z])(\d+)([a-z])/, function (all, prefix, index, suffix) {
return nextChar(prefix) + (Number(index) + 1) + nextChar(suffix);
})
selection = [label];
redraw();
}
function nextChar(c) {
return String.fromCharCode(c.charCodeAt(0) + 1);
}
}
Thanks for the post. It got me thinking! - Mark
Copy link to clipboard
Copied
Thanks @m1b . I was hoping someone would share a better idea. That's what I love about this forum. Best place to keep learning about scripting.
Copy link to clipboard
Copied
I know! It's awesome and I love it too. So helpful. Thanks again.
Copy link to clipboard
Copied
Hi kenta0D4D, it looks like the video shows a plug-in, not a plain script. If a plain script solution won't work for your case, you might need to find a developer who can make plug-ins. Sorry, I can't help. It's out of my league! - Mark
Copy link to clipboard
Copied
I would love to know how it's made, it's not a plugin.
one way it could work with scripting is by adding or duplicating placeholder text frames first. Then a script could run an update them.
Copy link to clipboard
Copied
I'm sure it could be replicated using Keyboard Maestro. But no time to try it. 🙂
Copy link to clipboard
Copied
...whenever you have a chance Ray, no presure 🙂
Copy link to clipboard
Copied
Ok, I couldn't resist trying. I used a variation of the script I created earlier and built it into a loop macro using Keyboard Maestro. If you're on Mac and want to try it I can make it available. Keyboard Maestro has a generous free trial as well.
And the updated script used in the macro:
// makeLabel();
var prefix, increment, suffix, sel;
function makeLabel() {
var aDoc = app.activeDocument;
if (selection.length == 1) {
sel = selection[0];
}
if (sel.typename == "TextFrame") {
var label = sel.contents;
prefix = /\b\w/.exec(label);
increment = /\d+/.exec(label);
suffix = /\w\b/.exec(label);
}
increment = (increment * 1) + 1;
function nextChar(c) {
return String.fromCharCode(c.charCodeAt(0) + 1);
}
label = (prefix + increment + suffix);
return(label);
}
function updateLabel (){
prefix = /\b\w/.exec(label);
increment = /\d+/.exec(label);
suffix = /\w\b/.exec(label);
}
increment = (increment * 1) + 1;
function nextChar(c) {
return String.fromCharCode(c.charCodeAt(0) + 1);
}
Copy link to clipboard
Copied
So good! 🙂 Nice use of diverse tools to solve a problem. OP might find a similar product on their platform if not Mac?
Copy link to clipboard
Copied
Hi rcraighead, thank you so much for your help and your quick turnaround. The script is working like a charm! One more request if possible is there any way to integrate an option for me to have a suffix or not have an suffix?
Copy link to clipboard
Copied
This is a temporary fix to eliminate the suffix:
makeLabelnoSuffix();
function makeLabelnoSuffix() {
var aDoc = app.activeDocument;
var prefix, increment, suffix, d;
var sel = selection[0];
if (sel.typename == "TextFrame") {
var label = sel.contents;
prefix = /\b\w/.exec(label);
increment = /\d+/.exec(label);
// suffix = /\w\b/.exec(label);
}
increment = (increment * 1) + 1;
function nextChar(c) {
return String.fromCharCode(c.charCodeAt(0) + 1);
}
label = (prefix + increment)// + suffix);
sel.duplicate();
redraw();
aDoc.selection[1].selected = false;
selection[0].translate(0,(selection[0].height * -1));
selection[0].contents = label;
}
Copy link to clipboard
Copied
One more try. This version will work with or without a suffix. Just start with the format you want and it should incrementally update the number with or without a suffix.
makeLabel();
function makeLabel() {
var aDoc = app.activeDocument;
var prefix, increment, suffix;
var sel = selection[0];
if (sel.typename == "TextFrame") {
var label = sel.contents;
prefix = /\b[A-Z]/.exec(label);
increment = /[0-9]/.exec(label);
suffix = /[a-z]\b/.exec(label);
}
increment = (increment * 1) + 1;
function nextChar(c) {
return String.fromCharCode(c.charCodeAt(0) + 1);
}
if (suffix != null) {
label = (prefix + increment + suffix);
}else{
label = (prefix + increment);
}
sel.duplicate();
redraw();
aDoc.selection[1].selected = false;
selection[0].translate(0, (selection[0].height * -1));
selection[0].contents = label;
}
Copy link to clipboard
Copied
Hi rcraighead, thank you for the updated script. If it's not too much work, is it possible me to ask for last request? Is there a way for this to work with both upper case or lowercase suffix and prefix?
For example
and in addition if there could be a option for the script to still work even with a "-" seperator between the prefix and the number.
For example
Hopefully these aren't too much of a ask. Thank you again in advance!
Copy link to clipboard
Copied
Here's a try. I'm sure some of the gurus here will have a good laugh, but it's late and it's the best I could come up with tonight.
makeLabel()
function makeLabel() {
var aDoc = app.activeDocument;
var prefix, increment, suffix;
var sel = selection[0];
if (sel.typename == "TextFrame") {
var label = sel.contents;
var i = sel.contents.length;
prefix = label.charAt (0);
dash = /-/.exec(label);
increment = /\d+/.exec(label);
if (i > 2){
suffix = label.charAt (i - 1);
}
}
if (increment == null) {
increment = "-";
} else {
increment = (increment * 1) + 1;
}
function nextChar(c) {
return String.fromCharCode(c.charCodeAt(0) + 1);
}
if (suffix != null && dash != null) {
label = (prefix + dash + increment + suffix);
}else if (suffix != null && dash == null) {
label = (prefix + increment + suffix);
}else if (suffix == null && dash == null) {
label = (prefix + increment);
}
sel.duplicate();
redraw();
aDoc.selection[1].selected = false;
selection[0].translate(0, (selection[0].height * -1));
selection[0].contents = label;
}
Copy link to clipboard
Copied
Here's my take:
incrementNumberInTextFrame(selection[0]);
function incrementNumberInTextFrame(item) {
if (item != undefined && item.typename == "TextFrame") {
var copyOfItem = item.duplicate();
copyOfItem.translate(0, -item.height);
var regex = /\d+/;
var numberString = item.contents.match(regex)[0];
copyOfItem.contents = copyOfItem.contents.replace(regex, Number(numberString) + 1);
selection = [copyOfItem];
redraw();
}
}
This will increment the first instance of any number in the textframe given to the function. It shouldn't matter what other characters are in the text frame.
- Mark
Edit: adjusted code for better meaningful variable names.
Copy link to clipboard
Copied
Perfect, Mark. Much better solution. I'll read it over better tomorrow morning.
Copy link to clipboard
Copied
Hi rcraighead & m1b. Sorry for the delayed response. I've been busy recently and didn't have a chance to check back. These script works great. Thank you very much for your help!
Copy link to clipboard
Copied
If it's not a plugin, I'm very interested! I'd love to be able to have access to mouse events outside of ScriptUI. Not sure if it's possible at the moment.
Copy link to clipboard
Copied
The used file in the first post is an *.EXE file. (Windows only file type)
I'm also not sure how it works - but it is outside of Illustrator. It is not a Illustrator script and not a plugin.
Copy link to clipboard
Copied
thanks for the demo Ray!! it's awesome. I'm on Windows though.
A quick search gave me a list of similar programs for Win.
Copy link to clipboard
Copied
Thanks Carlos. JavaScript and Keyboard Maestro have rather consumed me for the last couple years. By the time I feel comfortable with them it'll be time to retire. 🙂
Copy link to clipboard
Copied
LOL, yeah the more you learn the more you get sucked in 🙂
Copy link to clipboard
Copied
Really curious what the Windows alternatives have to offer. Don't have a Windows machine to test them on though. Keyboard Maestro is $36 (perpetual license) and pays for itself in about a week. 🙂