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

Illustrator Word Spacing Script

Explorer ,
Feb 21, 2024 Feb 21, 2024

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? 

TOPICS
Scripting

Views

550
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
Adobe
Participant ,
Feb 22, 2024 Feb 22, 2024

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.

https://community.adobe.com/t5/illustrator-discussions/how-to-get-textrange-each-line-start-and-end-...

 

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.

Votes

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
Advocate ,
Feb 23, 2024 Feb 23, 2024

Copy link to clipboard

Copied

Bonjour Rian,

Ce que vous voulez correspond t'il à cet exemple ?

space.PNGexpand image

Le texte peut-être vectorisé ?

René

Votes

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 ,
Feb 25, 2024 Feb 25, 2024

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.

Votes

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
Community Expert ,
Feb 26, 2024 Feb 26, 2024

Copy link to clipboard

Copied

LATEST

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

 

demo.gifexpand image

/**
 * @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;

};

Votes

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