Created
October 12, 2025 21:08
-
-
Save JohnGemstone/f97aab2b76a9ba5910581071691cf8d4 to your computer and use it in GitHub Desktop.
Indesign extendscript for making selected paragraph styles unique
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // disconnectStyles.jsx | |
| // | |
| // Generated with Gemini 2.5 Pro | |
| // | |
| // DESCRIPTION: | |
| // This script finds all paragraphs in the user's selection. | |
| // For each unique paragraph style applied to those paragraphs, it creates a new, | |
| // duplicated style with a "_new" suffix. It then applies these new styles | |
| // to the corresponding paragraphs, effectively "disconnecting" them from their | |
| // original styles. | |
| // | |
| // USAGE: | |
| // 1. Open an InDesign document. | |
| // 2. Select a text frame, multiple text frames, or a range of text. | |
| // 3. Run this script from the Scripts panel (Window > Utilities > Scripts). | |
| // | |
| // The entire operation can be undone with a single Ctrl+Z (Cmd+Z). | |
| #target indesign | |
| // Main function wrapped for safety and clarity | |
| function main() { | |
| // 1. --- VALIDATION --- | |
| // Check if a document is open | |
| if (app.documents.length === 0) { | |
| alert("Error: No document is open.\nPlease open a document and try again."); | |
| return; | |
| } | |
| var doc = app.activeDocument; | |
| // Check if there is a selection | |
| if (app.selection.length === 0) { | |
| alert("Error: Nothing is selected.\nPlease select a text frame or some text and try again."); | |
| return; | |
| } | |
| // 2. --- GATHER DATA --- | |
| var allParagraphs = []; | |
| var uniqueOriginalStyles = {}; // Use an object as a Set to store unique styles | |
| // Loop through all selected items to gather paragraphs | |
| for (var i = 0; i < app.selection.length; i++) { | |
| var selItem = app.selection[i]; | |
| // Check if the item has paragraphs (e.g., TextFrame, Text, Story) | |
| if (selItem.hasOwnProperty("paragraphs") && selItem.paragraphs.length > 0) { | |
| for (var j = 0; j < selItem.paragraphs.length; j++) { | |
| var para = selItem.paragraphs[j]; | |
| allParagraphs.push(para); | |
| // Store the style object, keyed by its unique ID, to avoid duplicates | |
| uniqueOriginalStyles[para.appliedParagraphStyle.id] = para.appliedParagraphStyle; | |
| } | |
| } | |
| } | |
| if (allParagraphs.length === 0) { | |
| alert("The selection does not contain any text paragraphs."); | |
| return; | |
| } | |
| // 3. --- PROCESS STYLES --- | |
| var styleMap = {}; // This will map original style IDs to the new style objects | |
| var newStylesCreatedCount = 0; | |
| // Iterate over the unique original styles we found | |
| for (var styleId in uniqueOriginalStyles) { | |
| if (uniqueOriginalStyles.hasOwnProperty(styleId)) { | |
| var originalStyle = uniqueOriginalStyles[styleId]; | |
| var baseNewName = originalStyle.name + "_new"; | |
| var finalNewName = baseNewName; | |
| var counter = 1; | |
| // Ensure the new style name is unique to avoid conflicts | |
| while (doc.paragraphStyles.itemByName(finalNewName).isValid) { | |
| finalNewName = baseNewName + "_" + counter; | |
| counter++; | |
| } | |
| // Duplicate the original style. This copies all its settings. | |
| var newStyle = originalStyle.duplicate(); | |
| newStyle.name = finalNewName; | |
| // Store the mapping from the old style ID to the new style object | |
| styleMap[originalStyle.id] = newStyle; | |
| newStylesCreatedCount++; | |
| } | |
| } | |
| // 4. --- APPLY NEW STYLES --- | |
| // Now, loop through the paragraphs again and apply the new styles | |
| for (var k = 0; k < allParagraphs.length; k++) { | |
| var para = allParagraphs[k]; | |
| var originalParaStyleId = para.appliedParagraphStyle.id; | |
| // Check if this paragraph's style is one that we duplicated | |
| if (styleMap[originalParaStyleId]) { | |
| // Apply the new style | |
| para.appliedParagraphStyle = styleMap[originalParaStyleId]; | |
| } | |
| } | |
| // 5. --- FINAL FEEDBACK --- | |
| alert("Script finished!\n\n" + newStylesCreatedCount + " new paragraph styles were created and applied to " + allParagraphs.length + " paragraphs in your selection."); | |
| } | |
| // This `app.doScript` block makes the entire script operation a single undo step. | |
| app.doScript( | |
| main, | |
| ScriptLanguage.JAVASCRIPT, | |
| undefined, | |
| UndoModes.ENTIRE_SCRIPT, | |
| "Disconnect Paragraph Styles" | |
| ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment