Search code examples
javascriptscriptingadobe-indesign

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!


Solution

  • 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';
            }
        } 
    }