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

Auto subheader style script help request

Contributor ,
Jul 06, 2024 Jul 06, 2024

I have made a script which a user can design a range of consecutive subheaders and the script will apply the styles for all instances of subheaders 

 

see screenshots for example 

 

As you can see there are 4 subheaders each with text settiings and then other entries with similar subheaders - rather than having to eyedrop all of them you can run the script and all subheaders will be styles - see the second screenshot 

 

SmythWharf_0-1720291198411.pngexpand image

 

SmythWharf_1-1720291279803.pngexpand image

 

As you can see each subhead has adopted the respective subhead.

 

The problem I have is if each subheader has a return after it the script does not see them as consecutive. 

Screenshot below shows the issue 

The same subheads but now with returns 

SmythWharf_2-1720291422882.pngexpand image

 

as you can see once the script has been run they all adopt the frust subheader 

SmythWharf_3-1720291616830.pngexpand image

Any advice on this would be most appreciated! 

 

This should be a useful script when complete and it feels like it is the final hurdle.

 

Many thanks 

 

Smyth

 

function findAndApplyTextSettings() {
    // Ensure that there's an active document open
    if (app.documents.length > 0) {
        var doc = app.activeDocument;
        var selection = app.selection;

        // Ensure there's a valid selection
        if (selection.length > 0 && (selection[0] instanceof TextFrame || selection[0].hasOwnProperty('insertionPoints'))) {
            var selectedTextFrames = [];
            if (selection[0] instanceof TextFrame) {
                selectedTextFrames.push(selection[0]);
            } else if (selection[0].hasOwnProperty('insertionPoints')) {
                selectedTextFrames.push(selection[0].parentTextFrames[0]);
            }

            var foundTargetParagraph = false;
            var targetTextSettingsList = [];

            // Iterate over each selected text frame
            for (var j = 0; j < selectedTextFrames.length; j++) {
                var paragraphs = selectedTextFrames[j].parentStory.paragraphs.everyItem().getElements();

                // Find the first suitable paragraph and all consecutive ones
                for (var i = 0; i < paragraphs.length; i++) {
                    var consecutiveParagraphs = [];
                    var allConsecutiveSettings = [];

                    for (var k = i; k < paragraphs.length; k++) {
                        var para = paragraphs[k];
                        var words = para.words.length;
                        var paragraphText = para.contents;

                        // Check criteria: 1 to 10 words and no full stop
                        if (words > 0 && words <= 10 && paragraphText.indexOf('.') === -1) {
                            consecutiveParagraphs.push(para);
                            allConsecutiveSettings.push(getTextSettings(para));
                        } else {
                            break; // Stop checking if the paragraph doesn't meet criteria
                        }
                    }

                    if (consecutiveParagraphs.length > 0) {
                        targetTextSettingsList = allConsecutiveSettings;
                        foundTargetParagraph = true;
                        break; // Exit loop once found
                    }
                }

                if (foundTargetParagraph) {
                    // Apply text settings to similar paragraphs within an undoable action
                    app.doScript(function() {
                        var currentConsecutiveIndex = 0;
                        for (var i = 0; i < paragraphs.length; i++) {
                            var para = paragraphs[i];
                            var words = para.words.length;
                            var paragraphText = para.contents;

                            // Apply text settings if it's a similar paragraph
                            if (words > 0 && words <= 10 && paragraphText.indexOf('.') === -1) {
                                if (currentConsecutiveIndex < targetTextSettingsList.length) {
                                    applyTextSettings(para, targetTextSettingsList[currentConsecutiveIndex]);
                                    currentConsecutiveIndex++;
                                }
                            } else {
                                currentConsecutiveIndex = 0; // Reset if paragraph does not meet criteria
                            }
                        }
                    }, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Apply Text Settings");
                } else {
                    alert("No suitable paragraphs found in the selected text frame.");
                }
            }
        } else {
            alert("Please select a text frame or place the cursor inside a text frame.");
        }
    } else {
        alert("No active document found.");
    }
}

// Function to get text settings from a paragraph
function getTextSettings(paragraph) {
    return {
        appliedFont: paragraph.appliedFont,
        pointSize: paragraph.pointSize,
        fillColor: paragraph.fillColor,
        fillTint: paragraph.fillTint,
        justification: paragraph.justification,
        leading: paragraph.leading,
        firstLineIndent: paragraph.firstLineIndent,
        baselineShift: paragraph.baselineShift,
        tracking: paragraph.tracking,
        capitalization: getCapitalization(paragraph.capitalization),
        alignToBaseline: paragraph.alignToBaseline,
        ruleAbove: paragraph.ruleAbove === true,
        ruleBelow: paragraph.ruleBelow === true,
        ruleAboveColor: paragraph.ruleAboveColor,
        ruleAboveGapColor: paragraph.ruleAboveGapColor,
        ruleAboveGapOverprint: paragraph.ruleAboveGapOverprint === true,
        ruleAboveGapTint: paragraph.ruleAboveGapTint,
        ruleAboveLeftIndent: paragraph.ruleAboveLeftIndent,
        ruleAboveLineWeight: paragraph.ruleAboveLineWeight,
        ruleAboveOffset: paragraph.ruleAboveOffset,
        ruleAboveOverprint: paragraph.ruleAboveOverprint === true,
        ruleAboveRightIndent: paragraph.ruleAboveRightIndent,
        ruleAboveTint: paragraph.ruleAboveTint,
        ruleAboveType: paragraph.ruleAboveType,
        ruleAboveWidth: paragraph.ruleAboveWidth,
        ruleBelowColor: paragraph.ruleBelowColor,
        ruleBelowGapColor: paragraph.ruleBelowGapColor,
        ruleBelowGapOverprint: paragraph.ruleBelowGapOverprint === true,
        ruleBelowGapTint: paragraph.ruleBelowGapTint,
        ruleBelowLeftIndent: paragraph.ruleBelowLeftIndent,
        ruleBelowLineWeight: paragraph.ruleBelowLineWeight,
        ruleBelowOffset: paragraph.ruleBelowOffset,
        ruleBelowOverprint: paragraph.ruleBelowOverprint === true,
        ruleBelowRightIndent: paragraph.ruleBelowRightIndent,
        ruleBelowTint: paragraph.ruleBelowTint,
        ruleBelowType: paragraph.ruleBelowType,
        ruleBelowWidth: paragraph.ruleBelowWidth
        // Add more text attributes as needed
    };
}

// Function to apply text settings to a paragraph
function applyTextSettings(paragraph, settings) {
    paragraph.appliedFont = settings.appliedFont;
    paragraph.pointSize = settings.pointSize;
    paragraph.fillColor = settings.fillColor;
    paragraph.fillTint = settings.fillTint;
    paragraph.leading = settings.leading;
    paragraph.firstLineIndent = settings.firstLineIndent;
    paragraph.justification = settings.justification;
    paragraph.ruleAbove = settings.ruleAbove;
    paragraph.ruleAboveColor = settings.ruleAboveColor;
    paragraph.ruleAboveGapColor = settings.ruleAboveGapColor;
    paragraph.ruleAboveGapOverprint = settings.ruleAboveGapOverprint;
    paragraph.ruleAboveGapTint = settings.ruleAboveGapTint;
    paragraph.ruleAboveLeftIndent = settings.ruleAboveLeftIndent;
    paragraph.ruleAboveLineWeight = settings.ruleAboveLineWeight;
    paragraph.ruleAboveOffset = settings.ruleAboveOffset;
    paragraph.ruleAboveOverprint = settings.ruleAboveOverprint;
    paragraph.ruleAboveRightIndent = settings.ruleAboveRightIndent;
    paragraph.ruleAboveTint = settings.ruleAboveTint;
    paragraph.ruleAboveType = settings.ruleAboveType;
    paragraph.ruleAboveWidth = settings.ruleAboveWidth;
    paragraph.ruleBelow = settings.ruleBelow;
    paragraph.ruleBelowColor = settings.ruleBelowColor;
    paragraph.ruleBelowGapColor = settings.ruleBelowGapColor;
    paragraph.ruleBelowGapOverprint = settings.ruleBelowGapOverprint;
    paragraph.ruleBelowGapTint = settings.ruleBelowGapTint;
    paragraph.ruleBelowLeftIndent = settings.ruleBelowLeftIndent;
    paragraph.ruleBelowLineWeight = settings.ruleBelowLineWeight;
    paragraph.ruleBelowOffset = settings.ruleBelowOffset;
    paragraph.ruleBelowOverprint = settings.ruleBelowOverprint;
    paragraph.ruleBelowRightIndent = settings.ruleBelowRightIndent;
    paragraph.ruleBelowTint = settings.ruleBelowTint;
    paragraph.ruleBelowType = settings.ruleBelowType;
    paragraph.ruleBelowWidth = settings.ruleBelowWidth;

    // Apply word-level settings to each word in the paragraph
    var paraWords = paragraph.words.everyItem().getElements();
    for (var k = 0; k < paraWords.length; k++) {
        paraWords[k].appliedFont = settings.appliedFont;
        paraWords[k].pointSize = settings.pointSize;
        paraWords[k].fillColor = settings.fillColor;
        paraWords[k].fillTint = settings.fillTint;
        paraWords[k].leading = settings.leading;
        paraWords[k].baselineShift = settings.baselineShift;
        paraWords[k].tracking = settings.tracking;
        paraWords[k].capitalization = settings.capitalization;
        paraWords[k].alignToBaseline = settings.alignToBaseline;
        // Apply other text attributes as needed
    }
}

// Helper function to map capitalization constants to InDesign values
function getCapitalization(constantValue) {
    switch (constantValue) {
        case 1634493296:
            return Capitalization.ALL_CAPS;
        case 1664250723:
            return Capitalization.CAP_TO_SMALL_CAP;
        case 1852797549:
            return Capitalization.NORMAL;
        case 1936548720:
            return Capitalization.SMALL_CAPS;
        case 1919251315:
            return true; // For ruleAbove
        case 1919251316:
            return true; // For ruleBelow
        default:
            return Capitalization.NORMAL; // Default to normal capitalization
    }
}

// Run the function
findAndApplyTextSettings();

 

 

 

 

 

TOPICS
How to , Scripting , SDK , UXP Scripting
613
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 Beginner , Jul 13, 2024 Jul 13, 2024
quote

I have made a script which a user can design a range of consecutive subheaders and the script will apply the styles for all instances of subheaders 

 

see screenshots for example 

 

As you can see there are 4 subheaders each with text settiings and then other entries with similar subheaders - rather than having to eyedrop all of them you can run the script and all subheaders will be styles - see the second screenshot 

 

SmythWharf_0-1720291198411.pngexpand image

 

SmythWharf_1-1720291279803.pngexpand image

 

As you can see each subhead has adopted the respective subhead.

 

The problem I ha

...
Translate
Community Beginner ,
Jul 13, 2024 Jul 13, 2024
quote

I have made a script which a user can design a range of consecutive subheaders and the script will apply the styles for all instances of subheaders 

 

see screenshots for example 

 

As you can see there are 4 subheaders each with text settiings and then other entries with similar subheaders - rather than having to eyedrop all of them you can run the script and all subheaders will be styles - see the second screenshot 

 

SmythWharf_0-1720291198411.pngexpand image

 

SmythWharf_1-1720291279803.pngexpand image

 

As you can see each subhead has adopted the respective subhead.

 

The problem I have is if each subheader has a return after it the script does not see them as consecutive. 

Screenshot below shows the issue 

The same subheads but now with returns 

SmythWharf_2-1720291422882.pngexpand image

 

as you can see once the script has been run they all adopt the frust subheader 

SmythWharf_3-1720291616830.pngexpand image

Any advice on this would be most appreciated! 

 

This should be a useful script when complete and it feels like it is the final hurdle.

 

Many thanks 

 

Smyth

By SmythWharfADPWorkforceNow

Hello, @SmythWharfADPWorkforceNow 

 

It’s great to see you working on this script to streamline subheader styling. Let’s tackle that final hurdle together!

 

From your description and the screenshots, it seems like you’ve made significant progress. However, handling consecutive subheaders with returns can indeed be tricky. I’ll provide some guidance to address this issue.

Identifying Consecutive Subheaders:
You’ve already defined the criteria for identifying subheaders: at least two hard enter returns (paragraph breaks), followed by a short string (up to 6 words) without a full stop.
The challenge lies in ensuring that these subheaders are recognized even when they have returns after them.
Script Enhancement:
To handle consecutive subheaders with returns, consider modifying your script as follows:
Instead of looking for a single instance of the word “test” (as in your initial working script), look for the subheader pattern.
Use regular expressions (regex) to match the specific criteria for subheaders.
Iterate through the paragraphs and apply the desired text settings to each identified subheader.
Sample Approach:
Here’s a high-level idea of how your script could be enhanced:
Define a regex pattern that matches your subheader criteria (e.g., two or more hard returns followed by a short string without a full stop).
Loop through the paragraphs in the text frame.
For each paragraph, check if it matches the subheader pattern.
If it does, apply the desired text settings to that paragraph.
Example (Pseudo-Code):

// Define your regex pattern for subheaders
var subheaderRegex = /(\r\n){2,}[^.]{1,6}$/;

// Loop through paragraphs
for (var i = 0; i < paragraphs.length; i++) {
var para = paragraphs[i];
if (subheaderRegex.test(para.contents)) {
// Apply text settings to identified subheader
// ...
}
}

 

Testing and Refining:
Test this enhanced script with various scenarios (including subheaders with returns) to ensure it correctly identifies and styles them.
Adjust the regex pattern or other conditions as needed based on real-world examples.

 

Remember, scripting is like solving a puzzle—sometimes it takes a few iterations to get it just right.

 

I hope this info is helpful to you.

 

Best Regard,
Gregory Chavez

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
Contributor ,
Jul 29, 2024 Jul 29, 2024

Hello, 

 

managed to get a fix quite some time ago 

 

try this 

 

 

// Main function to find and apply text settings to consecutive paragraphs
function findAndApplyTextSettings() {
    // Check if there's an active document open
    if (app.documents.length > 0) {
        var doc = app.activeDocument;
        var selection = app.selection;

        // Ensure there's a valid selection
        if (selection.length > 0 && (selection[0] instanceof TextFrame || selection[0].hasOwnProperty('insertionPoints'))) {
            var selectedTextFrames = [];
            if (selection[0] instanceof TextFrame) {
                selectedTextFrames.push(selection[0]);
            } else if (selection[0].hasOwnProperty('insertionPoints')) {
                selectedTextFrames.push(selection[0].parentTextFrames[0]);
            }

            var foundTargetParagraph = false;
            var targetTextSettingsList = [];

            // Iterate over each selected text frame
            for (var j = 0; j < selectedTextFrames.length; j++) {
                var textFrame = selectedTextFrames[j];
                var paragraphs = textFrame.parentStory.paragraphs.everyItem().getElements();

                var consecutiveCount = 0;
                var consecutiveParagraphs = [];
                var allConsecutiveSettings = [];

                // Loop through each paragraph
                for (var i = 0; i < paragraphs.length; i++) {
                    var paragraph = paragraphs[i];

                    // Check if the paragraph is empty
                    if (paragraph.contents.replace(/^\s+|\s+$/g, '').length === 0) {
                        continue; // Skip empty paragraphs without resetting the count
                    }

                    // Check if the paragraph meets the criteria
                    if (isValidParagraph(paragraph)) {
                        consecutiveCount++;
                        consecutiveParagraphs.push(paragraph);
                        allConsecutiveSettings.push(getTextSettings(paragraph));
                    } else {
                        // If consecutiveCount is greater than 0, process the consecutive paragraphs found
                        if (consecutiveCount > 0) {
                            if (!foundTargetParagraph) {
                                targetTextSettingsList = allConsecutiveSettings;
                                foundTargetParagraph = true;
                            }
                            applyTextSettingsToConsecutive(consecutiveParagraphs, targetTextSettingsList);
                            consecutiveCount = 0; // Reset consecutive count
                            consecutiveParagraphs = [];
                            allConsecutiveSettings = [];
                        } else {
                            consecutiveCount = 0; // Reset consecutive count
                            consecutiveParagraphs = [];
                            allConsecutiveSettings = [];
                        }
                    }
                }

                // After the loop, apply settings if found
                if (foundTargetParagraph) {
                    break; // Exit loop over selected text frames once settings applied
                } else {
                    alert("No subheaders found with corresponding paragraphs. \nPlease use the list script instead.");
                }
            }
        } else {
            alert("Please select a text frame or place the cursor inside a text frame.");
        }
    } else {
        alert("No active document found.");
    }
}

// Function to check if a paragraph meets the criteria
function isValidParagraph(paragraph) {
    // Ignore empty paragraphs (no characters)
    if (paragraph.contents.replace(/^\s+|\s+$/g, '').length === 0) {
        return false;
    }

    // Split the paragraph into words
    var words = paragraph.words;

    // Check number of words and absence of period
    if (words.length > 0 && words.length <= 10) {
        // Access the last word in the collection
        var lastWord = words.lastItem();

        // Check if last word ends with a period
        if (lastWord.contents.charAt(lastWord.contents.length - 1) === ".") {
            return false;
        }

        // All conditions met
        return true;
    }

    return false;
}

// Function to get text settings from a paragraph
function getTextSettings(paragraph) {
    return {
        appliedFont: paragraph.appliedFont,
        pointSize: paragraph.pointSize,
        fillColor: paragraph.fillColor,
        fillTint: paragraph.fillTint,
        justification: paragraph.justification,
        leading: paragraph.leading,
        firstLineIndent: paragraph.firstLineIndent,
        baselineShift: paragraph.baselineShift,
        tracking: paragraph.tracking,
        capitalization: getCapitalization(paragraph.capitalization),
        alignToBaseline: paragraph.alignToBaseline,
        ruleAbove: paragraph.ruleAbove === true,
        ruleBelow: paragraph.ruleBelow === true,
        ruleAboveColor: paragraph.ruleAboveColor,
        ruleAboveGapColor: paragraph.ruleAboveGapColor,
        ruleAboveGapOverprint: paragraph.ruleAboveGapOverprint === true,
        ruleAboveGapTint: paragraph.ruleAboveGapTint,
        ruleAboveLeftIndent: paragraph.ruleAboveLeftIndent,
        ruleAboveLineWeight: paragraph.ruleAboveLineWeight,
        ruleAboveOffset: paragraph.ruleAboveOffset,
        ruleAboveOverprint: paragraph.ruleAboveOverprint === true,
        ruleAboveRightIndent: paragraph.ruleAboveRightIndent,
        ruleAboveTint: paragraph.ruleAboveTint,
        ruleAboveType: paragraph.ruleAboveType,
        ruleAboveWidth: paragraph.ruleAboveWidth,
        ruleBelowColor: paragraph.ruleBelowColor,
        ruleBelowGapColor: paragraph.ruleBelowGapColor,
        ruleBelowGapOverprint: paragraph.ruleBelowGapOverprint === true,
        ruleBelowGapTint: paragraph.ruleBelowGapTint,
        ruleBelowLeftIndent: paragraph.ruleBelowLeftIndent,
        ruleBelowLineWeight: paragraph.ruleBelowLineWeight,
        ruleBelowOffset: paragraph.ruleBelowOffset,
        ruleBelowOverprint: paragraph.ruleBelowOverprint === true,
        ruleBelowRightIndent: paragraph.ruleBelowRightIndent,
        ruleBelowTint: paragraph.ruleBelowTint,
        ruleBelowType: paragraph.ruleBelowType,
        ruleBelowWidth: paragraph.ruleBelowWidth,
        spaceBefore: paragraph.spaceBefore, // Add spaceBefore attribute
        spaceAfter: paragraph.spaceAfter // Add spaceAfter attribute
        // Add more text attributes as needed
    };
}

// Function to apply text settings to a paragraph
function applyTextSettings(paragraph, settings) {
    paragraph.appliedFont = settings.appliedFont;
    paragraph.pointSize = settings.pointSize;
    paragraph.fillColor = settings.fillColor;
    paragraph.fillTint = settings.fillTint;
    paragraph.leading = settings.leading;
    paragraph.firstLineIndent = settings.firstLineIndent;
    paragraph.justification = settings.justification;
    paragraph.ruleAbove = settings.ruleAbove;
    paragraph.ruleAboveColor = settings.ruleAboveColor;
    paragraph.ruleAboveGapColor = settings.ruleAboveGapColor;
    paragraph.ruleAboveGapOverprint = settings.ruleAboveGapOverprint;
    paragraph.ruleAboveGapTint = settings.ruleAboveGapTint;
    paragraph.ruleAboveLeftIndent = settings.ruleAboveLeftIndent;
    paragraph.ruleAboveLineWeight = settings.ruleAboveLineWeight;
    paragraph.ruleAboveOffset = settings.ruleAboveOffset;
    paragraph.ruleAboveOverprint = settings.ruleAboveOverprint;
    paragraph.ruleAboveRightIndent = settings.ruleAboveRightIndent;
    paragraph.ruleAboveTint = settings.ruleAboveTint;
    paragraph.ruleAboveType = settings.ruleAboveType;
    paragraph.ruleAboveWidth = settings.ruleAboveWidth;
    paragraph.ruleBelow = settings.ruleBelow;
    paragraph.ruleBelowColor = settings.ruleBelowColor;
    paragraph.ruleBelowGapColor = settings.ruleBelowGapColor;
    paragraph.ruleBelowGapOverprint = settings.ruleBelowGapOverprint;
    paragraph.ruleBelowGapTint = settings.ruleBelowGapTint;
    paragraph.ruleBelowLeftIndent = settings.ruleBelowLeftIndent;
    paragraph.ruleBelowLineWeight = settings.ruleBelowLineWeight;
    paragraph.ruleBelowOffset = settings.ruleBelowOffset;
    paragraph.ruleBelowOverprint = settings.ruleBelowOverprint;
    paragraph.ruleBelowRightIndent = settings.ruleBelowRightIndent;
    paragraph.ruleBelowTint = settings.ruleBelowTint;
    paragraph.ruleBelowType = settings.ruleBelowType;
    paragraph.ruleBelowWidth = settings.ruleBelowWidth;
    paragraph.spaceBefore = settings.spaceBefore; // Apply spaceBefore
    paragraph.spaceAfter = settings.spaceAfter; // Apply spaceAfter

    // Apply word-level settings to each word in the paragraph
    var paraWords = paragraph.words.everyItem().getElements();
    for (var k = 0; k < paraWords.length; k++) {
        paraWords[k].appliedFont = settings.appliedFont;
        paraWords[k].pointSize = settings.pointSize;
        paraWords[k].fillColor = settings.fillColor;
        paraWords[k].fillTint = settings.fillTint;
        paraWords[k].leading = settings.leading;
        paraWords[k].baselineShift = settings.baselineShift;
        paraWords[k].tracking = settings.tracking;
        paraWords[k].capitalization = settings.capitalization;
        paraWords[k].alignToBaseline = settings.alignToBaseline;
        // Apply other text attributes as needed
    }
}

// Function to apply text settings to consecutive paragraphs
function applyTextSettingsToConsecutive(paragraphs, settingsList) {
    app.doScript(function() {
        var currentConsecutiveIndex = 0;
        for (var i = 0; i < paragraphs.length; i++) {
            var para = paragraphs[i];
            var words = para.words.length;
            var paragraphText = para.contents;

            // Apply text settings if it's a similar paragraph
            if (words > 0 && words <= 10 && paragraphText.indexOf('.') === -1) {
                if (currentConsecutiveIndex < settingsList.length) {
                    applyTextSettings(para, settingsList[currentConsecutiveIndex]);
                    currentConsecutiveIndex++;
                }
            } else {
                currentConsecutiveIndex = 0; // Reset if paragraph does not meet criteria
            }
        }
    }, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Apply Text Settings");
}

// Helper function to map capitalization constants to InDesign values
function getCapitalization(constantValue) {
    switch (constantValue) {
        case 1634493296:
            return Capitalization.ALL_CAPS;
        case 1664250723:
            return Capitalization.CAP_TO_SMALL_CAP;
        case 1852797549:
            return Capitalization.NORMAL;
        case 1936548720:
            return Capitalization.SMALL_CAPS;
        case 1919251315:
            return true; // For ruleAbove
        case 1919251316:
            return true; // For ruleBelow
        default:
            return Capitalization.NORMAL; // Default to normal capitalization
    }
}

// Run the function to find and apply text settings
app.doScript(function() {
    findAndApplyTextSettings();
}, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Find and Apply Text Settings");
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 ,
Jul 29, 2024 Jul 29, 2024

@SmythWharf

 

You don't need this part of the code:

    // Apply word-level settings to each word in the paragraph
    var paraWords = paragraph.words.everyItem().getElements();
    for (var k = 0; k < paraWords.length; k++) {
...
};

 

You can just apply your settings to the whole Paragraph - otherwise you'll end up with a lot of TextStyleRanges and spaces with possibly undetermined formatting. 

 

And it will work faster. 

 

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
Contributor ,
Jul 31, 2024 Jul 31, 2024

Hello, 

 

Ace, I should look into that, 

 

thanks

 

Smyth

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
Contributor ,
Jul 31, 2024 Jul 31, 2024

@Robert at ID-Tasker 

 

Hello, 

I had a look at the suggestion.

 

Additionally, I have now added a feature to be able to automatically remove any paragraph indents in the frist non empty paragraph after consecutive and / or no consective subheader paragraphs. 

Might be useful 

// Main function to find and apply text settings to consecutive paragraphs
function findAndApplyTextSettings() {
    // Check if there's an active document open
    if (app.documents.length > 0) {
        var doc = app.activeDocument;
        var selection = app.selection;

        // Ensure there's a valid selection
        if (selection.length > 0 && (selection[0] instanceof TextFrame || selection[0].hasOwnProperty('insertionPoints'))) {
            var selectedTextFrames = [];
            if (selection[0] instanceof TextFrame) {
                selectedTextFrames.push(selection[0]);
            } else if (selection[0].hasOwnProperty('insertionPoints')) {
                selectedTextFrames.push(selection[0].parentTextFrames[0]);
            }

            var foundTargetParagraph = false;
            var targetTextSettingsList = [];
            var applyIndentAdjustment = false;

            // Iterate over each selected text frame
            for (var j = 0; j < selectedTextFrames.length; j++) {
                var textFrame = selectedTextFrames[j];
                var paragraphs = textFrame.parentStory.paragraphs.everyItem().getElements();

                var consecutiveCount = 0;
                var consecutiveParagraphs = [];
                var allConsecutiveSettings = [];
                var lastValidParagraph = null;

                // Loop through each paragraph
                for (var i = 0; i < paragraphs.length; i++) {
                    var paragraph = paragraphs[i];

                    // Check if the paragraph is empty
                    if (paragraph.contents.replace(/^\s+|\s+$/g, '').length === 0) {
                        continue; // Skip empty paragraphs without resetting the count
                    }

                    // Check if the paragraph meets the criteria for subheaders
                    if (isValidParagraph(paragraph)) {
                        consecutiveCount++;
                        consecutiveParagraphs.push(paragraph);
                        allConsecutiveSettings.push(getTextSettings(paragraph));
                        lastValidParagraph = paragraph; // Track the last valid paragraph

                        // Set flag to adjust indent for the next non-empty paragraph
                        applyIndentAdjustment = true;
                    } else {
                        // If consecutiveCount is greater than 0, process the consecutive paragraphs found
                        if (consecutiveCount > 0) {
                            if (!foundTargetParagraph) {
                                targetTextSettingsList = allConsecutiveSettings;
                                foundTargetParagraph = true;
                            }
                            applyTextSettingsToConsecutive(consecutiveParagraphs, targetTextSettingsList);
                            consecutiveCount = 0; // Reset consecutive count
                            consecutiveParagraphs = [];
                            allConsecutiveSettings = [];
                            lastValidParagraph = null;
                            applyIndentAdjustment = false;
                        } else {
                            consecutiveCount = 0; // Reset consecutive count
                            consecutiveParagraphs = [];
                            allConsecutiveSettings = [];
                            lastValidParagraph = null;
                            applyIndentAdjustment = false;
                        }
                    }

                    // If flag is set, adjust the indent of the next non-empty paragraph
                    if (applyIndentAdjustment) {
                        // Find the next non-empty paragraph
                        for (var k = i + 1; k < paragraphs.length; k++) {
                            var nextParagraph = paragraphs[k];
                            if (nextParagraph.contents.replace(/^\s+|\s+$/g, '').length > 0) {
                                nextParagraph.firstLineIndent = 0;
                                applyIndentAdjustment = false; // Reset flag after adjustment
                                break; // Stop checking after adjustment
                            }
                        }
                    }
                }

                // After the loop, apply settings if found
                if (foundTargetParagraph) {
                    break; // Exit loop over selected text frames once settings applied
                } else {
                    // Optionally, you can include a comment here to indicate no subheaders were found
                    // e.g., "No subheaders found with corresponding paragraphs."
                }
            }
        } else {
            // No valid selection or text frame found
        }
    } else {
        // No active document found
    }
}

// Function to check if a paragraph meets the criteria
function isValidParagraph(paragraph) {
    // Ignore empty paragraphs (no characters)
    if (paragraph.contents.replace(/^\s+|\s+$/g, '').length === 0) {
        return false;
    }

    // Split the paragraph into words
    var words = paragraph.words;

    // Check number of words and absence of period
    if (words.length > 0 && words.length <= 10) {
        // Access the last word in the collection
        var lastWord = words.lastItem();

        // Check if last word ends with a period
        if (lastWord.contents.charAt(lastWord.contents.length - 1) === ".") {
            return false;
        }

        // All conditions met
        return true;
    }

    return false;
}

// Function to get text settings from a paragraph
function getTextSettings(paragraph) {
    return {
        appliedFont: paragraph.appliedFont,
        pointSize: paragraph.pointSize,
        fillColor: paragraph.fillColor,
        fillTint: paragraph.fillTint,
        justification: paragraph.justification,
        leading: paragraph.leading,
        firstLineIndent: paragraph.firstLineIndent,
        baselineShift: paragraph.baselineShift,
        tracking: paragraph.tracking,
        capitalization: getCapitalization(paragraph.capitalization),
        alignToBaseline: paragraph.alignToBaseline,
        ruleAbove: paragraph.ruleAbove === true,
        ruleBelow: paragraph.ruleBelow === true,
        ruleAboveColor: paragraph.ruleAboveColor,
        ruleAboveGapColor: paragraph.ruleAboveGapColor,
        ruleAboveGapOverprint: paragraph.ruleAboveGapOverprint === true,
        ruleAboveGapTint: paragraph.ruleAboveGapTint,
        ruleAboveLeftIndent: paragraph.ruleAboveLeftIndent,
        ruleAboveLineWeight: paragraph.ruleAboveLineWeight,
        ruleAboveOffset: paragraph.ruleAboveOffset,
        ruleAboveOverprint: paragraph.ruleAboveOverprint === true,
        ruleAboveRightIndent: paragraph.ruleAboveRightIndent,
        ruleAboveTint: paragraph.ruleAboveTint,
        ruleAboveType: paragraph.ruleAboveType,
        ruleAboveWidth: paragraph.ruleAboveWidth,
        ruleBelowColor: paragraph.ruleBelowColor,
        ruleBelowGapColor: paragraph.ruleBelowGapColor,
        ruleBelowGapOverprint: paragraph.ruleBelowGapOverprint === true,
        ruleBelowGapTint: paragraph.ruleBelowGapTint,
        ruleBelowLeftIndent: paragraph.ruleBelowLeftIndent,
        ruleBelowLineWeight: paragraph.ruleBelowLineWeight,
        ruleBelowOffset: paragraph.ruleBelowOffset,
        ruleBelowOverprint: paragraph.ruleBelowOverprint === true,
        ruleBelowRightIndent: paragraph.ruleBelowRightIndent,
        ruleBelowTint: paragraph.ruleBelowTint,
        ruleBelowType: paragraph.ruleBelowType,
        ruleBelowWidth: paragraph.ruleBelowWidth,
        spaceBefore: paragraph.spaceBefore, // Add spaceBefore attribute
        spaceAfter: paragraph.spaceAfter // Add spaceAfter attribute
        // Add more text attributes as needed
    };
}

// Function to apply text settings to a paragraph
function applyTextSettings(paragraph, settings) {
    paragraph.appliedFont = settings.appliedFont;
    paragraph.pointSize = settings.pointSize;
    paragraph.fillColor = settings.fillColor;
    paragraph.fillTint = settings.fillTint;
    paragraph.leading = settings.leading;
    paragraph.firstLineIndent = settings.firstLineIndent;
    paragraph.justification = settings.justification;
    paragraph.ruleAbove = settings.ruleAbove;
    paragraph.ruleAboveColor = settings.ruleAboveColor;
    paragraph.ruleAboveGapColor = settings.ruleAboveGapColor;
    paragraph.ruleAboveGapOverprint = settings.ruleAboveGapOverprint;
    paragraph.ruleAboveGapTint = settings.ruleAboveGapTint;
    paragraph.ruleAboveLeftIndent = settings.ruleAboveLeftIndent;
    paragraph.ruleAboveLineWeight = settings.ruleAboveLineWeight;
    paragraph.ruleAboveOffset = settings.ruleAboveOffset;
    paragraph.ruleAboveOverprint = settings.ruleAboveOverprint;
    paragraph.ruleAboveRightIndent = settings.ruleAboveRightIndent;
    paragraph.ruleAboveTint = settings.ruleAboveTint;
    paragraph.ruleAboveType = settings.ruleAboveType;
    paragraph.ruleAboveWidth = settings.ruleAboveWidth;
    paragraph.ruleBelow = settings.ruleBelow;
    paragraph.ruleBelowColor = settings.ruleBelowColor;
    paragraph.ruleBelowGapColor = settings.ruleBelowGapColor;
    paragraph.ruleBelowGapOverprint = settings.ruleBelowGapOverprint;
    paragraph.ruleBelowGapTint = settings.ruleBelowGapTint;
    paragraph.ruleBelowLeftIndent = settings.ruleBelowLeftIndent;
    paragraph.ruleBelowLineWeight = settings.ruleBelowLineWeight;
    paragraph.ruleBelowOffset = settings.ruleBelowOffset;
    paragraph.ruleBelowOverprint = settings.ruleBelowOverprint;
    paragraph.ruleBelowRightIndent = settings.ruleBelowRightIndent;
    paragraph.ruleBelowTint = settings.ruleBelowTint;
    paragraph.ruleBelowType = settings.ruleBelowType;
    paragraph.ruleBelowWidth = settings.ruleBelowWidth;
    paragraph.spaceBefore = settings.spaceBefore; // Apply spaceBefore
    paragraph.spaceAfter = settings.spaceAfter; // Apply spaceAfter
}

// Function to apply text settings to consecutive paragraphs
function applyTextSettingsToConsecutive(paragraphs, settingsList) {
    app.doScript(function() {
        var currentConsecutiveIndex = 0;
        for (var i = 0; i < paragraphs.length; i++) {
            var para = paragraphs[i];
            var words = para.words.length;
            var paragraphText = para.contents;

            // Apply text settings if it's a similar paragraph
            if (words > 0 && words <= 10 && paragraphText.indexOf('.') === -1) {
                if (currentConsecutiveIndex < settingsList.length) {
                    applyTextSettings(para, settingsList[currentConsecutiveIndex]);
                    currentConsecutiveIndex++;
                }
            } else {
                currentConsecutiveIndex = 0; // Reset if paragraph does not meet criteria
            }
        }
    }, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Apply Text Settings");
}

// Helper function to map capitalization constants to InDesign values
function getCapitalization(constantValue) {
    switch (constantValue) {
        case 1634493296:
            return Capitalization.ALL_CAPS;
        case 1664250723:
            return Capitalization.CAP_TO_SMALL_CAP;
        case 1852797549:
            return Capitalization.NORMAL;
        case 1936548720:
            return Capitalization.SMALL_CAPS;
        case 1919251315:
            return true; // For ruleAbove
        case 1919251316:
            return true; // For ruleBelow
        default:
            return Capitalization.NORMAL; // Default to normal capitalization
    }
}

// Run the function to find and apply text settings
app.doScript(function() {
    findAndApplyTextSettings();
}, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Find and Apply Text Settings");



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
Contributor ,
Jul 31, 2024 Jul 31, 2024

Another adjustment 

 

A user can now have a range of text boxes selected and the script will run over them left to right. 

This gives users two ways to begin - cursor in the frame, or selection of one or now more text frames. 

I will probs add a feature for a control regarding tick box for indent on the pargraph being indented to zero - but that is tbc 

// Main function to find and apply text settings to consecutive paragraphs
function findAndApplyTextSettings() {
    // Check if there's an active document open
    if (app.documents.length > 0) {
        var doc = app.activeDocument;
        var selection = app.selection;

        // Ensure there's a valid selection
        if (selection.length > 0) {
            var selectedTextFrames = [];

            // Collect all text frames from selection
            for (var i = 0; i < selection.length; i++) {
                if (selection[i] instanceof TextFrame) {
                    selectedTextFrames.push(selection[i]);
                } else if (selection[i].hasOwnProperty('insertionPoints')) {
                    selectedTextFrames.push(selection[i].parentTextFrames[0]);
                }
            }

            if (selectedTextFrames.length === 0) {
                alert("No valid text frames found in selection.");
                return;
            }

            // Process each text frame individually
            for (var j = 0; j < selectedTextFrames.length; j++) {
                processTextFrame(selectedTextFrames[j]);
            }
        } else {
            // No valid selection
            alert("Please select at least one text frame or insertion point.");
        }
    } else {
        // No active document found
        alert("No active document found.");
    }
}

// Function to process a single text frame
function processTextFrame(textFrame) {
    var paragraphs = textFrame.parentStory.paragraphs.everyItem().getElements();
    
    var foundTargetParagraph = false;
    var targetTextSettingsList = [];
    var applyIndentAdjustment = false;

    var consecutiveCount = 0;
    var consecutiveParagraphs = [];
    var allConsecutiveSettings = [];
    var lastValidParagraph = null;

    // Loop through each paragraph
    for (var i = 0; i < paragraphs.length; i++) {
        var paragraph = paragraphs[i];

        // Check if the paragraph is empty
        if (paragraph.contents.replace(/^\s+|\s+$/g, '').length === 0) {
            continue; // Skip empty paragraphs without resetting the count
        }

        // Check if the paragraph meets the criteria for subheaders
        if (isValidParagraph(paragraph)) {
            consecutiveCount++;
            consecutiveParagraphs.push(paragraph);
            allConsecutiveSettings.push(getTextSettings(paragraph));
            lastValidParagraph = paragraph; // Track the last valid paragraph

            // Set flag to adjust indent for the next non-empty paragraph
            applyIndentAdjustment = true;
        } else {
            // If consecutiveCount is greater than 0, process the consecutive paragraphs found
            if (consecutiveCount > 0) {
                if (!foundTargetParagraph) {
                    targetTextSettingsList = allConsecutiveSettings;
                    foundTargetParagraph = true;
                }
                applyTextSettingsToConsecutive(consecutiveParagraphs, targetTextSettingsList);
                consecutiveCount = 0; // Reset consecutive count
                consecutiveParagraphs = [];
                allConsecutiveSettings = [];
                lastValidParagraph = null;
                applyIndentAdjustment = false;
            } else {
                consecutiveCount = 0; // Reset consecutive count
                consecutiveParagraphs = [];
                allConsecutiveSettings = [];
                lastValidParagraph = null;
                applyIndentAdjustment = false;
            }
        }

        // If flag is set, adjust the indent of the next non-empty paragraph
        if (applyIndentAdjustment) {
            // Find the next non-empty paragraph
            for (var k = i + 1; k < paragraphs.length; k++) {
                var nextParagraph = paragraphs[k];
                if (nextParagraph.contents.replace(/^\s+|\s+$/g, '').length > 0) {
                    nextParagraph.firstLineIndent = 0;
                    applyIndentAdjustment = false; // Reset flag after adjustment
                    break; // Stop checking after adjustment
                }
            }
        }
    }

    // After the loop, apply settings if found
    if (foundTargetParagraph) {
        // Optionally handle cases where settings were found
    } else {
        // Optionally handle cases where no subheaders were found
    }
}

// Function to check if a paragraph meets the criteria
function isValidParagraph(paragraph) {
    // Ignore empty paragraphs (no characters)
    if (paragraph.contents.replace(/^\s+|\s+$/g, '').length === 0) {
        return false;
    }

    // Split the paragraph into words
    var words = paragraph.words;

    // Check number of words and absence of period
    if (words.length > 0 && words.length <= 10) {
        // Access the last word in the collection
        var lastWord = words.lastItem();

        // Check if last word ends with a period
        if (lastWord.contents.charAt(lastWord.contents.length - 1) === ".") {
            return false;
        }

        // All conditions met
        return true;
    }

    return false;
}

// Function to get text settings from a paragraph
function getTextSettings(paragraph) {
    return {
        appliedFont: paragraph.appliedFont,
        pointSize: paragraph.pointSize,
        fillColor: paragraph.fillColor,
        fillTint: paragraph.fillTint,
        justification: paragraph.justification,
        leading: paragraph.leading,
        firstLineIndent: paragraph.firstLineIndent,
        baselineShift: paragraph.baselineShift,
        tracking: paragraph.tracking,
        capitalization: getCapitalization(paragraph.capitalization),
        alignToBaseline: paragraph.alignToBaseline,
        ruleAbove: paragraph.ruleAbove === true,
        ruleBelow: paragraph.ruleBelow === true,
        ruleAboveColor: paragraph.ruleAboveColor,
        ruleAboveGapColor: paragraph.ruleAboveGapColor,
        ruleAboveGapOverprint: paragraph.ruleAboveGapOverprint === true,
        ruleAboveGapTint: paragraph.ruleAboveGapTint,
        ruleAboveLeftIndent: paragraph.ruleAboveLeftIndent,
        ruleAboveLineWeight: paragraph.ruleAboveLineWeight,
        ruleAboveOffset: paragraph.ruleAboveOffset,
        ruleAboveOverprint: paragraph.ruleAboveOverprint === true,
        ruleAboveRightIndent: paragraph.ruleAboveRightIndent,
        ruleAboveTint: paragraph.ruleAboveTint,
        ruleAboveType: paragraph.ruleAboveType,
        ruleAboveWidth: paragraph.ruleAboveWidth,
        ruleBelowColor: paragraph.ruleBelowColor,
        ruleBelowGapColor: paragraph.ruleBelowGapColor,
        ruleBelowGapOverprint: paragraph.ruleBelowGapOverprint === true,
        ruleBelowGapTint: paragraph.ruleBelowGapTint,
        ruleBelowLeftIndent: paragraph.ruleBelowLeftIndent,
        ruleBelowLineWeight: paragraph.ruleBelowLineWeight,
        ruleBelowOffset: paragraph.ruleBelowOffset,
        ruleBelowOverprint: paragraph.ruleBelowOverprint === true,
        ruleBelowRightIndent: paragraph.ruleBelowRightIndent,
        ruleBelowTint: paragraph.ruleBelowTint,
        ruleBelowType: paragraph.ruleBelowType,
        ruleBelowWidth: paragraph.ruleBelowWidth,
        spaceBefore: paragraph.spaceBefore, // Add spaceBefore attribute
        spaceAfter: paragraph.spaceAfter // Add spaceAfter attribute
        // Add more text attributes as needed
    };
}

// Function to apply text settings to a paragraph
function applyTextSettings(paragraph, settings) {
    paragraph.appliedFont = settings.appliedFont;
    paragraph.pointSize = settings.pointSize;
    paragraph.fillColor = settings.fillColor;
    paragraph.fillTint = settings.fillTint;
    paragraph.leading = settings.leading;
    paragraph.firstLineIndent = settings.firstLineIndent;
    paragraph.justification = settings.justification;
    paragraph.ruleAbove = settings.ruleAbove;
    paragraph.ruleAboveColor = settings.ruleAboveColor;
    paragraph.ruleAboveGapColor = settings.ruleAboveGapColor;
    paragraph.ruleAboveGapOverprint = settings.ruleAboveGapOverprint;
    paragraph.ruleAboveGapTint = settings.ruleAboveGapTint;
    paragraph.ruleAboveLeftIndent = settings.ruleAboveLeftIndent;
    paragraph.ruleAboveLineWeight = settings.ruleAboveLineWeight;
    paragraph.ruleAboveOffset = settings.ruleAboveOffset;
    paragraph.ruleAboveOverprint = settings.ruleAboveOverprint;
    paragraph.ruleAboveRightIndent = settings.ruleAboveRightIndent;
    paragraph.ruleAboveTint = settings.ruleAboveTint;
    paragraph.ruleAboveType = settings.ruleAboveType;
    paragraph.ruleAboveWidth = settings.ruleAboveWidth;
    paragraph.ruleBelow = settings.ruleBelow;
    paragraph.ruleBelowColor = settings.ruleBelowColor;
    paragraph.ruleBelowGapColor = settings.ruleBelowGapColor;
    paragraph.ruleBelowGapOverprint = settings.ruleBelowGapOverprint;
    paragraph.ruleBelowGapTint = settings.ruleBelowGapTint;
    paragraph.ruleBelowLeftIndent = settings.ruleBelowLeftIndent;
    paragraph.ruleBelowLineWeight = settings.ruleBelowLineWeight;
    paragraph.ruleBelowOffset = settings.ruleBelowOffset;
    paragraph.ruleBelowOverprint = settings.ruleBelowOverprint;
    paragraph.ruleBelowRightIndent = settings.ruleBelowRightIndent;
    paragraph.ruleBelowTint = settings.ruleBelowTint;
    paragraph.ruleBelowType = settings.ruleBelowType;
    paragraph.ruleBelowWidth = settings.ruleBelowWidth;
    paragraph.spaceBefore = settings.spaceBefore; // Apply spaceBefore
    paragraph.spaceAfter = settings.spaceAfter; // Apply spaceAfter
}

// Function to apply text settings to consecutive paragraphs
function applyTextSettingsToConsecutive(paragraphs, settingsList) {
    app.doScript(function() {
        var currentConsecutiveIndex = 0;
        for (var i = 0; i < paragraphs.length; i++) {
            var para = paragraphs[i];
            var words = para.words.length;
            var paragraphText = para.contents;

            // Apply text settings if it's a similar paragraph
            if (words > 0 && words <= 10 && paragraphText.indexOf('.') === -1) {
                if (currentConsecutiveIndex < settingsList.length) {
                    applyTextSettings(para, settingsList[currentConsecutiveIndex]);
                    currentConsecutiveIndex++;
                }
            } else {
                currentConsecutiveIndex = 0; // Reset if paragraph does not meet criteria
            }
        }
    }, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Apply Text Settings");
}

// Helper function to map capitalization constants to InDesign values
function getCapitalization(constantValue) {
    switch (constantValue) {
        case 1634493296:
            return Capitalization.ALL_CAPS;
        case 1664250723:
            return Capitalization.CAP_TO_SMALL_CAP;
        case 1852797549:
            return Capitalization.NORMAL;
        case 1936548720:
            return Capitalization.SMALL_CAPS;
        case 1919251315:
            return true; // For ruleAbove
        case 1919251316:
            return true; // For ruleBelow
        default:
            return Capitalization.NORMAL; // Default to normal capitalization
    }
}

// Run the function to find and apply text settings
app.doScript(function() {
    findAndApplyTextSettings();
}, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Find and Apply Text Settings");




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
Contributor ,
Aug 09, 2024 Aug 09, 2024

New update  - now carries caps and baseline rules across subheades 

 

 

// Main function to find and apply text settings to consecutive paragraphs
function findAndApplyTextSettings() {
    // Check if there's an active document open
    if (app.documents.length > 0) {
        var doc = app.activeDocument;
        var selection = app.selection;

        // Ensure there's a valid selection
        if (selection.length > 0) {
            var selectedTextFrames = [];

            // Collect all text frames from selection
            for (var i = 0; i < selection.length; i++) {
                if (selection[i] instanceof TextFrame) {
                    selectedTextFrames.push(selection[i]);
                } else if (selection[i].hasOwnProperty('insertionPoints')) {
                    selectedTextFrames.push(selection[i].parentTextFrames[0]);
                }
            }

            if (selectedTextFrames.length === 0) {
                alert("No valid text frames found in selection.");
                return;
            }

            // Process each text frame individually
            for (var j = 0; j < selectedTextFrames.length; j++) {
                processTextFrame(selectedTextFrames[j]);
            }
        } else {
            // No valid selection
            alert("Please select at least one text frame or insertion point.");
        }
    } else {
        // No active document found
        alert("No active document found.");
    }
}

// Function to process a single text frame
function processTextFrame(textFrame) {
    var paragraphs = textFrame.parentStory.paragraphs.everyItem().getElements();
    
    var foundTargetParagraph = false;
    var targetTextSettingsList = [];
    var applyIndentAdjustment = false;

    var consecutiveCount = 0;
    var consecutiveParagraphs = [];
    var allConsecutiveSettings = [];
    var lastValidParagraph = null;

    // Loop through each paragraph
    for (var i = 0; i < paragraphs.length; i++) {
        var paragraph = paragraphs[i];

        // Check if the paragraph is empty
        if (paragraph.contents.replace(/^\s+|\s+$/g, '').length === 0) {
            continue; // Skip empty paragraphs without resetting the count
        }

        // Check if the paragraph meets the criteria for subheaders
        if (isValidParagraph(paragraph)) {
            consecutiveCount++;
            consecutiveParagraphs.push(paragraph);
            allConsecutiveSettings.push(getTextSettings(paragraph));
            lastValidParagraph = paragraph; // Track the last valid paragraph

            // Set flag to adjust indent for the next non-empty paragraph
            applyIndentAdjustment = true;
        } else {
            // If consecutiveCount is greater than 0, process the consecutive paragraphs found
            if (consecutiveCount > 0) {
                if (!foundTargetParagraph) {
                    targetTextSettingsList = allConsecutiveSettings;
                    foundTargetParagraph = true;
                }
                applyTextSettingsToConsecutive(consecutiveParagraphs, targetTextSettingsList);
                consecutiveCount = 0; // Reset consecutive count
                consecutiveParagraphs = [];
                allConsecutiveSettings = [];
                lastValidParagraph = null;
                applyIndentAdjustment = false;
            } else {
                consecutiveCount = 0; // Reset consecutive count
                consecutiveParagraphs = [];
                allConsecutiveSettings = [];
                lastValidParagraph = null;
                applyIndentAdjustment = false;
            }
        }

        // If flag is set, adjust the indent of the next non-empty paragraph
        if (applyIndentAdjustment) {
            // Find the next non-empty paragraph
            for (var k = i + 1; k < paragraphs.length; k++) {
                var nextParagraph = paragraphs[k];
                if (nextParagraph.contents.replace(/^\s+|\s+$/g, '').length > 0) {
                    nextParagraph.firstLineIndent = 0;
                    applyIndentAdjustment = false; // Reset flag after adjustment
                    break; // Stop checking after adjustment
                }
            }
        }
    }

    // After the loop, apply settings if found
    if (foundTargetParagraph) {
        // Optionally handle cases where settings were found
    } else {
        // Optionally handle cases where no subheaders were found
    }
}

// Function to check if a paragraph meets the criteria
function isValidParagraph(paragraph) {
    // Ignore empty paragraphs (no characters)
    if (paragraph.contents.replace(/^\s+|\s+$/g, '').length === 0) {
        return false;
    }

    // Split the paragraph into words
    var words = paragraph.words;

    // Check number of words and absence of period
    if (words.length > 0 && words.length <= 10) {
        // Access the last word in the collection
        var lastWord = words.lastItem();

        // Check if last word ends with a period
        if (lastWord.contents.charAt(lastWord.contents.length - 1) === ".") {
            return false;
        }

        // All conditions met
        return true;
    }

    return false;
}

// Function to get text settings from a paragraph
function getTextSettings(paragraph) {
    return {
        appliedFont: paragraph.appliedFont,
        pointSize: paragraph.pointSize,
        fillColor: paragraph.fillColor,
        fillTint: paragraph.fillTint,
        justification: paragraph.justification,
        leading: paragraph.leading,
        firstLineIndent: paragraph.firstLineIndent,
        baselineShift: paragraph.baselineShift,
        tracking: paragraph.tracking,
        capitalization: getCapitalization(paragraph.capitalization),
        alignToBaseline: paragraph.alignToBaseline,
        ruleAbove: paragraph.ruleAbove === true,
        ruleBelow: paragraph.ruleBelow === true,
        ruleAboveColor: paragraph.ruleAboveColor,
        ruleAboveGapColor: paragraph.ruleAboveGapColor,
        ruleAboveGapOverprint: paragraph.ruleAboveGapOverprint === true,
        ruleAboveGapTint: paragraph.ruleAboveGapTint,
        ruleAboveLeftIndent: paragraph.ruleAboveLeftIndent,
        ruleAboveLineWeight: paragraph.ruleAboveLineWeight,
        ruleAboveOffset: paragraph.ruleAboveOffset,
        ruleAboveOverprint: paragraph.ruleAboveOverprint === true,
        ruleAboveRightIndent: paragraph.ruleAboveRightIndent,
        ruleAboveTint: paragraph.ruleAboveTint,
        ruleAboveType: paragraph.ruleAboveType,
        ruleAboveWidth: paragraph.ruleAboveWidth,
        ruleBelowColor: paragraph.ruleBelowColor,
        ruleBelowGapColor: paragraph.ruleBelowGapColor,
        ruleBelowGapOverprint: paragraph.ruleBelowGapOverprint === true,
        ruleBelowGapTint: paragraph.ruleBelowGapTint,
        ruleBelowLeftIndent: paragraph.ruleBelowLeftIndent,
        ruleBelowLineWeight: paragraph.ruleBelowLineWeight,
        ruleBelowOffset: paragraph.ruleBelowOffset,
        ruleBelowOverprint: paragraph.ruleBelowOverprint === true,
        ruleBelowRightIndent: paragraph.ruleBelowRightIndent,
        ruleBelowTint: paragraph.ruleBelowTint,
        ruleBelowType: paragraph.ruleBelowType,
        ruleBelowWidth: paragraph.ruleBelowWidth,
        spaceBefore: paragraph.spaceBefore, // Add spaceBefore attribute
        spaceAfter: paragraph.spaceAfter // Add spaceAfter attribute
        // Add more text attributes as needed
    };
}

// Function to apply text settings to a paragraph
function applyTextSettings(paragraph, settings) {
    paragraph.appliedFont = settings.appliedFont;
    paragraph.pointSize = settings.pointSize;
    paragraph.fillColor = settings.fillColor;
    paragraph.fillTint = settings.fillTint;
    paragraph.leading = settings.leading;
    paragraph.firstLineIndent = settings.firstLineIndent;
    paragraph.justification = settings.justification;
    paragraph.baselineShift = settings.baselineShift; // Apply baselineShift
    paragraph.tracking = settings.tracking; // Apply tracking
    paragraph.capitalization = settings.capitalization; // Apply capitalization
    paragraph.alignToBaseline = settings.alignToBaseline; // Apply alignToBaseline
    paragraph.ruleAbove = settings.ruleAbove; // Apply ruleAbove
    paragraph.ruleAboveColor = settings.ruleAboveColor; // Apply ruleAboveColor
    paragraph.ruleAboveGapColor = settings.ruleAboveGapColor; // Apply ruleAboveGapColor
    paragraph.ruleAboveGapOverprint = settings.ruleAboveGapOverprint; // Apply ruleAboveGapOverprint
    paragraph.ruleAboveGapTint = settings.ruleAboveGapTint; // Apply ruleAboveGapTint
    paragraph.ruleAboveLeftIndent = settings.ruleAboveLeftIndent; // Apply ruleAboveLeftIndent
    paragraph.ruleAboveLineWeight = settings.ruleAboveLineWeight; // Apply ruleAboveLineWeight
    paragraph.ruleAboveOffset = settings.ruleAboveOffset; // Apply ruleAboveOffset
    paragraph.ruleAboveOverprint = settings.ruleAboveOverprint; // Apply ruleAboveOverprint
    paragraph.ruleAboveRightIndent = settings.ruleAboveRightIndent; // Apply ruleAboveRightIndent
    paragraph.ruleAboveTint = settings.ruleAboveTint; // Apply ruleAboveTint
    paragraph.ruleAboveType = settings.ruleAboveType; // Apply ruleAboveType
    paragraph.ruleAboveWidth = settings.ruleAboveWidth; // Apply ruleAboveWidth
    paragraph.ruleBelow = settings.ruleBelow; // Apply ruleBelow
    paragraph.ruleBelowColor = settings.ruleBelowColor; // Apply ruleBelowColor
    paragraph.ruleBelowGapColor = settings.ruleBelowGapColor; // Apply ruleBelowGapColor
    paragraph.ruleBelowGapOverprint = settings.ruleBelowGapOverprint; // Apply ruleBelowGapOverprint
    paragraph.ruleBelowGapTint = settings.ruleBelowGapTint; // Apply ruleBelowGapTint
    paragraph.ruleBelowLeftIndent = settings.ruleBelowLeftIndent; // Apply ruleBelowLeftIndent
    paragraph.ruleBelowLineWeight = settings.ruleBelowLineWeight; // Apply ruleBelowLineWeight
    paragraph.ruleBelowOffset = settings.ruleBelowOffset; // Apply ruleBelowOffset
    paragraph.ruleBelowOverprint = settings.ruleBelowOverprint; // Apply ruleBelowOverprint
    paragraph.ruleBelowRightIndent = settings.ruleBelowRightIndent; // Apply ruleBelowRightIndent
    paragraph.ruleBelowTint = settings.ruleBelowTint; // Apply ruleBelowTint
    paragraph.ruleBelowType = settings.ruleBelowType; // Apply ruleBelowType
    paragraph.ruleBelowWidth = settings.ruleBelowWidth; // Apply ruleBelowWidth
    paragraph.spaceBefore = settings.spaceBefore; // Apply spaceBefore
    paragraph.spaceAfter = settings.spaceAfter; // Apply spaceAfter
}

// Function to apply text settings to consecutive paragraphs
function applyTextSettingsToConsecutive(paragraphs, settingsList) {
    app.doScript(function() {
        var currentConsecutiveIndex = 0;
        for (var i = 0; i < paragraphs.length; i++) {
            var para = paragraphs[i];
            var words = para.words.length;
            var paragraphText = para.contents;

            // Apply text settings if it's a similar paragraph
            if (words > 0 && words <= 10 && paragraphText.indexOf('.') === -1) {
                if (currentConsecutiveIndex < settingsList.length) {
                    applyTextSettings(para, settingsList[currentConsecutiveIndex]);
                    currentConsecutiveIndex++;
                }
            } else {
                currentConsecutiveIndex = 0; // Reset if paragraph does not meet criteria
            }
        }
    }, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Apply Text Settings");
}

// Helper function to map capitalization constants to InDesign values
function getCapitalization(constantValue) {
    switch (constantValue) {
        case 1634493296:
            return Capitalization.ALL_CAPS;
        case 1664250723:
            return Capitalization.CAP_TO_SMALL_CAP;
        case 1852797549:
            return Capitalization.NORMAL;
        case 1936548720:
            return Capitalization.SMALL_CAPS;
        case 1919251315:
            return true; // For ruleAbove
        case 1919251316:
            return true; // For ruleBelow
        default:
            return Capitalization.NORMAL; // Default to normal capitalization
    }
}

// Run the function to find and apply text settings
app.doScript(function() {
    findAndApplyTextSettings();
}, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Find and Apply Text Settings");
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 ,
Aug 09, 2024 Aug 09, 2024

@SmythWharf

 

If your first paragraphs have some formatting applied - I assume through ParaStyles - why not just save the names of those ParaStyles and apply them when needed? Instead of saving and restoring some of the properties?

 

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
Contributor ,
Aug 14, 2024 Aug 14, 2024

Hi Robert, 

 

Below is an update version of the script which now takes into account if a user has a subheader styles via paragraph styles. It will now add that paragraph style throughout any automatically found headers. If the paragraph style has been adjusted by a user then it will use the users settings not the paragraph style. 

However, I think this is missing the point. 

The very purpose of this script is to provide an automated way of styling subheaders without the designer having to read through all the text. The designer can update the styles very easily through the first instance(s) subheaders. 

 

Let me know if there are other pointer. 

 

Thanks 

 

Smyth 


Notes on the below update 
- Now takes note if a user has used a paaragaph style, will apply unedited paragraph styles to repective subheaders 
- Now periods inside of subheaders less than words will not prevent styles from being applied, this allows for prices and numbered headers etc 

// Main function to find and apply text settings to consecutive paragraphs
function findAndApplyTextSettings() {
    if (app.documents.length > 0) {
        var doc = app.activeDocument;
        var selection = app.selection;

        if (selection.length > 0) {
            var selectedTextFrames = [];

            for (var i = 0; i < selection.length; i++) {
                if (selection[i] instanceof TextFrame) {
                    selectedTextFrames.push(selection[i]);
                } else if (selection[i].hasOwnProperty('insertionPoints')) {
                    selectedTextFrames.push(selection[i].parentTextFrames[0]);
                }
            }

            if (selectedTextFrames.length === 0) {
                alert("No valid text frames found in selection.");
                return;
            }

            for (var j = 0; j < selectedTextFrames.length; j++) {
                processTextFrame(selectedTextFrames[j]);
            }
        } else {
            alert("Please select at least one text frame or insertion point.");
        }
    } else {
        alert("No active document found.");
    }
}

// Function to process a single text frame
function processTextFrame(textFrame) {
    var paragraphs = textFrame.parentStory.paragraphs.everyItem().getElements();
    
    var foundTargetParagraph = false;
    var targetTextSettingsList = [];
    var applyIndentAdjustment = false;

    var consecutiveCount = 0;
    var consecutiveParagraphs = [];
    var allConsecutiveSettings = [];
    var lastValidParagraph = null;

    for (var i = 0; i < paragraphs.length; i++) {
        var paragraph = paragraphs[i];

        if (paragraph.contents.replace(/^\s+|\s+$/g, '').length === 0) {
            continue;
        }

        if (isValidParagraph(paragraph)) {
            consecutiveCount++;
            consecutiveParagraphs.push(paragraph);
            allConsecutiveSettings.push(getTextSettings(paragraph));
            lastValidParagraph = paragraph;

            applyIndentAdjustment = true;
        } else {
            if (consecutiveCount > 0) {
                if (!foundTargetParagraph) {
                    targetTextSettingsList = allConsecutiveSettings;
                    foundTargetParagraph = true;
                }
                applyTextSettingsToConsecutive(consecutiveParagraphs, targetTextSettingsList);
                consecutiveCount = 0;
                consecutiveParagraphs = [];
                allConsecutiveSettings = [];
                lastValidParagraph = null;
                applyIndentAdjustment = false;
            } else {
                consecutiveCount = 0;
                consecutiveParagraphs = [];
                allConsecutiveSettings = [];
                lastValidParagraph = null;
                applyIndentAdjustment = false;
            }
        }

        if (applyIndentAdjustment) {
            for (var k = i + 1; k < paragraphs.length; k++) {
                var nextParagraph = paragraphs[k];
                if (nextParagraph.contents.replace(/^\s+|\s+$/g, '').length > 0) {
                    nextParagraph.firstLineIndent = 0;
                    applyIndentAdjustment = false;
                    break;
                }
            }
        }
    }

    if (foundTargetParagraph) {
        // Handle cases where settings were found
    } else {
        // Handle cases where no subheaders were found
    }
}

// Function to check if a paragraph meets the criteria
function isValidParagraph(paragraph) {
    var contents = paragraph.contents.replace(/^\s+|\s+$/g, '');
    
    if (contents.length === 0) {
        return false;
    }

    var words = paragraph.words;
    if (words.length > 0 && words.length <= 10) {
        var lastWord = words.lastItem();
        var lastWordContents = lastWord.contents;

        // Check if the last word ends with a period
        if (lastWordContents.charAt(lastWordContents.length - 1) === ".") {
            // Check if the period is part of a number or abbreviation
            var periodPattern = /\d+\.\d+|[a-zA-Z]\.\s*$/;
            if (periodPattern.test(lastWordContents)) {
                return true;
            } else {
                return false;
            }
        }

        return true;
    }

    return false;
}

// Function to get text settings from a paragraph
function getTextSettings(paragraph) {
    var settings = {
        appliedFont: paragraph.appliedFont,
        pointSize: paragraph.pointSize,
        fillColor: paragraph.fillColor,
        fillTint: paragraph.fillTint,
        justification: paragraph.justification,
        leading: paragraph.leading,
        firstLineIndent: paragraph.firstLineIndent,
        baselineShift: paragraph.baselineShift,
        tracking: paragraph.tracking,
        capitalization: getCapitalization(paragraph.capitalization),
        alignToBaseline: paragraph.alignToBaseline,
        ruleAbove: paragraph.ruleAbove === true,
        ruleBelow: paragraph.ruleBelow === true,
        ruleAboveColor: paragraph.ruleAboveColor,
        ruleAboveGapColor: paragraph.ruleAboveGapColor,
        ruleAboveGapOverprint: paragraph.ruleAboveGapOverprint === true,
        ruleAboveGapTint: paragraph.ruleAboveGapTint,
        ruleAboveLeftIndent: paragraph.ruleAboveLeftIndent,
        ruleAboveLineWeight: paragraph.ruleAboveLineWeight,
        ruleAboveOffset: paragraph.ruleAboveOffset,
        ruleAboveOverprint: paragraph.ruleAboveOverprint === true,
        ruleAboveRightIndent: paragraph.ruleAboveRightIndent,
        ruleAboveTint: paragraph.ruleAboveTint,
        ruleAboveType: paragraph.ruleAboveType,
        ruleAboveWidth: paragraph.ruleAboveWidth,
        ruleBelowColor: paragraph.ruleBelowColor,
        ruleBelowGapColor: paragraph.ruleBelowGapColor,
        ruleBelowGapOverprint: paragraph.ruleBelowGapOverprint === true,
        ruleBelowGapTint: paragraph.ruleBelowGapTint,
        ruleBelowLeftIndent: paragraph.ruleBelowLeftIndent,
        ruleBelowLineWeight: paragraph.ruleBelowLineWeight,
        ruleBelowOffset: paragraph.ruleBelowOffset,
        ruleBelowOverprint: paragraph.ruleBelowOverprint === true,
        ruleBelowRightIndent: paragraph.ruleBelowRightIndent,
        ruleBelowTint: paragraph.ruleBelowTint,
        ruleBelowType: paragraph.ruleBelowType,
        ruleBelowWidth: paragraph.ruleBelowWidth,
        spaceBefore: paragraph.spaceBefore,
        spaceAfter: paragraph.spaceAfter
    };

    var paragraphStyle = paragraph.appliedParagraphStyle;
    if (paragraphStyle.isValid && isStyleUnmodified(paragraph, paragraphStyle)) {
        settings.paragraphStyle = paragraphStyle;
    } else {
        settings.paragraphStyle = null;
    }

    return settings;
}

// Function to check if the paragraph matches its base paragraph style
function isStyleUnmodified(paragraph, paragraphStyle) {
    var styleProperties = ['appliedFont', 'pointSize', 'fillColor', 'fillTint', 'justification', 'leading', 'firstLineIndent', 'baselineShift', 'tracking', 'capitalization', 'alignToBaseline', 'ruleAbove', 'ruleBelow', 'spaceBefore', 'spaceAfter'];

    for (var i = 0; i < styleProperties.length; i++) {
        var prop = styleProperties[i];
        if (paragraph[prop] !== paragraphStyle[prop]) {
            return false;
        }
    }
    return true;
}

// Function to apply text settings to a paragraph
function applyTextSettings(paragraph, settings) {
    if (settings.paragraphStyle) {
        paragraph.applyParagraphStyle(settings.paragraphStyle, true);
    } else {
        paragraph.appliedFont = settings.appliedFont;
        paragraph.pointSize = settings.pointSize;
        paragraph.fillColor = settings.fillColor;
        paragraph.fillTint = settings.fillTint;
        paragraph.leading = settings.leading;
        paragraph.firstLineIndent = settings.firstLineIndent;
        paragraph.justification = settings.justification;
        paragraph.baselineShift = settings.baselineShift;
        paragraph.tracking = settings.tracking;
        paragraph.capitalization = settings.capitalization;
        paragraph.alignToBaseline = settings.alignToBaseline;
        paragraph.ruleAbove = settings.ruleAbove;
        paragraph.ruleAboveColor = settings.ruleAboveColor;
        paragraph.ruleAboveGapColor = settings.ruleAboveGapColor;
        paragraph.ruleAboveGapOverprint = settings.ruleAboveGapOverprint;
        paragraph.ruleAboveGapTint = settings.ruleAboveGapTint;
        paragraph.ruleAboveLeftIndent = settings.ruleAboveLeftIndent;
        paragraph.ruleAboveLineWeight = settings.ruleAboveLineWeight;
        paragraph.ruleAboveOffset = settings.ruleAboveOffset;
        paragraph.ruleAboveOverprint = settings.ruleAboveOverprint;
        paragraph.ruleAboveRightIndent = settings.ruleAboveRightIndent;
        paragraph.ruleAboveTint = settings.ruleAboveTint;
        paragraph.ruleAboveType = settings.ruleAboveType;
        paragraph.ruleAboveWidth = settings.ruleAboveWidth;
        paragraph.ruleBelow = settings.ruleBelow;
        paragraph.ruleBelowColor = settings.ruleBelowColor;
        paragraph.ruleBelowGapColor = settings.ruleBelowGapColor;
        paragraph.ruleBelowGapOverprint = settings.ruleBelowGapOverprint;
        paragraph.ruleBelowGapTint = settings.ruleBelowGapTint;
        paragraph.ruleBelowLeftIndent = settings.ruleBelowLeftIndent;
        paragraph.ruleBelowLineWeight = settings.ruleBelowLineWeight;
        paragraph.ruleBelowOffset = settings.ruleBelowOffset;
        paragraph.ruleBelowOverprint = settings.ruleBelowOverprint;
        paragraph.ruleBelowRightIndent = settings.ruleBelowRightIndent;
        paragraph.ruleBelowTint = settings.ruleBelowTint;
        paragraph.ruleBelowType = settings.ruleBelowType;
        paragraph.ruleBelowWidth = settings.ruleBelowWidth;
        paragraph.spaceBefore = settings.spaceBefore;
        paragraph.spaceAfter = settings.spaceAfter;
    }
}

// Function to apply text settings to consecutive paragraphs
function applyTextSettingsToConsecutive(paragraphs, settingsList) {
    app.doScript(function() {
        var currentConsecutiveIndex = 0;
        for (var i = 0; i < paragraphs.length; i++) {
            var para = paragraphs[i];
            var words = para.words.length;
            var paragraphText = para.contents;

            if (words > 0 && words <= 10 && !/^\d+(\.\d+)?$/.test(paragraphText)) {
                if (currentConsecutiveIndex < settingsList.length) {
                    applyTextSettings(para, settingsList[currentConsecutiveIndex]);
                    currentConsecutiveIndex++;
                }
            } else {
                currentConsecutiveIndex = 0;
            }
        }
    }, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Apply Text Settings");
}

// Helper function to map capitalization constants to InDesign values
function getCapitalization(constantValue) {
    switch (constantValue) {
        case 1634493296:
            return Capitalization.ALL_CAPS;
        case 1664250723:
            return Capitalization.CAP_TO_SMALL_CAP;
        case 1852797549:
            return Capitalization.NORMAL;
        case 1936548720:
            return Capitalization.SMALL_CAPS;
        case 1919251315:
            return true;
        case 1919251316:
            return true;
        default:
            return Capitalization.NORMAL;
    }
}

// Run the function to find and apply text settings
app.doScript(function() {
    findAndApplyTextSettings();
}, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Find and Apply Text Settings");

 

 

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 ,
Aug 14, 2024 Aug 14, 2024

@SmythWharf

 

I think you are missing my point - you should NEVER EVER use local formatting when working in InDesign.

 

So you should "promote" using Styles - ParaStyles in this case - which will also mean that your code will be much simpler AND faster. 

 

If user will change formatting for those first few paragraphs - user will have to re-run your script. 

 

But if ParaStyles are applied - your script needs to be run only once - unless user add more text. 

 

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
Contributor ,
Aug 14, 2024 Aug 14, 2024

Hello Robert, 

 

Thank you for your feedback regarding the use of local formatting versus paragraph styles. I appreciate your insights and did implement the paragraph style aspect to the script. 

 

However, I’d like to share some additional considerations:

 

In my experience, many designers in their roles use a combination of local formatting and paragraph styles. 

 

I have also seen InDesign used with content mangement systems which mean paragaph styles can behave differently depending on the document people are working on. (This occurs when paragraph styles are preloaded with the document by default rather than empty documents which have styles assigned to them - don't ask me why I have seen this... mainly publishing houses. In short pullquote library item will look different based on document - although same library item and paragraph style.)

 

While creating a new paragraph style each time the script runs is an option, this could lead to a cluttered paragraph style list with multiple, perhaps unnecessary, styles—especially if designers change their preferences frequently based on client feedback or during the design process.

 

If the script was to change to do such, how would they be named so users can understand what the styles were. For example if each time it ran and it created another style, style 1, style 2, style n... this would get confusing. 

Perhaps it creates the style once and then if changed it gets redefined? But how would it know when to make or redine a style? Any hints on this could be useful to think about. 

 

Take into consideration that subheaders are stacked designers could test styles in a test bit of copy but people are lazy and so giving people a way to see subheader styles arross all text in the fastest way is my aim.

 

Regarding performance, I’ve tested the script with texts ranging from 3,000 to 5,000 words, and it performs the task in seconds—certainly faster than manual formatting. Additionally, the script allows for easy updates: a designer can modify the formatting of the first instance and run the script to apply those changes across the rest of the text in the set of threaded frames.

 

Having said that, yes they would need change the style for each frist instance header(s),  and then to run the script for each parent frame. However, one would hope on such an expansive project, for example one would define the paragraph styles in the first header then run the script for all sets of frames and then if they needed to change something they can do it through the paragraph style menu.  They could still use the script to style the copy though and it would be faster than by hand.

 

But on smaller projects layouts, poster updating header(s) even if you do have to do it for each parent threaded frame is still going to be faster than having to do it by hand.

 

I use this script regularly via a shortcut and find that speed wize it's negligible compared to redefining the paragraph style via the style menu. So for smaller projects like a big list entry etc it would be much the same, the main issue comes in the example above. 

 

While the script might not be as elegant as a fully style-based approach, it provides practical benefits in environments where both local formatting and paragraph styles are used. 

 

I don't mean to sound mistrusting of  your advice, I simply wish to make the point that it's not entirely useless even if it is not following the best guidelines.

 

Again I would like to thank you again for your input—I’m always open to refining the tool further.

 

Best, 

 

Smyth

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
Contributor ,
Aug 14, 2024 Aug 14, 2024

One quick thought I had is - right now if you have the text box selected or the cursor in the text the scripts runs over all text. But this could behave differntly, i.e. text frame selection does all, but cursor in text would do everything beyond that point. 

 

Might help issues where 10 headers and number 5, 7 both had subeaders. You could run the script again from that point as if you run it currently it would not work etc.

 

Anyhow it's all a work in progress

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 ,
Aug 15, 2024 Aug 15, 2024

I'm not arguing that script is faster than doing it manually. That's why I've created my tool as well. And you've done a great job with your tool. 

 

Even if you need / prefer to have local formatting - you can create a new / temporary ParaStyle, apply it to the texts - then delete and keep formatting. 

 

There are 400+ Text properties - do you really want to rewrite all of them in the code? 

 

Not sure what is wrong with CMS? You have a template that you populate with data - template dictates formatting - if it needs to be changed - styles can be redefined - for this particular situation - after template is populated. 

If someone needs to create variations of the text to have multiple versions - it's still better to create copies of the styles, instead of local formatting - that can be lost with one wrong click...

 

If someone can't handle multiple sets of styles... 

 

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
Contributor ,
Aug 15, 2024 Aug 15, 2024

Hello,

 

Ah okay, so I can have tempory paragraph styles - okay I will dive into this....... didn't think of this as a tempory concept. 

 

I understand your benifits regarding cutting down on lines of code avoiding the hard coding in of styles etc 

 

Okay lemme take a look, 

 

Best 

 

Smyth 

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 ,
Aug 15, 2024 Aug 15, 2024
LATEST

Scripting is to help people get job done quicker - but it doesn't mean, that coder needs to work harder. 

 

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