Illustrator Word Spacing Script
Copy link to clipboard
Copied
I am trying to write a script so that a stack words, of varying heights, will be spaced with an 11pt vertical gap between each of them (measured between the text and not the bounding boxes). Anyone know how to do this?
Explore related tutorials & articles
Copy link to clipboard
Copied
Femkeblanko wrote something that determines the coordinates of the start and end of an area frame. It takes a text frame and creates a duplicate to outline which you can then get precise top/bottom coords for the text. This could be 1 approach, would just have to be reconfigured for your needs.
alternatively, you could try making an algorithm of sorts to determine the text height based on typeface pt size. I've tried such before, but it's usually not perfect.
Copy link to clipboard
Copied
Bonjour Rian,
Ce que vous voulez correspond t'il à cet exemple ?
Le texte peut-être vectorisé ?
René
Copy link to clipboard
Copied
That would've helped. Since I was only using one font, I ended up doing it by manually measuring the height of the spaces box above and below the text, and getting their ratios to the bounding box's full height. Then I had the script place the text boxes on the page, top edge to bottom edge, and used the ratios to get the actual distance between the text and adjusted it accordingly. There's probably an easier way, but I am new to programming. The one benefit of this method is you don't have to convert the text to paths.
Copy link to clipboard
Copied
Hi @Brian32453879u67v (and others), I am late to this thread, but I've done a fair bit of this type of thing before, so I've put together a function that, given one or more text frames, will space the text (by adjusting leading) so that the space between lines is an exact amount. Not tested much at all at this stage. See how it goes.
- Mark
/**
* @file Set Space Between Text Lines.js
* Demonstrates `setSpaceBetweenTextLines` function.
* Usage: select one or more text frames and run script.
* @author m1b
* @discussion https://community.adobe.com/t5/illustrator-discussions/illustrator-word-spacing-script/m-p/14439010
*/
(function () {
var doc = app.activeDocument,
textFrames = doc.selection;
if (0 === textFrames.length)
return alert('Please select one or more text frames and try again.');
var spacing = prompt('Enter line spacing amount, in points:', 0);
if (
null !== spacing
&& !isNaN(Number(spacing))
)
setSpaceBetweenTextLines(doc, textFrames, Number(spacing));
})();
/**
* Given a text frame, will adjust leading
* so the distance between glyphs on each line
* matches `spacing` value.
* @author m1b
* @version 2024-02-27
* @param {Document} doc - an Illustrator Document.
* @param {TextFrame|Array<TextFrame>} textFrame - the text frame to adjust, or array of text frames.
* @param {Number} [spacing] - the desired spacing, in points, between lines (default: 0).
*/
function setSpaceBetweenTextLines(doc, textFrame, spacing) {
spacing = spacing || 0;
if ('Array' === textFrame.constructor.name) {
// handle array of textFrames
for (var i = 0; i < textFrame.length; i++)
setSpaceBetweenTextLines(doc, textFrame[i], spacing);
return;
}
else if (!textFrame.hasOwnProperty('story'))
throw Error('setSpaceBetweenTextLines: bad `text` supplied.');
if ('TextFrame' !== textFrame.constructor.name)
textFrame = textFrame.story.textFrames[0];
// set the leading to absolute
convertToAbsoluteLeading(textFrame);
// add extra gap between lines
textFrame.textRange.leading += 100;
// get the outlined text grouped into lines
var outlines = outlineTextLines(doc, textFrame.duplicate());
for (var i = 1, y1, y2; i < outlines.length; i++) {
y1 = outlines[i - 1].geometricBounds[3];
y2 = outlines[i].geometricBounds[1];
// set text line's leading
textFrame.lines[i].leading += (y2 - y1) + spacing;
}
// clean up
for (var i = outlines.length - 1; i >= 0; i--)
outlines[i].remove();
};
/**
* Returns `textFrame` converted into outlines, grouped into "lines".
* NOTE: `textFrame` will be destroyed.
* @author m1b
* @version 2024-02-27
* @param {Document} doc - an Illustrator Document.
* @param {TextFrame} textFrame - a TextFrame.
* @returns {Array<GroupItem>}
*/
function outlineTextLines(doc, textFrame) {
var leadings = Array(textFrame.lines.length),
groups = Array(textFrame.lines.length);
// create a group for each line
for (var i = 0; i < textFrame.lines.length; i++) {
leadings[i] = textFrame.lines[i].leading;
groups[i] = doc.groupItems.add();
groups[i].move(textFrame, ElementPlacement.PLACEBEFORE);
}
var outlines = textFrame.createOutline(),
items = outlines.pageItems,
leadingPositions = [];
// get the bottom of each line (top of bounds to bottom of leading)
for (var i = 0, bottom = outlines.geometricBounds[1]; i < leadings.length; i++) {
bottom -= leadings[i];
leadingPositions.push(bottom);
}
// collect each item into its line
// by comparing bottom of outlined character
// against bottom of leading
itemsLoop:
for (var i = items.length - 1, y; i >= 0; i--) {
y = items[i].geometricBounds[3];
leadingsLoop:
for (var j = 0; j < leadings.length; j++) {
if (y > leadingPositions[j]) {
items[i].move(groups[j], ElementPlacement.PLACEATEND);
// lines[j].push(items[i]);
continue itemsLoop;
}
}
}
// remove the original group
outlines.remove();
return groups;
};
/**
* Sets the text frame's leading
* to an absolute value.
* @param {TextFrame} textFrame
*/
function convertToAbsoluteLeading(textFrame) {
var oldLeading = textFrame.textRange.leading;
textFrame.textRange.autoLeading = false;
textFrame.textRange.leading = oldLeading;
};

