javascriptadobe-indesignbasil.js

Custom word styling from csv into InDesign


I have a builded a text editor in javascript that takes keyboard-written-text as an input, and outputs the same paragraph, but with each word styled accordingly to how it was written. My text editor exports a CSV file, where each row is a word, and its specifc styling values covering: font size, word tracking, spacing between two words, and the color of the word.

The effect can be seen here

Now I want to import this csv file into InDesign using the basil.js library, so that I can create a text box with a paragraph of the words and the stylings located in the csv file.

The csv file can be seen here:

word,spacing,size,tracking,color
"Hello,",0,16,0,90
this,70,16,0.22,90
is,0,16,7,0
a,0,16,0,90
test,0,24,3.98,90
to,0,16,5.06,90
show,0,16,-1.56,90
what,42.84,16,-0.6,90
i,0,16,0,90
mean,0,16,-0.79,90

I’ve managed to import the csv, create a paragraph with each word, and make the font-size styling work for each work. But I can’t make the tracking property work. Also I dont really have an Idea how to create increasd space between two words in a paragraph through basil.js (In the texteditor it used left-padding css). Also I dont know how to change the color of each word.

Is this possible with basil.js?

My current code looks like this:

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


function draw(){

   b.clear(b.doc());

   //import csv file
   var data = b.CSV.decode( b.loadString("mycsv.csv"));

   //paragraph placeholder
   var paragraph = ""; 

   //parse to right data type,
   for (var i = 0; i < data.length; i++) {
     data[i].spacing = parseInt(data[i].spacing);
     data[i].size = parseInt(data[i].size);
     data[i].tracking = parseInt(data[i].tracking);
     data[i].color = parseInt(data[i].color);
     // data[i].word is already a string at it should

     //Add each word in the csv row to create a paragraph
     paragraph +=  data[i].word + " ";
  };

      //create a textframe element for the paragraph   
      var tf = b.text(paragraph, 36, 36, 500, b.height);
      var myWords = b.words(tf);

      // iterate through each word and  apply the specific styling for the
      specific word. 

      for(var i = 0; i < myWords.length; i++){  

             var size_ =  data[i].size; // font size
             var tracking_ = data[i].tracking; //word tracking
             var color_ = data[i].color;    // font color 
             var spacing_ = data[i].spacing;

            // this one works
            myWords[i].pointSize = size_; 

            //I'ld like to change tracking for each word - but this dosnt work
            myWords[i].tracking = tracking_; 

           //myWords[i].color = rgb(color_); - How can I apply a specific color to a specific word in the paragraph
           // myWords[i].word_spacing =  - I would like to increase the spacing between specific pairs of words. How can this be done?   

       }
}

b.go();

Solution

  • Tracking

    I think your tracking does actually work, but the values you get from your csv are way too small to be noticeable. Legal tracking values range from -1000 up to 10000, so I would multiply your values by 100 or by 1000 to see the effect.

    Color

    To change the color of a word, you need to change its fillColor property. To create a valid InDesign color you can make use of the basil function b.color(r, g, b). So to color a word in red, you could do

    myWords[i].fillColor = b.color(255, 0, 0);
    

    Word space

    To change the space between to words, you actually need to target the space string between two words and change its kerningValue property. To do that you can separate the text in all its characters using b.characters(text), like you already did with the words. Then you need to loop through the characters and see if it is a space and if so, you can change its kerning value.

    var chars = b.characters(tf);
    
    for (var i = 0; i < chars.length; i++) {
      if(chars[i].contents === " ") {
        chars[i].kerningValue = 400;
      }
    }