Search code examples
javascriptadobe-indesign

Auto Place Text Frames Below Each Other (JavaScript)


I am trying to automate inDesign to create text frames from a JSON file, where every record shall be placed in a text frame, which is right below the foregoing record.

var tweets_json = '[ {"name":"record_1"}, {"name":"record_2"}, ... ]';  // I have not yet figured out how to import external JSON files, so tor testing this is my current way to go
var tweets = eval("(" + tweets_json + ")");

for ( var t = 0; t < tweets.length; t++ ) {
  var newTextFrame = page.textFrames.add();
  newTextFrame.textFramePreferences.autoSizingType = AutoSizingTypeEnum.HEIGHT_ONLY;
  var tweet = tweets[ t ];

  newTextFrame.parentStory.texts.item(0).applyParagraphStyle(styleContent, true);
  newTextFrame.geometricBounds = [y1,x1,y2,x2];   // Ignore values
  newTextFrame.contents = tweet.name;
}

I started inDesign scripting a few days ago and the documentation is hard to find the solution i am looking for, especially with my basic JavaScript knowledge, so any help is appreciated! Thank You!


Solution

  • It could be something like this:

    var doc = app.activeDocument;
    var page = doc.pages[0];
    
    // get JSON data (just as an example)
    var tweets_json = '[ {"name":"line1 line2"}, {"name":"line3"}, {"name":"line4, line5"}]';
    var tweets = eval("(" + tweets_json + ")");
    
    // set geometric bounds for the first text frame
    var x = 0, y = 0;                          // coordinates of top a left corner of the text frame
    var width = 15;                            // width of the text frame
    var min_heigth = 20;                       // minimal heigth of the text frame
    var bottom = min_heigth;                   // bottom edge of the text frame
    var bounds = [y, x, bottom, width];
    
    for (var t = 0; t < tweets.length; t++) {
        var tweet = tweets[t];
    
        // create the a new text frame and set its geometric bounds
        var newTextFrame = page.textFrames.add();
        newTextFrame.geometricBounds = bounds;
    
        // fill the box with a text and apply the style
        newTextFrame.contents = tweet.name;
        newTextFrame.parentStory.texts[0].applyParagraphStyle(styleContent, true);
    
        // resize the created text box with auto sizing
        newTextFrame.textFramePreferences.autoSizingReferencePoint = AutoSizingReferenceEnum.TOP_CENTER_POINT;
        newTextFrame.textFramePreferences.autoSizingType = AutoSizingTypeEnum.HEIGHT_ONLY;
    
        // set the new geometric bounds for the next text frame
        bounds = newTextFrame.geometricBounds; // get the bounds of the created text frame
        bottom = bounds[2];                    // get the new bottom edge
        bounds[0] = bottom;                    // set the top edge for the next text frame
        bounds[2] = bounds[2] + min_heigth;    // set the bottom edge for the next text frame
    }
    

    Result:

    enter image description here

    The code a bit verbose, for educational purposes. Actually it can be way shorter.