Skip to content

InDesign script to change the style of the first letter of a line

I am trying to write a script for InDesign to find the first character of every line of every paragraph, and change it to another color if it is a vowel. Since it is my very first effort in InDesign scripting, I downloaded Adobe’s Scripting Guide and managed so far to do the following:

createCharacterStyle();
main();


function main() {
    // I don't check if a document is open for now
    var myDocument = app.documents.item(0);
    var myStory = myDocument.stories.item(0);
    var noOfParas = myStory.paragraphs.length;
    for ( var theParaCounter = 0 ; theParaCounter < noOfParas ; theParaCounter++) {
        var currentParaLinesCount = myStory.paragraphs.item(theParaCounter).lines.length;

        for (var theLineCounter = 0 ; theLineCounter < currentParaLinesCount - 1 ; theLineCounter++ ) {
            var theCurrentLine = myStory.paragraphs.item(theParaCounter).lines.item(theLineCounter).contents;
            var theFirstChar = theCurrentLine.charAt(0);
            if ( theFirstChar == 'a' || theFirstChar == 'e' || theFirstChar == 'i' || 
                theFirstChar == 'o' || theFirstChar == 'u') {
                theFirstChar.appliedCharacterStyle = 'Highlighted';
            }
        }
    }

}


function createCharacterStyle() {
    var myDocument = app.documents.item(0);
    // Create the highlight color
    try {
        myColor = myDocument.colors.item('Red');
        myName = myColor.name;
    }
    catch ( myError ) {
        myColor = myDocument.colors.add({name:'Red', model:ColorModel.process, colorValue:[0,100,100,0]});
    }

    // Create a new Character Style
    try {
        myCharStyle = myDocument.characterStyles.item('Highlighted');
        myName = myCharStyle.name;
    }
    catch ( myError ) {
        myCharStyle = myDocument.characterStyles.add({name:'Highlighted'});
    }
    myCharStyle.fillColor = myColor;
    myCharStyle.underline = true;
}

At first I create the character style (red underline) and then I loop through the lines. The loop works, and finds the first character. The problem is that the style is never applied. Any help will be appreciated. Thanks!

Answer

As a quick fix you can replace the line:

theFirstChar.appliedCharacterStyle = 'Highlighted';

with:

myStory.paragraphs[theParaCounter].lines[theLineCounter].characters[0].appliedCharacterStyle = 'Highlighted';

The problem is the theFirstChar in your code is just a string, a text. It has no the property appliedCharacterStyle. You have to get the object character from the story/paragraph/line: stories[0].paragraphs[counter].lines[counter].character[0] if you want to apply a character style on it.

Note: the paragraphs.item(theParaCounter) is the same as paragraphs[theParaCounter], lines.item(theLineCounter) is the same as lines[theLineCounter].


Additionally the condition can be shortened:

if ('aeiou'.indexOf(theFirstChar.toLowerCase()) > -1) {

instead of:

if ( theFirstChar == 'a' || theFirstChar == 'e' || theFirstChar == 'i' || 
                theFirstChar == 'o' || theFirstChar == 'u') {

.toLowerCase() makes the condition case insensitive. If you need it.


The main() function can be boiled down to this:

function main() {
    var doc = app.activeDocument;
    var story = doc.stories[0];
    var paragraphs = story.paragraphs.everyItem().getElements();
    while (paragraphs.length) {
        var lines = paragraphs.shift().lines.everyItem().getElements();
        while (lines.length) {
            var character = lines.shift().characters[0];
            if ('aeiou'.indexOf(character.contents.toLowerCase()) < 0) continue;
            character.appliedCharacterStyle = 'Highlighted';
        }
    } 
}