1

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();
ambaamba
  • 71
  • 6

1 Answers1

0

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

Yuri Khristich
  • 13,448
  • 2
  • 8
  • 23
  • Wow! it seems like you made it! It's not working on my end, it says "var point1" is an error, would you know why? – ambaamba Mar 06 '22 at 17:26
  • I've check the code one more time. I see no errors. It should work. Probably there is something in your layout that need additional attentions. I can see if you share your .indd file. – Yuri Khristich Mar 06 '22 at 18:05
  • Here is the file : https://wetransfer.com/downloads/63787ad6df02346770b6595efca4ea0020220306181959/ae630dde9f131c0d5eca1db51bb4859220220306181959/3e4300 – ambaamba Mar 06 '22 at 18:22
  • I found this on the way : http://basiljs.ch/gallery/linking-words/ – ambaamba Mar 06 '22 at 18:23
  • I've added the `try/catch` statement. Try the updated code. It should work **within first page**. Let me know if it works. And if it needs to work with many pages/spreads. – Yuri Khristich Mar 06 '22 at 18:52
  • I've added a version of the code that can link styles on many pages (across spreads). – Yuri Khristich Mar 06 '22 at 19:25
  • Wow! It seems to be working on your end, on mine there are errors on line 12 " var points = [];" Indesign says it's an error :/. – ambaamba Mar 06 '22 at 19:52
  • Sorry. My bad. It was a typo. I just corrected it. – Yuri Khristich Mar 06 '22 at 20:14
  • Great! It works! Amazing! Thanks so much! – ambaamba Mar 06 '22 at 20:42
  • Well. I have learned something new as well. If it works could you accept the answer? – Yuri Khristich Mar 06 '22 at 21:16
  • Accetped! The next step, would be how to find out how to anchor the strokes or make them follow the text dynamically so that you can modify the layout making it elastic. But this is already so awesome! Thanks again! Would you have any references on how you made this script so I can learn from it? – ambaamba Mar 07 '22 at 08:16
  • How I made the script? And where I learned scripting? It's probably the hardest question. Basically there are three source: examples in the wild (google, stackoverflow, adobe official forums, etc, great source for example is here: http://kasyan.ho.ua/scripts_by_categories.html), official docs (includes not official https://www.indesignjs.de/extendscriptAPI/indesign-latest/) and my personal experience. So there is no simply answer. You have to google examples, modify them to solve your problems, read docs... and repeat it for years. And keep asking questions on stakoverflow of course – Yuri Khristich Mar 07 '22 at 12:17