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;
}
}
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.
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");
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.
Copy link to clipboard
Copied
Also, if you haven't already, check out this post for some good non-scripting info.
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.
/* 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");
Copy link to clipboard
Copied
Thank you @m1b .
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.
Copy link to clipboard
Copied
Thank you @Peter Kahrel .