@brian_p_dts, I had a bit of a play and wrote a function "fitText" that aims to fit text to a given textFrame and also takes a maxLineCount parameter, so you can specify that you want, say, 3 lines and if there are more than 3 lines it will reduce point size further. (maxLineCount only works in area text—on path text you just get one line no matter what.) It's a quick script so will definitely fail in edge cases. See what you think.
- Mark

/**
* Fit text to text frame
* @discussion https://community.adobe.com/t5/illustrator-discussions/jsx-parm-error-when-setting-characterattributes-size-of-story-textrange/m-p/13535839
*/
(function () {
var doc = app.activeDocument,
tf = doc.selection[0];
if (tf == undefined) {
alert('Please select a text frame and try again.');
return;
}
// some example text
tf.textRange.contents = 'The quick brown fox jumps over the lazy dog';
// fit the text, specifying number of lines
fitText(tf, 3);
/**
* Fits text to an area text frame or path text.
* @author m1b
* @version 2023-01-29
* @param {TextFrame} textFrame - an Illustrator TextFrame (area text or path text).
* @param {Number} [maxLineCount] - the maximum number of lines of the final text (default: no limit). This is ignored for path text.
* @param {Number} [increment] - the increment of size changing; the precision of the fit (default: 0.05).
*/
function fitText(textFrame, maxLineCount, increment) {
maxLineCount = maxLineCount || Infinity;
increment = increment || 0.05;
if (textFrame.kind == TextType.POINTTEXT)
// "fitting" makes no sense with point text
return;
var text = textFrame.textRange.contents,
size = textFrame.textRange.characterAttributes.size,
// make an overflow text frame
overflowTextFrame = addOverflowTextFrame(textFrame);
// reapply the text contents
textFrame.textRange.contents = text;
// first enlarge text
while (
overflowTextFrame.words.length === 0
&& textFrame.lines.length !== 0
) {
size += increment;
sizeBothTextFrames(size);
}
// now reduce the text size to fit
while (
overflowTextFrame.words.length > 0
|| textFrame.lines.length > maxLineCount
) {
size -= increment;
sizeBothTextFrames(size);
}
// cleanup
overflowTextFrame.remove();
// helper function
function sizeBothTextFrames(size) {
textFrame.textRange.characterAttributes.size = size;
overflowTextFrame.textRange.characterAttributes.size = size;
}
};
/**
* Adds a linked area text frame to the given text frame.
* @author m1b
* @version 2023-01-29
* @param {TextFrame} textFrame - an Illustrator TextFrame (area text or path text).
* @returns {TextFrame} - the overflow textFrame
*/
function addOverflowTextFrame(textFrame) {
try {
var doc = getParentDocument(textFrame);
// make the overflow text frame
return doc.textFrames.areaText(doc.pathItems.rectangle(0, 150, 1000, 1000), TextOrientation.HORIZONTAL, textFrame);
} catch (error) { }
};
/**
* Returns the item's document, if possible.
* @author m1b
* @version 2022-05-29
* @param {PageItem} item - an Illustrator page item.
* @returns {Document}
*/
function getParentDocument(item) {
while (
item.hasOwnProperty('parent')
&& item.constructor.name != 'Document'
)
item = item.parent;
return item;
};
})();