Welcome Dialog

Welcome to the Community!

We have a brand new look! Take a tour with us and explore the latest updates on Adobe Support Community.


How to find loose line and fix

Engaged ,
Aug 10, 2021 Aug 10, 2021

Copy link to clipboard

Copied

Hi,

 

How to find loose line text and fix it?

I have in mind below codes but it is lengthy process.

 

 

 

var document, textArray, counter, paragraph;
document = app.documents[0];
app.findGrepPreferences = null;
app.findGrepPreferences.findWhat = " ";
textArray = document.findGrep();
for (counter = -1; ++counter < textArray.length;) {
    if ((textArray[counter].endHorizontalOffset - textArray[counter].horizontalOffset) >= 4) {
        paragraph = textArray[counter].paragraphs[0];
        paragraph.tracking = paragraph.tracking - 5;
    }
}

 

 

 

 

SumitChaurasia_0-1628593838548.png

 

 

-Sumit
TOPICS
Scripting, Server developers

Views

89

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Adobe Community Professional , Aug 11, 2021 Aug 11, 2021
Sumit -- The problem with the paragraph you showed is that no amount of tracking or glyph scaling, letter spacing, or word spacing will fix it. I would enable the highlighting of H&J violations and check those reference sections visually. P.

Likes

Translate

Translate
Enthusiast ,
Aug 10, 2021 Aug 10, 2021

Copy link to clipboard

Copied

Hi Sumit, I think I can help with part of it. I've written a script that highlights lines in a story if they are less than 3 words on a line, and then colors the lines according to character count. The idea is that the worst lines in justified text are the ones with the lowest number of characters, but ignoring the last line. To test this script, make the text column narrow enough so that the script will be triggered, ie. so that there are some 3-or-less-words lines. You will also need to make two color swatches: "Bad Color" (red) and "Warning Color" (orange).

Once the script has found a short line you will have to experiment with what you want to do with it. For some functions you may need to process the lines in reverse order so that they aren't messed up. It isn't a trivial problem, because when you track a line in to fix one line, another newly-bad line may appear.

Anyway, maybe you can use some ideas from my script to put in yours.

- Mark

/* by m1b, here https://community.adobe.com/t5/indesign/how-to-find-loose-line-and-fix/m-p/12308622#M440598  */

function main() {

    // call the function, assuming a suitable item is selected, eg. a text frame
    var shortLines = storyLinesWithNWordsOrLess(
        app.selection[0], /* eg. a text frame */
        3, /* words or less */
        colorLineByCharacterCount /* just an example function */
    );

    // this function is just an example. It assigns
    // either "Bad Color" or "Warning Color" swatches
    // to a Line object according to character count
    // (you can use a more elaborate function yourself)
    function colorLineByCharacterCount(line) {
        var len = line.contents.length;
        if (len <= 10) {
            line.fillColor = "Bad Color";
        } else if (len <= 15) {
            line.fillColor = "Warning Color";
        }
    }

    // this is the function that goes through a story
    // and finds lines which are most likely to have
    // bad justification artefacts
    function storyLinesWithNWordsOrLess(item, n, fn) {
        var found = [];
        if (item && item.isValid) {

            // try and get the Story from whatever is selected
            if (!item.constructor.name != 'Story') {
                if (!item.hasOwnProperty('parentStory')) item = item.parent;
                if (item.hasOwnProperty('parentStory')) item = item.parentStory
            }
            if (item.constructor.name == "Story") {
                // start looking through the story
                var _paragraphs = item.paragraphs;
                for (var p = 0; p < _paragraphs.length; p++) {
                    var lines = _paragraphs[p].lines;
                    // note: the - 1 on the next line means
                    // ignore last line of paragraph
                    for (var i = 0; i < lines.length - 1; i++) {
                        if (lines[i].words.length <= n) {
                            found.push(lines[i]);
                            if (fn) {
                                fn(lines[i]);
                            }
                        }
                    }
                }
            }
        }
        return found;
    }


}

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Highlight Badly Justified Lines");

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Aug 10, 2021 Aug 10, 2021

Copy link to clipboard

Copied

Thank you @m1b for your efforts but I am writing script for auto pagination and it will run on indesign server.

-Sumit

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 10, 2021 Aug 10, 2021

Copy link to clipboard

Copied

Also, if you haven't already, check out this post for some good non-scripting info.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 10, 2021 Aug 10, 2021

Copy link to clipboard

Copied

I had another play around and made this variation on the script. This time the function supplied tightens the tracking until either the maximum is exceeded, or a new word squeezes in to the line. Edit the maxTracking value to suit your preference.

 

Please bear in mind that if this is all you want to do with the script, it is much better to adjust this in the Justification settings of the paragraph style. Just put a negative minium letterspacing. Using the script, I think you will be hard-pressed to improve on the general composing capabilities of Indesign, but there's definitely room for a script to cater to special, specific typesetting needs. See what you think.

Screen Shot 2021-08-11 at 10.19.03 am.png

/* by m1b, here: https://community.adobe.com/t5/indesign/how-to-find-loose-line-and-fix/td-p/12308622 */


function main() {

    // call the main function
    applyFunctionToLinesOfStory(app.selection[0], tightenTracking, "$ID/HL Single Optyca", true);

    // A function to plug in to applyFunctionToLinesOfStory:
    // This function progressively tightens letterspace
    // until either the maxTracking is reached, or
    // the next word now fits on the line
    function tightenTracking(para, line, index) {
        // para is the paragraph containing linel;
        // index is the line number within para.
        var maxTracking = -20; /* set this to the max suitable in your case */

        var startTracking = line.tracking,
            w = line.words.length,
            t = startTracking;

        while (
            line.tracking > startTracking + maxTracking
            && line.words.length == w
        ) {
            t -= 1;
            line.tracking = t;
            para.recompose();
            line = para.lines[index];
        }
        // depending on whether it managed to squeeze in an extra word,
        // apply new tracking to whole line (currently last word isn't tracked)
        // or reset tracking to original value
        line.tracking = line.words.length > w ? t : startTracking;
    }

    // for fun: a function that increases the tracking of a line from left to right
    function explodeTracking(para, line, index) {
        // para is the paragraph containing linel;
        // index is the line number within para.
        var maxTracking = 200; /* set this to the max suitable in your case */

        var startTracking = line.tracking,
            w = line.words.length,
            t = startTracking;

        while (
            line.tracking > startTracking + maxTracking
            && line.words.length == w
        ) {
            t -= 1;
            line.tracking = t;
            para.recompose();
            line = para.lines[index];
        }
        // depending on whether it managed to squeeze in an extra word,
        // apply new tracking to whole line (currently last word isn't tracked)
        // or reset tracking to original value
        line.tracking = line.words.length > w ? t : startTracking;
    }


    // this function just iterates over every paragraph and line
    // in the story and calls the function once per line
    function applyFunctionToLinesOfStory(item, fn, composerKey, ignoreLastLineOfParagraph) {
        var story = getItemStory(item);
        if (story) {
            var paragraphs = item.paragraphs;
            for (var p = 0; p < paragraphs.length; p++) {
                if (composerKey) {
                    paragraphs[p].composer = composerKey;
                    paragraphs[p].recompose();
                }
                var index = 0,
                    lines = paragraphs[p].lines,
                    numberOfLines = paragraphs[p].lines.length + (ignoreLastLineOfParagraph == true ? -1 : 0);
                while (index < numberOfLines) {
                    fn(paragraphs[p], lines[index], index);
                    index++;
                }
            }
        }
    }


    function getItemStory(item) {
        var story;
        if (item && item.isValid) {
            // try and get the Story from whatever is selected
            if (!item.constructor.name != 'Story') {
                if (!item.hasOwnProperty('parentStory')) item = item.parent;
                if (item.hasOwnProperty('parentStory')) item = item.parentStory
            }
            if (item.constructor.name == "Story") {
                story = item;
            }
        }
        return story;
    }



} // end main

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Adjust Story Tracking");

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Aug 12, 2021 Aug 12, 2021

Copy link to clipboard

Copied

LATEST

Thank you @m1b .

-Sumit

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Aug 11, 2021 Aug 11, 2021

Copy link to clipboard

Copied

Sumit -- The problem with the paragraph you showed is that no amount of tracking or glyph scaling, letter spacing, or word spacing will fix it. I would enable the highlighting of H&J violations and check those reference sections visually.

P.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Aug 12, 2021 Aug 12, 2021

Copy link to clipboard

Copied

Thank you @Peter Kahrel .

-Sumit

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines