Adobe Illustrator Variable Data​: dealing with overset text.

Adobe Illustrator Variable Data: dealing with overset text.

Note: this article speaks on the topic of variable data in Adobe Illustrator, and knowledge of using Illustrator variables is a pre-requisite. It is quite possibly too complicated for beginners or intermediate users. To learn about importing variable data into Illustrator, you can read my other article here:

https://www.garudax.id/pulse/import-csv-txt-files-adobe-illustrator-datasets-vasily-hall?trk=pulse_spock-articles

In Illustrator variable data one of the most common issues is the occurrence of overset text. Unlike Indesign which provides the option to generate a simple text log of all such occurrences (to have the means of tracking which pages need to be adjusted manually), Illustrator has no automatic method by which to even detect the overset items. Suppose that some of the text frames in a dynamic document set come out overset, is there anything we can do about it, assuming that no robust 3rd party plugins are already at work?

The answer is yes, but it lies in the ability to put a script snippet to work during the post-population action which takes place during dataset processing via Illustrator Actions. Basically, an action has to be added to the batch process which will run on every dataset, which then calls the custom script snippet. During batch-processing via actions (the only way Illustrator batch-processes variable datasets), the variable content is first updated and document appearance is changed, and then the user's custom actions play on the document to accomplish whatever the user wants. Typically, the most basic of such batch actions involves a file export of some type. However, many other actions can be played to reach any result so desired, and the ability to run a script from such an action is key to solving issues such as overset text. Another previous article touches on the subject of calling a script from an action: https://www.garudax.id/pulse/illustrator-variable-data-advanced-techniques-vasily-hall?trk=pulse_spock-articles

The gist of which is using an Insert Menu Command to insert a script which appears in File > Scripts menu into the action.

While this is a viable solution, the script has to take certain steps into account, and furthermore deal with the nuances of how Illustrator scripting handles and detects the overset itself. It is important to note that even if a script successfully takes care of oversets by changing the size of the font of the text, or the tracking, or even horizontal or vertical scaling of the text, the affected text box will not automatically snap back to its original properties when the next dataset is populated. The script has to have an action to reset the text box back, explicitly. One way to do this would be to have the script record the affected text box properties during the first dataset in the "note" (Attributes panel > note) and remove the recorded note during the very last dataset, all the while during processing, taking care to reset the properties of the text box to the recorded numbers. Removing the recorded note would not be necessary, except for the possibility of using the same file later, with edited font sizes and having previous notes interfere with the updated workflow. On the same topic, the last processed dataset would leave the text box properties in the template file indefinitely changed, unless other actions/scripts were made active to reset the template - which is also easily accomplished by using File > Revert, or simply closing the template file and not saving the changes.So, what's an example? The following script adjusts the font size on text areas with a single line of text only. To affect text areas with multiple lines, it has to be edited or perhaps entirely re-written to accommodate them.

function DealWithOversetText_SingleLine() {
  var defaultSizeTagName = "overset_text_default_size";
  var defaultIncrement = 0.1;


  function recordFontSizeInTag(size, art){
    var tag;
    var tags = art.tags;
    try {
      tag = tags.getByName(defaultSizeTagName);
      tag.value = size;
    } catch(e) {
      tag = tags.add();
      tag.name = defaultSizeTagName;
      tag.value = size;
    }
  };


  function readFontSizeFromTag(art){
    var tag;
    var tags = art.tags;
    try {
      tag = tags.getByName(defaultSizeTagName);
      return tag.value * 1;
    } catch(e) {
      return null;
    }
  };


  function recordFontSize() {
    var doc = app.activeDocument;
    for (var i = 0; i < doc.textFrames.length; i++) {
      var t = doc.textFrames[i];
      if ((t.kind == TextType.AREATEXT || t.kind == TextType.PATHTEXT) && t.editable && !t.locked && !t.hidden) {
        // t.note = t.textRange.characterAttributes.size;
        recordFontSizeInTag(t.textRange.characterAttributes.size, t);
      }
    };
  };


  function isOverset(textBox, lineAmt) {
    if (textBox.lines.length > 0) {
      var charactersOnVisibleLines = 0;
      if(typeof(lineAmt) != "undefined"){
        lineAmt = 1;
      }
      for (var i = 0; i < lineAmt; i++) {
        charactersOnVisibleLines += textBox.lines[i].characters.length;
      }
      if (charactersOnVisibleLines < textBox.characters.length) {
        return true;
      } else {
        return false;
      }
    } else if (textBox.characters.length > 0) {
      return true;
    }
  };


  function shrinkFont(textBox) {
    var totalCharCount = textBox.characters.length;
    var lineCount = textBox.lines.length;
    if (textBox.lines.length > 0) {
      var firstLineCharCount = textBox.lines[0].characters.length;
      if (isOverset(textBox, lineCount)) {
        var inc = defaultIncrement;
        while (isOverset(textBox, lineCount)) {
          textBox.textRange.characterAttributes.size -= inc;
        }
      }
    } else if (textBox.characters.length > 0) {
      var inc = defaultIncrement;
      while (isOverset(textBox, lineCount)) {
        textBox.textRange.characterAttributes.size -= inc;
      }
    }
  };


  function resetSize(textAreaBox) {
    var t = textAreaBox;
    if (t.contents != "") {
      // if (t.note != "") {
      //     t.textRange.characterAttributes.size = (t.note * 1);
      // }
      var size = readFontSizeFromTag(t);
      if(size != null){
        t.textRange.characterAttributes.size = size;
      }
    }
  };


  function removeTagsOnText(){
    var doc = app.activeDocument;
    for (var i = 0; i < doc.textFrames.length; i++) {
      try {
        doc.textFrames[i].tags.getByName(defaultSizeTagName).remove();
      } catch (e) {


      }
    }
  };


  function resetAllTextBoxes() {
    for (var i = 0; i < doc.textFrames.length; i++) {
      var t = doc.textFrames[i];
      if ((t.kind == TextType.AREATEXT || t.kind == TextType.PATHTEXT) && t.editable && !t.locked && !t.hidden) {
        resetSize(t);
      }
    };
  };


  function shrinkAllTextBoxes() {
    for (var i = 0; i < doc.textFrames.length; i++) {
      var t = doc.textFrames[i];
      if ((t.kind == TextType.AREATEXT || t.kind == TextType.PATHTEXT) && t.editable && !t.locked && !t.hidden) {
        shrinkFont(t);
      }
    };
  };
  if (app.documents.length > 0) {
    var doc = app.activeDocument;
    if (doc.dataSets.length > 0 && doc.activeDataSet == doc.dataSets[0]) {
      recordFontSize();
    }
    resetAllTextBoxes();
    shrinkAllTextBoxes();
    if (doc.dataSets.length > 0 && doc.activeDataSet == doc.dataSets[doc.dataSets.length - 1]) {
      removeTagsOnText();
    }
  }
  return true;
};
DealWithOversetText_SingleLine();



[EDIT: 10/5/2017] Now, this script uses Illustrator's scripting tags to record the original text size, leaving the note field alone. This means you can now use both Overset Text Single-Line with the Recolor.jsx recoloring script!

[EDIT: 9/5/2018] Ah there was a bug which ought to have made this script unusable until I fixed it just now. The github link to the version that should always be the latest is here: https://github.com/Silly-V/Adobe-Illustrator/blob/master/Dataset%20Processing/DealWithOversetText_SingleLine.jsx

Whoa! That was a mouthful!

Indeed, even this script to take care of overset text on a single line is more than trivial. To utilize scripting functionality for those creative professionals who do not code, or are short on time to toil with the quirks of Adobe Illustrator scripting, the best bet is to procure the talents of the established scripters on the Adobe scripting forum, or other domains such as freelancing websites or even LinkedIn.

Why?

With existence of robust 3rd party plugins for Illustrator which may already handle oversets and much, much more, it may come as a natural question as to why would one want to go through the trouble of getting a script and running it from an action while processing datasets. The reason to use the more cumbersome native Illustrator functionality depends on the individual needs of the user. For example, in situations where variable data used less often than is needed to justify the expense of purchasing one of those plugins. Getting a scripter to produce a snippet such as above is a mere fraction of the cost of an industrial-grade plugin. This approach would also apply in situations where a purchase of a plugin is anticipated, but the sales and the logistics are being hashed out, such as in acquisition and demo-ing to new customers. An organization may choose to test the waters in variable data for a new account rather than diving in head-first into a purchase which may not pan out - thus it's the more conservative approach to business.

I hope you enjoyed this read, and I encourage anyone curious enough, to test out this script in the way described above. It worked for me, and I would be ecstatic if this article helped any creative professionals get more insight into a variable data workflow in Adobe Illustrator.

Hi Lukas, the VariableImporter script can hand both point and area text. Deciding to use one over the other would be dependent on the layout and text considerations of the project. With data merge in Adobe InDesign, there is no “point text” it is all area text anyway.

Like
Reply

Is it best to use Area Text for variable data? Would have thought point text would be preffered but then the script needs to be different.

Like
Reply

Vasily, forgetting about automated "fixes" for the moment, what about creating a report text file or ai/pdf file listing which filenames contain overset text (similar to InDesign reporting the pages). As the "fix" may be best handled on a case by case basis, I personally would prefer to do this manually.

Like
Reply

Vasily Hall utilizing Variable Data in illustrator is something I have recently done a lot of exploration with. Overflow was something I always resolved with placing variable text within an un-warped Envelope Distort, but the result can end up being very stretched, or skewed type depending on the length of the variable data. This script you put together is another excellent solution. I cannot wait to try it out!

To view or add a comment, sign in

More articles by Vasily Hall

Others also viewed

Explore content categories