Search code examples
javascriptadobe-indesignextendscriptbasil.js

How to link chacter styles with strokes in InDesign with Basil.js


enter image description here

I would like to link character styles with a stroke but I don't know how to begin. I have this that just draws a random line, but I would like the line to link all the character styles :

#includepath "~/Documents/;%USERPROFILE%Documents";
#include "basiljs/bundle/basil.js";

function draw() {

    var selItems = b.selections(); // get all selected items
    
    var textFrame1 = selItems[0]; // the first textframe
    var textFrame2 = selItems[1]; // the second textframe
    
    var words1 = b.words(textFrame1);
    var words2 = b.words(textFrame2);        
    
    b.layer("generatedLines"); // get or create this layer and set it as the active one
    b.strokeWeight(1); // we like hairs
    
    for(var i = 0; i < words1.length; i++){ // for each word

      var w1 = words1[i]; // current word from the first textframe

      // nested for-loop, connect each word with all other words of other textframe
      for(var j = 0; j < words2.length; j++){ 

        var w2 = words2[j]; // the current word from the second textframe
    
        b.line(
            // add half of the width and height to make sure the lines are centered
            b.bounds(w1).left + b.bounds(w1).width / 2, 
            b.bounds(w1).top + b.bounds(w1).height / 2, 
            b.bounds(w2).left + b.bounds(w2).width / 2, 
            b.bounds(w2).top + b.bounds(w2).height / 2
        );
          
      }
        
    }
  
}

b.go();

Solution

  • Here is example how you can draw the lines for the texts on the first page of your document:

    // find all the texts with character style 'My Style'
    app.findGrepPreferences = NothingEnum.nothing;
    app.findGrepPreferences.findWhat = '.+';
    app.findGrepPreferences.appliedCharacterStyle = 'My Style';
    var texts = app.activeDocument.findGrep();
    
    // get coordinates of start and end points of the texts
    var points = [];
    while (texts.length) {
        try {
            var point1 = {
                'x': text.insertionPoints.firstItem().horizontalOffset,
                'y': text.insertionPoints.firstItem().baseline
            }
            var point2 = {
                'x': text.insertionPoints.lastItem().endHorizontalOffset,
                'y': text.insertionPoints.lastItem().baseline
            }
            points.push(point1, point2);
        } catch(e) {}
    }
    
    // remove first and end points
    points.shift();
    points.pop();
    
    // draw lines on first page
    var page = app.activeDocument.pages[0];
    while(points.length) {
        var line = page.graphicLines.add();
        var point1 = points.shift();
        var point2 = points.shift();
        line.paths[0].pathPoints[0].anchor = [point1.x, point1.y];
        line.paths[0].pathPoints[1].anchor = [point2.x, point2.y];
        line.strokeWeight = 1;
    }
    

    enter image description here

    It doesn't use basiljs library though.

    If you need to handle many pages, I think it can be done as well. But it will require more coding.

    Update

    Here is a version of the script that handles many pages:

    app.activeDocument.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN;
    
    app.findGrepPreferences = NothingEnum.nothing;
    app.findGrepPreferences.findWhat = '.+';
    app.findGrepPreferences.appliedCharacterStyle = 'My Style';
    var texts = app.activeDocument.findGrep();
    
    // get coordinates of start and end points of the texts
    var points = [];
    while (texts.length) {
        var text = texts.shift();
        try {
            var start_point = {
                'page': text.parentTextFrames[0].parentPage.name,
                'spread': text.parentTextFrames[0].parentPage.parent.index,
                'x': text.insertionPoints.firstItem().horizontalOffset + .5,
                'y': text.insertionPoints.firstItem().baseline - 13
            }
            var end_point = {
                'page': text.parentTextFrames[0].parentPage.name,
                'spread': text.parentTextFrames[0].parentPage.parent.index,
                'x': text.insertionPoints.lastItem().endHorizontalOffset - .5,
                'y': text.insertionPoints.lastItem().baseline + 1
            }
            points.push(start_point, end_point);
        } catch(e) {}
    }
    
    // remove first and end points
    points.shift();
    points.pop();
    
    // draw lines on first page
    while(points.length) {
        var start_point = points.shift();
        var end_point = points.shift();
        if (start_point.spread == end_point.spread) {
            var page = app.activeDocument.pages[start_point.page-1]
            var line = page.graphicLines.add();
            line.paths[0].pathPoints[0].anchor = [start_point.x, start_point.y];
            line.paths[0].pathPoints[1].anchor = [end_point.x, end_point.y];
            line.strokeWeight = 1;
        }
    }
    

    enter image description here