Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
0

Soft return at end of line

Enthusiast ,
Mar 28, 2025 Mar 28, 2025

Hi,

I have multiple textframes threaded. Page as been setup properly as I wanted. I want to put a soft return at the end of line. If there is a new paragraph change, it will ignore that. I have marked it with red circles, the places where I want soft-returns. How to do this with a script. I want to target a particular para style.

TOPICS
How to , Scripting
249
Translate
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

Community Expert , Mar 28, 2025 Mar 28, 2025

Hi @Bedazzled532, try this script. You need to set the name of the target paragraph style in the settings object. Let me know if it works for you.

- Mark

 

/**
 * @file Force Line Breaks.js
 *
 * Adds a line break at the end of every line of text
 * of selected items or, optionally, the whole document.
 *
 * Notes:
 *   - only processes text in the target paragraph style
 *     (edit the settings object below).
 *   - makes a valiant attempt at hardening justified text,
 *     but only handles l
...
Translate
Community Expert ,
Mar 28, 2025 Mar 28, 2025

Hi @Bedazzled532, try this script. You need to set the name of the target paragraph style in the settings object. Let me know if it works for you.

- Mark

 

/**
 * @file Force Line Breaks.js
 *
 * Adds a line break at the end of every line of text
 * of selected items or, optionally, the whole document.
 *
 * Notes:
 *   - only processes text in the target paragraph style
 *     (edit the settings object below).
 *   - makes a valiant attempt at hardening justified text,
 *     but only handles left-justified text.
 *
 * @author m1b
 * @version 2025-03-29
 * @discussion https://community.adobe.com/t5/indesign-discussions/soft-return-at-end-of-line/m-p/15236469
 */
function main() {

    var settings = {

        /* only paragraphs in this style will be processed (set to `undefined` to disable filtering) */
        paragraphStyleName: 'My Best Paragraph Style',

    };

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    const EXPAND_JUSTIFIED_TEXT_FRAME = 3,
        SQUASH_AMOUNT = -100;

    var doc = app.activeDocument,
        stories = getSelectedStories(doc.selection);

    if (0 === stories.length) {

        // check with user
        if (!confirm('Do you want to apply to whole document?'))
            return;

        // no selected stories, so get every story from document
        stories = doc.stories.everyItem().getElements();

    }

    var spaceCharacter = /\s/,
        linefeeds = /[\n\r]/;

    // we'll slightly expand the text frames later on
    var framesToAdjust = {};

    storyLoop:
    for (var i = stories.length - 1; i >= 0; i--) {

        var paragraphs = stories[i].paragraphs.everyItem().getElements();

        paragraphsLoop:
        for (var j = paragraphs.length - 1; j >= 0; j--) {

            var paragraph = paragraphs[j];

            if (
                undefined != settings.paragraphStyleName
                && settings.paragraphStyleName !== paragraph.appliedParagraphStyle.name
            )
                continue paragraphsLoop;

            var isJustified = (Justification.LEFT_JUSTIFIED === paragraph.justification);

            var lines = paragraph.lines.everyItem().getElements(),

                // store character positions
                positions = [];

            linesLoop:
            for (var k = lines.length - 1; k >= 0; k--) {

                var line = lines[k],
                    suffix;

                if (0 === line.parentTextFrames.length)
                    continue linesLoop;

                if (
                    linefeeds.test(line.characters[-1].contents)
                    || SpecialCharacters.FORCED_LINE_BREAK === line.characters[-1].contents
                    || !line.parentStory.characters[line.characters[-1].index + 1].isValid
                )
                    // last line in paragraph or story
                    continue linesLoop;

                suffix = !spaceCharacter.test(line.characters[-1].contents)
                    ? suffix = '-\n' // hyphenated word
                    : suffix = '\n';

                if (isJustified)
                    // store positions for later
                    positions.unshift(line.characters.everyItem().horizontalOffset);

                // force line break
                line.insertionPoints[-1].contents = suffix;

            }

            if (!isJustified)
                continue paragraphsLoop;

            // now we harden the justification, line by line

            // start by aligning left (let me know if you need RTL)
            paragraph.justification = Justification.LEFT_ALIGN;

            // collect all the parent text frames
            for (var f = 0; f < paragraph.parentTextFrames.length; f++) {

                var tf = paragraph.parentTextFrames[f];

                if (!framesToAdjust[tf.id])
                    framesToAdjust[tf.id] = tf;

            }

            // temporarily squash text up a bit to stop unwanted line breaking
            squashLoop:
            for (var k = paragraph.lines.length - 2; k >= 0; k--) {

                if (
                    !paragraph.lines[k].isValid
                    || 0 === paragraph.lines[k].parentTextFrames.length
                )
                    continue squashLoop;

                paragraph.lines[k].characters.itemByRange(
                    paragraph.lines[k].characters[0],
                    paragraph.lines[k].characters[-4]
                ).tracking = SQUASH_AMOUNT;

            }

            // refresh the lines reference
            lines = paragraph.lines.everyItem().getElements();

            linePositionsLoop:
            for (var l = 0; l < lines.length; l++) {

                var linePositions = positions[l];

                if (!linePositions)
                    continue linePositionsLoop;

                var len = Math.min(lines[l].characters.length, linePositions.length);

                charactersLoop:
                for (var c = 1; c < len; c++) {

                    var ch0 = paragraph.lines[l].characters[c - 1],
                        ch1 = paragraph.lines[l].characters[c],
                        pos = ch1.horizontalOffset,
                        target = linePositions[c];

                    if (undefined == target)
                        continue charactersLoop;

                    ch0.tracking += (target - pos) * (1000 / ch0.pointSize);

                }

            }

        }

    }

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Force Line Breaks');

/**
* Returns the document's selected stories.
* @author m1b
* @version 2025-03-26
* @param {Array<PageItem>} items - the items from which to gather stories.
* @returns {Array<Story>}
*/
function getSelectedStories(items) {

    var stories = [],
        unique = {};

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

        if ('TextFrame' === items[i].constructor.name) {

            if (unique[items[i].parentStory.id])
                // already collected this story
                continue;

            unique[items[i].parentStory.id] = true;
            items[i] = items[i].parentStory;
        }

        if ('function' === typeof items[i].changeGrep)
            stories.push(items[i]);

    }

    return stories;

};

Edit 2025-03-29: added handling of left-justified text; it will "harden" the justification using custom tracking and the lines are fixed, even if you expand the text frame. Like this:

demo.gifexpand image

Translate
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 ,
Mar 28, 2025 Mar 28, 2025
@m1b thanks. I'll chk once i m infront of my computer.
Translate
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 ,
Mar 28, 2025 Mar 28, 2025

@m1b Thanks it worked!!

Translate
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
Community Expert ,
Mar 28, 2025 Mar 28, 2025

@Bedazzled532 I notice in your example screenshot you have justified text. Just for fun I've updated the script above to handle left-justified text so that the frame can be expanded without interfering with the spacing.

- Mark

Translate
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 ,
Mar 29, 2025 Mar 29, 2025

Thanks a ton!!

Translate
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
Community Expert ,
Mar 29, 2025 Mar 29, 2025
LATEST

You're welcome. It might need some changes to work with Arabic or other RTL text though.

Translate
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
Community Expert ,
Mar 28, 2025 Mar 28, 2025

Whalt purpose should those soft return have?

Translate
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
Community Expert ,
Mar 28, 2025 Mar 28, 2025
quote

Whalt purpose should those soft return have?


By Willi Adelberger

 

It's a mockup - but it probably has something to do with the other thread - and changing Word spacing. 

 

Translate
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 ,
Mar 28, 2025 Mar 28, 2025
It will be a same paragraph and yet in new line. That's why soft return.
Translate
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
Community Expert ,
Mar 28, 2025 Mar 28, 2025
quote
It will be a same paragraph and yet in new line. That's why soft return.
By Bedazzled532

 

Yes, but normally, you don't have to do this - only in some special circumstances - that's what @Willi Adelberger would like to know - your special reason.

 

Translate
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
Community Expert ,
Mar 28, 2025 Mar 28, 2025

But without these soft returns you would get the same result with less work. When the lne ends the text goes on on the next line in the same paragraph.,

Translate
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 ,
Mar 28, 2025 Mar 28, 2025

@Willi Adelberger Actually I want to apply this on a placeholder threaded frame. It actually has 3 setions. First threaded frame where I want to apply this is in Arabic Language. All arabic threaded together. Second section is the translations threaded together and 3rd section is transliteration frames threaded together. I want to use different arabic fonts in section 1 and also I want to hard code the breaks. This will prevent me from error if any arabic word goes to next frame, I can identify it easily.

Translate
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
Community Expert ,
Mar 28, 2025 Mar 28, 2025

@Bedazzled532 

 

This one-liner does pretty much what you need - but as it modifies ALL text lines - it requires some cleaning:

 

app.activeDocument.stories.everyItem().lines.everyItem().insertionPoints[-1].contents = "\n";

app.findTextPreferences = NothingEnum.nothing; 
app.changeTextPreferences = NothingEnum.nothing; 
app.findTextPreferences.findWhat = "\r\n"; 
app.changeTextPreferences.changeTo = "\r"; 
app.activeDocument.changeText();  

RobertatIDTasker_1-1743161700978.pngexpand image

Translate
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 ,
Mar 28, 2025 Mar 28, 2025

@Robert at ID-Tasker Thanks it worked.

Translate
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
Community Expert ,
Mar 28, 2025 Mar 28, 2025

@Bedazzled532

 

Great 😉 but I'll have to "fix" it 😉 as you need to only modify a specific ParaStyle - piece of cake - but I'm not at home right now.

 

Translate
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