Skip to content

Instantly share code, notes, and snippets.

@gepatto
Last active February 25, 2024 16:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gepatto/d19ad3eb1b5fd004ff5ecca73a8a6d2d to your computer and use it in GitHub Desktop.
Save gepatto/d19ad3eb1b5fd004ff5ecca73a8a6d2d to your computer and use it in GitHub Desktop.
Illustrator script: Create Duplicates of Selected group in a grid fitting inside a specified area setting it text to values from an array
/**
* @author Patrick Gutlich
* @year 2024
* @description Create Duplicates of Selected group in a grid fitting inside a specified area setting it text to values from an array
*/
/**
* Helpers
*/
function cmToPoints(cm) {
return cm * 28.3464567;
}
function pointsToCm(pt) {
return pt * 0.035277776;
}
function trim(s) {
return String(s).replace(/^\s+|\s+$/gm, "");
}
function firstWord(s) {
return String(s).split(" ")[0];
}
// Variables
var doc;
var documentMarginX = 8;
var documentMarginY = 8;
var areaWidth = 40; // default value
var areaHeight = 30; // default value
var spacingHorizontal = 8;
var spacingVertical = 8;
var red = new RGBColor();
red.red = 255;
red.green = 0;
red.blue = 0;
var noColor = new NoColor();
var names = [
"foo","bar","dodo"
];
var fontIndex;
var fontNames_array = [];
var fontSize = 24;
var fontName = "Nobel-Bold"; //preferred font
var font;
// populate font_names array and find the index of preferred font;
// so it can be slected in the font dropdown
for (var t = 0; t < app.textFonts.length; t++) {
fontNames_array.push(app.textFonts[t].name);
if (fontNames_array[t] == fontName) {
fontIndex = t;
}
}
var original; // selected object to duplicate
var originalName = ""; // given name of selected object
var textTarget; // the textframe to fill with value of the array
var sizeWarning = false;
// UI Variables, make them global for easy access
var dialog;
var mainGroup;
var dimensionsGroup;
var originalPanel;
var originalwidthrow;
var lblOriginalwidth;
var txtOriginalWidth;
var originalheightrow;
var lblOriginalheight;
var txtOriginalHeight;
var panelArea;
var areaWidthGroup;
var lblAreareaWidth;
var txtAreaWidth;
var areaHeightGroup;
var lblAreaheight;
var txtAreaHeight;
var textGroup;
var textPanel;
var txtNames;
var chkTrimSpaces;
var chkFirstWord;
var fontPanel;
var chkOverrideFont;
var fontOverridesGroup;
var lblFontFamily;
var lstFontNames;
var fontsizeGroup;
var lblFontsize;
var txtFontSize;
var btnGroup;
var btnCreate;
/**
* CREATE DUPLICATES
*/
function createDuplicates() {
if (original == null) {
// by now orginal should not be null, but check it anyway
alert("No object selected");
} else {
// are there any textFrames in the selected object, if so select the first one.
if (original.textFrames.length > 0) {
textTarget = original.textFrames[0];
}
// make a new group to hold the duplicates
var duplicatesGroup = doc.groupItems.add(doc, ElementPlacement.PLACEBEFORE);
duplicatesGroup.name = "duplicates group";
var cols = Math.floor(areaWidth / (original.width + spacingHorizontal));
if(fontName!="" && fontName!=undefined){
font = app.textFonts.getByName(fontName);
}
if (font == null) {
font = app.textFonts[0] ;
}
for (var i = 0; i < names.length; i++) {
var j = i + 1; //leave original intact
var xPos =
original.position[0] +
(j % cols) * (original.width + spacingHorizontal);
var yPos =
original.position[1] -
Math.floor(j / cols) * (original.height + spacingVertical);
var duplicateObject = original.duplicate(
duplicatesGroup,
ElementPlacement.PLACEATEND
);
duplicateObject.name = originalName + "_" + j;
duplicateObject.position = [xPos, yPos];
duplicateObject.stroked = true;
duplicateObject.strokeWidth = 0.01;
duplicateObject.strokeColor = red;
duplicateObject.fillColor = noColor;
textTarget = duplicateObject.textFrames[0];
if (textTarget != undefined) {
textTarget.contents = chkFirstWord.value
? firstWord(names[i])
: trim(names[i]);
if (chkOverrideFont.value) {
textTarget.textRange.characterAttributes.textFont = font;
textTarget.textRange.characterAttributes.size = fontSize;
}
} else {
// if there is no textFrame let's add one and center it
var myTextFrame = duplicatesGroup.textFrames.add();
myTextFrame.contents = trim(names[i]);
myTextFrame.textRange.characterAttributes.textFont = font;
myTextFrame.textRange.characterAttributes.size = fontSize;
myTextFrame.position = [
xPos + (original.width - myTextFrame.width) * 0.5,
yPos - (original.height - myTextFrame.height) * 0.5,
];
}
if(textTarget.width > original.width || textTarget.height > original.height){
sizeWarning = true;
textTarget.textRange.characterAttributes.fillColor = red;
}
}
if( sizeWarning ){
alert("Some texts exceed the area of the original\n They are colored red");
}
}
}
/**
* CREATE DIALOG UI
*/
function createDialog() {
// CREATE DIALOG
// ======
dialog = new Window("dialog");
dialog.text = "Original Creator";
//ialog.orientation = "column";
dialog.alignChildren = ["center", "top"];
dialog.spacing = 16;
dialog.margins = 16;
// MAINGROUP
// =========
mainGroup = dialog.add("group", undefined, { name: "mainGroup" });
mainGroup.orientation = "column";
mainGroup.alignChildren = ["left", "center"];
mainGroup.spacing = 8;
mainGroup.margins = 4;
// DIMENSIONSGROUP
// ===============
dimensionsGroup = mainGroup.add("group", undefined, {name: "dimensionsGroup"});
dimensionsGroup.orientation = "row";
dimensionsGroup.alignChildren = ["center", "center"];
dimensionsGroup.spacing = 10;
dimensionsGroup.margins = 4;
dimensionsGroup.alignment = ["fill", "center"];
// ORIGINALPANEL
// ==========
originalPanel = dimensionsGroup.add("panel", undefined, undefined, {name: "originalPanel"});
originalPanel.text = "Selected Original (cm)";
originalPanel.preferredSize.width = 201;
originalPanel.orientation = "column";
originalPanel.alignChildren = ["right", "top"];
originalPanel.spacing = 10;
originalPanel.margins = 16;
originalPanel.alignment = ["center", "fill"];
// ORIGINALWIDTHROW
// =============
originalwidthrow = originalPanel.add("group", undefined, {name: "originalwidthrow"});
originalwidthrow.orientation = "row";
originalwidthrow.alignChildren = ["left", "center"];
originalwidthrow.spacing = 10;
originalwidthrow.margins = 0;
lblOriginalwidth = originalwidthrow.add("statictext", undefined, undefined, {name: "lblOriginalwidth"});
lblOriginalwidth.text = "Width";
txtOriginalWidth = originalwidthrow.add('edittext {properties: {name: "originalWidth", "readonly":true}}');
txtOriginalWidth.text = pointsToCm(original.width);
txtOriginalWidth.preferredSize.width = 120;
// ORIGINALHEIGHTROW
// ==============
originalheightrow = originalPanel.add("group", undefined, {name: "originalheightrow"});
originalheightrow.orientation = "row";
originalheightrow.alignChildren = ["left", "center"];
originalheightrow.spacing = 10;
originalheightrow.margins = 0;
lblOriginalheight = originalheightrow.add("statictext", undefined,undefined,{ name: "lblOriginalheight" });
lblOriginalheight.text = "Height";
txtOriginalHeight = originalheightrow.add('edittext {properties: {name: "originalHeight","readonly":true}}');
txtOriginalHeight.text = pointsToCm(original.height);
txtOriginalHeight.preferredSize.width = 120;
// PANELAREA
// =========
panelArea = dimensionsGroup.add("panel", undefined, undefined, {name: "panelArea"});
panelArea.text = "Bounding Area (cm)";
panelArea.orientation = "column";
panelArea.alignChildren = ["right", "top"];
panelArea.spacing = 10;
panelArea.margins = 16;
panelArea.alignment = ["center", "fill"];
// areaWidthGroup
// ======
areaWidthGroup = panelArea.add("group", undefined, {name: "areaWidthGroup"});
areaWidthGroup.orientation = "row";
areaWidthGroup.alignChildren = ["left", "center"];
areaWidthGroup.spacing = 10;
areaWidthGroup.margins = 0;
lblAreareaWidth = areaWidthGroup.add("statictext", undefined, undefined, {name: "lblAreareaWidth"});
lblAreareaWidth.text = "Width";
txtAreaWidth = areaWidthGroup.add('edittext {justify: "right", properties: {name: "areaWidth"}}');
txtAreaWidth.text = parseFloat(areaWidth).toFixed(2);
txtAreaWidth.preferredSize.width = 62;
// areaHeightGroup
// =======
areaHeightGroup = panelArea.add("group", undefined, {name: "areaHeightGroup"});
areaHeightGroup.orientation = "row";
areaHeightGroup.alignChildren = ["left", "center"];
areaHeightGroup.spacing = 10;
areaHeightGroup.margins = 0;
lblAreaheight = areaHeightGroup.add("statictext", undefined, undefined, {name: "lblAreaheight"});
lblAreaheight.text = "Height";
txtAreaHeight = areaHeightGroup.add('edittext {justify: "right", properties: {name: "areaHeight"}}');
txtAreaHeight.text = parseFloat(areaHeight).toFixed(2);;
txtAreaHeight.preferredSize.width = 62;
// TEXTGROUP
// =========
textGroup = mainGroup.add("group", undefined, { name: "textGroup" });
textGroup.orientation = "column";
textGroup.alignChildren = ["center", "center"];
textGroup.spacing = 12;
textGroup.margins = 0;
textGroup.alignment = ["fill", "center"];
// TEXTPANEL
// =========
textPanel = textGroup.add("panel", undefined, undefined, {name: "textPanel"});
textPanel.text = "Names";
textPanel.orientation = "column";
textPanel.alignChildren = ["fill", "top"];
textPanel.spacing = 10;
textPanel.margins = 16;
textPanel.alignment = ["fill", "center"];
txtNames = textPanel.add("edittext {properties: {name: names , multiline: true, scrollable: true }}");
txtNames.helpTip = "comma separated names ";
txtNames.text = names.join(",");
txtNames.preferredSize.height = 128;
chkTrimSpaces = textPanel.add("checkbox", undefined, undefined, {name: "trimSpaces"});
chkTrimSpaces.text = "Trim Spaces";
chkTrimSpaces.value = true;
chkFirstWord = textPanel.add("checkbox", undefined, undefined, {name: "firstWord"});
chkFirstWord.text = "First Word Only";
chkFirstWord.value = true;
// FONTPANEL
// =========
fontPanel = textGroup.add("panel", undefined, undefined, {name: "fontPanel"});
fontPanel.text = "Font";
fontPanel.orientation = "column";
fontPanel.alignChildren = ["fill", "top"];
fontPanel.spacing = 10;
fontPanel.margins = 16;
fontPanel.alignment = ["fill", "center"];
chkOverrideFont = fontPanel.add("checkbox", undefined, undefined, {name: "overrideFont"});
chkOverrideFont.text = "Override Font";
chkOverrideFont.value = false;
chkOverrideFont.onClick = function () {
fontOverridesGroup.enabled = chkOverrideFont.value;
};
fontOverridesGroup = fontPanel.add("group", undefined, { name: "overrides" });
fontOverridesGroup.orientation = "column";
fontOverridesGroup.alignChildren = ["fill", "top"];
fontOverridesGroup.enabled = chkOverrideFont.value;
lblFontFamily = fontOverridesGroup.add("statictext", undefined, undefined, {name: "lblFontFamily"});
lblFontFamily.text = "FontFamily";
lstFontNames = fontOverridesGroup.add("dropdownlist", undefined, undefined, {name: "fontName", items: fontNames_array});
lstFontNames.selection = fontIndex;
fontName = lstFontNames.selection;
lstFontNames.onChange = function () {
fontName = lstFontNames.selection;
};
// FONTSIZEGROUP
// =============
fontsizeGroup = fontOverridesGroup.add("group", undefined, {name: "fontsizeGroup"});
fontsizeGroup.orientation = "row";
fontsizeGroup.alignChildren = ["right", "center"];
fontsizeGroup.spacing = 10;
fontsizeGroup.alignment = ["left", "top"];
lblFontsize = fontsizeGroup.add("statictext", undefined, undefined, {name: "lblFontsize"});
lblFontsize.text = "Font Size (points)";
txtFontSize = fontsizeGroup.add('edittext {properties: {name: "fontSize"}}');
txtFontSize.text = fontSize;
txtFontSize.preferredSize.width = 65;
txtFontSize.alignment = ["right", "center"];
// BTNGROUP
// ========
btnGroup = mainGroup.add("group", undefined, { name: "btnGroup" });
btnGroup.orientation = "column";
btnGroup.alignChildren = ["center", "center"];
btnGroup.spacing = 10;
btnGroup.margins = 0;
btnGroup.alignment = ["center", "center"];
btnCreate = btnGroup.add("button", undefined, undefined, {name: "btnCreate"});
btnCreate.text = "Create";
btnCreate.onClick = function () {
areaWidth = cmToPoints(parseFloat(txtAreaWidth.text));
areaHeight = cmToPoints(parseFloat(txtAreaHeight.text));
fontSize = parseFloat(txtFontSize.text);
names = txtNames.text.split(",");
layer = doc.layers[0];
createDuplicates();
dialog.close();
};
}
// Check if there is an open docuement
doc = app.activeDocument;
if (doc != null) {
areaWidth = pointsToCm(doc.width);
areaHeight = pointsToCm(doc.height);
// Check if there is something selected
original = app.activeDocument.selection[0];
if (original != undefined) {
originalName = original.name; //store the name of the selected object
//original.name = "original_" + original.name;
createDialog();
dialog.show();
} else {
alert("Select a group in an open document");
}
} else {
alert("Select a group in an open document");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment