fit frame to text (free script)

Contributor ,
Nov 15, 2016 Nov 15, 2016

Copy link to clipboard

Copied

Wrote it but don't need it, so help yourselves…

/* fit_frame_to_text.js -- resize selected text frames to fit their current text content [Adobe Illustrator]

This script is released into the public domain. No warranty provided, E&OE, caveat emptor, etc.

Notes:

- Text frame must be rectangular area text, vertically aligned to avoid skewing when its path height changes.

- On success, fitFrame returns new height in points. If text frame is empty it is resized to 0 height.

- If text frame was point- or path-based, or not a text frame, fitFrame returns -1 to indicate it was ignored.

Caution:

- JSX scripts should use anonymous functions and local vars only whenever possible, as AI's shared JS interpreter gets increasingly fragile as globals are defined, eventually resulting in JS (and AS!) commands repeatedly failing with PARM ('MRAP') errors until AI is relaunched. (Though even this doesn't necessarily avoid problem; e.g. repeatedly running any JS script from AS seems to blow up after a while, after which AS commands randomly fail as well.)
*/

(function() {

     function fitFrame(textFrame) { // textFrame must be a TextFrameItem
          if (!(textFrame instanceof TextFrame && textFrame.kind == TextType.AREATEXT)) { // ignore point/path text
               return -1;
          }
          var limit = 0.2;
          var textPath = textFrame.textPath;
          var textLength = textFrame.contents.replace(/\s+$/, "").length; // get length of printable text (ignores trailing whitespace)
          if (textLength === 0) {
               textPath.height = 0; // text frame is empty so set to zero-height and return
               return 0;
          }
          var h = textPath.height;
          // if frame has no height, add some to get things started
          if (h < limit) {
               h = limit;
               textPath.height = h;
          }
          // overflow checker; this checks length of printable text to index of last visible character in frame
          var hasOverflow = function() {
               var lastLine = textFrame.lines[textFrame.lines.length-1];
               if (lastLine === undefined) { // no lines are visible (frame is too small)
                    return textLength > 0;
               }
               return textLength > (lastLine.characters[0].characterOffset + lastLine.length - 1);
          }
          // adjust text frame height using two-stage divide and conquer; crude, but works, and acceptably fast
          // find initial approximate min and max heights between which text overflow occurs
          var oh;
          if (hasOverflow()) {
               do {
                    oh = h;
                    h *= 1.5;
                    textPath.height = h;
               } while (hasOverflow());
          } else {
               do {
                    oh = h;
                    h /= 1.5;
                    textPath.height = h;
               } while (!hasOverflow());
          }
          // narrow the difference between min and max approximations till it falls within limit
          var d = oh - h;
          if (d < 0) { d = -d; }
          while (d > limit) {
               d /= 2;
               h += (hasOverflow() ? d : -d);
               textPath.height = h;
          }
          // if final reduction caused overflow, undo it
          if (hasOverflow()) {
               textPath.height = h + d;
          }
          return textPath.height;
     }
    
     for (var i = 0; i < activeDocument.selection.length; i++) { // iterate over each item in AI's janky selection object
          fitFrame(activeDocument.selection);
     }
})();

TOPICS
Scripting

Views

3.6K

Likes

Translate

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
Engaged ,
Nov 17, 2016 Nov 17, 2016

Copy link to clipboard

Copied

Thank you, hhas01​!

Some time ago I wrote a script for yourself (including split the text frame by the end-of-line symbols) that needed this feature.

I'm somehow thinking that is impossible.

Likes

Translate

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 ,
Nov 17, 2016 Nov 17, 2016

Copy link to clipboard

Copied

Very useful. Thank you

Likes

Translate

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 ,
Nov 18, 2016 Nov 18, 2016

Copy link to clipboard

Copied

Is the same code possible including height and width? Or just width?

Thank you very much

Likes

Translate

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
Contributor ,
Nov 18, 2016 Nov 18, 2016

Copy link to clipboard

Copied

That code always adjusts a text frame path's *vertical height* relative to document. It knows nothing of the text frame's actual shape or orientation. Just make a test doc containing a bunch of text frames rotated to different angles. e.g. If your text frame is 90° rotated, it'll make it 'wider'. If your text frame is at 30°, it'll distort into a parallelogram (not really what you want). If the frame is upside-down, it'll change its height, though it'll be the 'bottom' of the text that stays in position while the top edge moves.

You could parameterize the fit function to take a second function that applies all the adjustments to either the height property, the width property, or even both at the same time. That said, it still won't do you any good for frames at odd angles (anything except 0/90/180/270°). The way I do it, rather than making the fit function itself more complex, is to rotate the frame from whatever angle it's at until it's upright, then apply the basic vertical fit, then rotate it back to its original angle.

Needs a couple extra bits if you also want to put it back into its original position: you'll need to get its original coordinates on the artboard before you rotate, and take its height before and after it's resized, then after you re-rotate you reposition it again based its old coordinates, taking into account whether or not its height has changed, and if it has whether you want to top/bottom/center-align it relative to the old frame's top and bottom edges.

Functions to reposition paths and other objects above/below/around resized text frames are also very doable, long as you still remember how to do your high school math. JavaScript is not something I want to get side-tracked into, though, so I'll leave that as an exercise for others. Here's a screen recording that gives some idea:

Automated brand guidelines demo

And here's the automation system I'm currently developing (and is already running production jobs at a client):

Manta Toolkit | preview

The software is free and open-source; you can even download it and go through the tutorial if you like. Though it probably won't make a huge amount of sense going in cold: there's a lot of documentation not yet done and a major lack of runnable examples, and there is no nice GUI editor with autocomplete and all the other mod cons. I also can't provide unpaid support, and paid support is purely on a consulting basis: i.e. free platform, bespoke development and support. Anything non-trivial, like setting up workflows and creating custom rules, is something I have to do myself until the system's mature enough for users and other developers to easily do it too. And for now I regret don't have time or resources to supply services outside the UK. I'm just putting this here so you can _see_ what's achievable in high-end Illustrator Automation if you just put your back into it a bit.

--

(Sometimes, late at night, around crackling fires and great pitchers of foaming ale, you may hear an incredible tale told by some ancient, weary, battle-broken packaging industry veteran of this magical faraway artwork templating system that promises to do anything and everything you could possibly ever wish for—and Actually Does Do It Too. Crazy mad talk indeed. Only, this mythical beat really _does_ exist—I should know: I wrote it! And now I'm writing my next one too…:)

Likes

Translate

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 ,
Nov 18, 2016 Nov 18, 2016

Copy link to clipboard

Copied

Thanks for the information (read it calmly). I am Spanish and it makes the English a little difficult for me.

What I would like to do with the code is that if the text frame is wider than the text content, it is horizonally adjusted. Or if the text frame is smaller than the text content. (Fit horizontally)

It's possible? Thank you.

Likes

Translate

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
Contributor ,
Nov 18, 2016 Nov 18, 2016

Copy link to clipboard

Copied

The simplest thing that should do what you describe (and nothing more): make a copy of the script, find-and-replace all of its `.height` properties with `.width`, then run it in AI and see what happens. With luck, the right edge of the text frame will move to fit the text exactly. If it doesn't work, just read through the script until you identify whatever other code needs modified, as I'll have just forgotten something. (It's a while since I wrote it.)

If you want to do other stuff like automatically repositioning the resized text frame, perhaps other JavaScript speakers here can help you with that. (I'm really an AppleScript guy, and rather busy right now.)

HTH

Likes

Translate

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
New Here ,
Feb 09, 2022 Feb 09, 2022

Copy link to clipboard

Copied

LATEST

no need to extra scripts or tricks. Just go with this link.

This saves me from big problem.

https://millo.co/overlooked-illustrator-feature-first-now-saves-time-headaches

Likes

Translate

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