Skip to main content
Participating Frequently
March 22, 2025
Question

Script to modify paragraph styles based on user-selected input value

  • March 22, 2025
  • 4 replies
  • 1761 views

Hi,

I'd appreciate any help with the following. First, I'll describe the problem, to estabish context and also open the door for anyone who has a better suggestion than my proposed solution.

The Problem

  • I produce a large range of product documents (user guides, product inserts etc) which use a consistent set of styles. The styles are maintained in their own InDesign document. Every time I edit a document, first thing I do is re-import all the styles, to make sure it's got the latest. This is cumbersome but I don't know of any other way to keep them all in sync.
  •  Several paragraph stylesheets (currently: 4) have numbering styles that contain text prefixes: Appendix, Chapter, Table, and Figure. (Each has its own list style.)
  • Once the English version of a document is ready, it goes to our outsourced translation service. I give them a separate copy of the English 'source document' for each target language. We currently have 4 languages other than English but that will increase over time.
  • The translators have standing instructions to translate the text prefixes in those stylesheets (so 'Table' becomes 'Tabla' in Spanish). But the next time that document is modified (for any reason), I will reimport the stylesheets—thus resetting 'Tabla' to 'Table'.

Proposed Solution

  1.  A script that contains preconfigured sets of prefixes (Appendix, Chapter, Table, and Figure) in each language. I would modify this whenever we add a language. Although I don't know InDesign scripting, I'm familiar with concepts such as variables from other scripting languages like VBA.
  2.  When it is run, the script could pop up a dialog allowing me to choose the language. It would then use that set of prefixes to modify the relevant stylesheets.
  3.  The proposed workflow: before sending a document for translation, I would first reimport all the styles, then run the script.  The translators would receive a document with those terms already translated. The same would happen if the document needs to be modified subsequently (for example, whenever I tweak a stylesheet in my common set, I have to reimport them back into every document, though I don't do this until the next time I modify each document).

Apologies for the lengthy description but I thought it would be helpful to understand the context, especially as I can't be sure the proposed solution is the best one (or even a good one).

Cheers,

--Alistair

4 replies

m1b
Community Expert
Community Expert
March 23, 2025

Hi @Alistair-MB I don't really understand your workflow—there are some things that don't make sense based on the limited info you've given us—but I'll leave that to experts like Joel.

 

However, aside from that, I'm a crazy scripter and this caught my interest, despite that there's a high chance it isn't what you need anyway and might not be the best way to go in any case. So here is a script that renames document styles per configured languages, with a simple UI. Read the script instructions and edit the `settings` object as needed. Will this help?

- Mark

/**
 * @file Rename Styles By Language.js
 *
 * Replaces words in document style names from one configured
 * language list of words to another and also sets the applied language.
 *
 * Edit the `settings` object below as needed.
 *
 * @author m1b
 * @version 2025-03-23
 * @discussion https://community.adobe.com/t5/indesign-discussions/script-to-modify-paragraph-styles-based-on-user-selected-input-value/m-p/15226562
 */
function main() {

    var settings = {

        /** the translation languages; add more as you need. */
        languages: {
            'English': { words: ['Appendix', 'Chapter', 'Figure', 'Table'], appliedLanguage: 'English: USA' },
            'German': { words: ['Anhang', 'Kapitel', 'Abbildung', 'Tabelle'], appliedLanguage: 'German: 2006 Reform' },
            'Spanish': { words: ['Apéndice', 'Capítulo', 'Figura', 'Tabla'], appliedLanguage: 'Spanish' },
        },

        /** the language to translate from */
        fromLanguage: 'English',

        /** the language to translate to */
        toLanguage: 'Spanish',

        /** which document elements to translate */
        translateThese: [
            'allParagraphStyles',
            // 'allCharacterStyles',
            // 'allObjectStyles',
            // 'allCellStyles',
            // 'allTableStyles',
        ],

        /** whether to show UI */
        showUI: true,

        /** whether to show user how many translations were made */
        showResults: false,

    };

    if (0 === app.documents.length)
        return alert('Please open a document and try again.');

    var doc = settings.doc = app.activeDocument;


    // collect all the styles to rename
    var styles = [];

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

        var things = doc[settings.translateThese[i]];

        for (var j = 0; j < things.length; j++)
            styles.push(things[j]);

    }

    if (settings.showUI) {

        var result = ui(settings);

        if (2 === result)
            // user cancelled
            return;

    }

    var counter = 0,
        fromWords = settings.languages[settings.fromLanguage].words,
        toWords = settings.languages[settings.toLanguage].words,
        appliedLanguage = getThing(app.languagesWithVendors, 'name', settings.languages[settings.toLanguage].appliedLanguage);

    // do the renaming
    for (var i = 0; i < styles.length; i++) {

        wordLoop:
        for (var j = 0; j < fromWords.length; j++) {

            if (-1 === styles[i].name.search(fromWords[j]))
                continue wordLoop;

            styles[i].name = styles[i].name.replace(fromWords[j], toWords[j]);

            if (
                styles[i].hasOwnProperty('appliedLanguage')
                && undefined != appliedLanguage
            )
                styles[i].appliedLanguage = appliedLanguage;

            counter++;
        }

    }

    if (settings.showResults)
        alert('Translated ' + counter + ' style names\nfrom ' + settings.fromLanguage + ' to ' + settings.toLanguage + '.');

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Rename Styles By Language');


/**
 * Shows UI for Name Styles By Language
 * @param {Object} settings - the settings to adjust via UI.
 * @returns {1|2} - result code
 */
function ui(settings) {

    // load last-used languages from document
    settings.toLanguage = settings.doc.extractLabel('renameFromLanguage') || settings.toLanguage;
    settings.fromLanguage = settings.doc.extractLabel('renameToLanguage') || settings.fromLanguage;

    var w = new Window("dialog", 'Rename Styles By Language', undefined),

        fromMenuGroup = w.add('group {orientation:"row", alignment:["left","top"], alignChildren: ["left","top"], margins:[10,10,10,20], preferredSize: [120,-1] }'),
        fromlanguageMenu = fromMenuGroup.add('dropDownList { title: "From", preferredSize:[150,-1] }'),
        spacer = fromMenuGroup.add('group {orientation:"column", preferredSize: [20,-1] }'),
        tolanguageMenu = fromMenuGroup.add('dropDownList { title: "To", preferredSize:[150,-1] }'),

        buttons = w.add("Group { orientation: 'row', alignment: ['right','bottom'], margins:[0,0,0,6] }"),
        cancelButton = buttons.add("Button { text:'Cancel', properties:{name:'cancel'} }"),
        renameButton = buttons.add("Button { text:'Rename Styles', enabled:false, enabled: true, name: 'ok' }");

    // populate the language menus
    var fromSelected = 0,
        toSelected = 1,
        index = 0;

    for (var langName in settings.languages) {

        if (settings.languages.hasOwnProperty(langName)) {

            fromlanguageMenu.add('item', langName);
            tolanguageMenu.add('item', langName);

            if (settings.fromLanguage === langName)
                fromSelected = index;
            if (settings.toLanguage === langName)
                toSelected = index;

        }

        index++;

    }

    fromlanguageMenu.selection = fromSelected;
    tolanguageMenu.selection = toSelected;

    renameButton.onClick = function () {

        // update settings
        settings.fromLanguage = fromlanguageMenu.selection.text;
        settings.toLanguage = tolanguageMenu.selection.text;

        // store last-used languages in document
        settings.doc.insertLabel('renameToLanguage', settings.toLanguage);
        settings.doc.insertLabel('renameFromLanguage', settings.fromLanguage);

        // close window with success code
        w.close(1);
    };

    w.center();
    return w.show();

};

/**
 * Returns a thing with matching property.
 * If `key` is undefined, evaluate the object itself.
 * @author m1b
 * @version 2024-04-21
 * @param {Array|Collection} things - the things to look through.
 * @param {String} [key] - the property name (default: undefined).
 * @param {*} value - the value to match.
 * @returns {*?} - the thing, if found.
 */
function getThing(things, key, value) {

    for (var i = 0, obj; i < things.length; i++)
        if ((undefined == key ? things[i] : things[i][key]) == value)
            return things[i];

};

 

Participating Frequently
March 23, 2025

Wow! That looks like a ton of work—thanks so much! Honestly, I'm quite tired right now, and it may be tomorrow before I gather the energy to try it out. (I'm in Australia, by the way.) But I will do so, and let you know.

 

Once I try it out, I will give you some feedback and that may clarify my workflow for you. But in a nutshell: I maintain all the stylesheets in their own InDesign document, which I'll call 'Style Guide'. I use this document to keep the stylesheets in sync across all the working documents: every time I work on a document, I resync from Style Guide using 'Load all text styles'. This ensures every document is constantly updated with the latest set of stylesheets. 

 

Some stylesheets have numbering styles that use prefixes: for example, images are auto-numbered Figure 1, Figure 2, Figure n by a stylesheet ('Caption') that contains the number code:

Figure ^#:^>

 

When the document is translated (say, to Italian), that comes back to me as:

 

Figura ^#:^>

 

Sometime later, I make a change to 'Style Guide'. Perhaps the Table Label style gets modified. Or a different style. Or maybe I'm making another new document type which requires a whole new stylesheet.

 

Now I'm asked to replace a screenshot of our software which appears in our Italian document. This doesn't require translation: it's a straight replacement. Even the caption (Figura 2) won't change. However, when I open the Italian document, my process requires me to reimport all the stylesheets. At which point, the Caption stylesheet reverts from Figura  to Figure. Meaning, I then have to then go and change it back manually.

 

Of course, one might ask: if none of the stylesheets in my Italian document are affected by the change to Style Guide, why reimport them? Because it becomes virtually impossible to track which stylesheets are used in which documents and when they were last updated. I would need to keep a log and analyze it every time I open a document: "The styles in this Italian document were last updated on mm/dd/yyyy. Since then, the following changes have been to Style Guide. Do I need to reupdate the stylesheets in this Italian document now, or not?"

 

But I avoid all that through discipline: every document always has the same set of stylesheets, and I know this, because every time I open a document I reload the styles regardless of whether I need to or not. I don't even need to think about, which in fact is sort of the point. But it does mean a lot of manual work re-updating styles which are localized.

 

I'll apologize if none of that made sense, but as mentioned, very tired. I'll try the script and let you know. Cheers!

Robert at ID-Tasker
Legend
March 23, 2025
quote

[...] However, when I open the Italian document, my process requires me to reimport all the stylesheets. At which point, the Caption stylesheet reverts from Figura  to Figure. Meaning, I then have to then go and change it back manually.[...] 


By @Alistair-MB

 

Unless I'm missing something - you could have different stylesheets - for each language - and use them before and after the translation?

 

Joel Cherney
Community Expert
Community Expert
March 23, 2025

One of the day-to-day tasks I perform for translation firms on a regular basis is to prepare InDesign files for translation. Similarly, I frequenly advise businesses and organizations that use external translations services on how they can improve their own translation workflows and reduce translation costs. (In other words, this isn't the first time I've seen your question.) There is a wide variety of tools that these translation providers use, and your question somewhat implies that you're imagining what being a localization engineer might be like. So, when you propose the idea that you could pre-translate parts of the document before assignment with a custom tool, in order to save yourself effort after you get the translated documents back? There is an entire world of enterprise-class tools to do exactly that.  And, pardon me for being a little  bit flippant here, every time your InDesign files cross the desktops of your provider's localization engineers, they're letting out a little world-weary sigh and undoing some of your preparatory work.

 

See, any reasonably technically proficient firm on the planet is using a tool that consumes IDML exported from InDesign. Very rarely are you going to find that your InDesign files are being opened up in InDesign by your Spanish translators.  More likely, your text gets extracted and is processed (translated by humans, translated by machines, terminology controlled from client glossaries, post-translation editing, etc.) in tools that aren't graphic design tools at all. 

 

One of my jobs, broadly speaking, is to make sure that the tool that is consuming your work can actually process all of the text, in human-readable units. So when you say

 

Several paragraph stylesheets (currently: 4) have numbering styles that contain text prefixes: Appendix, Chapter, Table, and Figure. 

 

I know that your entry in my client's workflow tool or CRM module or whatever would have this fact noted, and it'd be my job to automate the process of getting terms like "Appendix" out of the paragraph style, and into the live text. Then I'd build a tool to put it back in there after transation, because the last thing I'd want to do is to have my client deliver something to you that didn't match what you'd sent. Clearly, your provider isn't doing that step, or it'd say "capítulo" in your styles in your Spanish doc where it says "chapter" in English.

 

So if you really wanted to make this process faster & less troublesome for everyone, you should be raising these questions directly with your provider. I don't know what tools they use, so I don't know what optimizations to your workflow would be the most likely to make it so you wouldn't have to go looking for custom tool development to preserve your tablas and your capítulos. I don't assume that you doing pre-translation with a custom tool is the best way, but it might well be, depending on business conditions. Better to go back to your provider and talk about how you need to post-process their deliveries, and if my guesses are correct, they'll come back with "Well, we need to pre-process your assignments! We're working at cross-purposes here; let's stop ." 

 

But if you don't have that kind of relationship with your provider, two ideas spring immediately to mind: 

 

1) One element of a paragraph style in InDesign is the language. Why don't you have a separate Spanish style template that already has your tablas and your capítulos? That means more style management work on your end, of course, but if you're working with Spanish text, it really ought to be marked as Spanish, right? And there are ways to automate away some of that style-management effort. 

 

2) In general, I'd say live text doesn't belong in paragraph styles. I mean, where is it? In Bullets and Numbering? Edit your master styles to remove all text that you mean to have translated, and put it in the live text. That's what I'd do, in my hypothetical job as the loc engineer preprocessing your files. 

 

Participating Frequently
March 23, 2025

Thanks for your detailed and considered reply. As I made clear in my original post, I'm well aware that my proposed solution may not be right, and when I invited alternative suggestions, I did so sincerely. If 45 years in production has taught me anything, it's that it's never safe to make assumptions about someone else's workflow or the reasons behind it. So, no, I am not attempting to imagine how a localization engineer works. Indeed, this wasn't about how they work at all, and I apologise if that wasn't clear. It's about how I work. But I'll come back to that later.

 

My working relationship with our translation service is, as far as I'm aware, open and co-operative. I certainly don't try to tell them how to do their job: I'm busy enough trying to do my own. There is no way I am going to spend even 1 minute of effort in attempting to make something easier or better for them, unless they have specifically told me it's what they want. I have provided detailed but succinct documentation on our stylesheets and made it clear that if there's anything they'd like me to do differently, my door (and more importantly, my attitude) is open. So far, the only feedback has been to say "much appreciated". I'm not aware if it was accompanied by a little world-weary sigh or not—but if it was, that's on them. You can lead a horse to water…

 

The purpose of my solution isn't so that I can pre-translate these prefixes. It's so that I don't lose the translations when I need to re-sync the stylesheets after they return the documents to me. If the entire document needs to be retranslated, it doesn't matter. But if I am simply changing a few stylesheets, I have no reason to send it back (and can't justify the time and expense of doing so). I just want to reimport my standard stylesheets, then run a script to change all the prefixes back to their required languages. (In my original post, I did float the idea of also running that script before I send them a document in English, but I take your point that it's unnecessary and undesirable.)

 

Yes, I could have separate stylesheets, or even separate style templates, for each language, but I don't see how that solves the issue. Because, for Latin, Greek and Cyrillic writing systems, all the stylesheets ultimately derive from the English: if I change a stylesheet setting in English, I still need to sync it the others, no matter where they live. And then they will lose their localization and it will have to be redone. I can (and currently do) keep a record of each prefix translated into each language; each time I reimport the stylesheets, I go through and restore all the tabelles and tabelas manually. But even with four foreign languages, it's a pain, and four will soon grow into doube figures.

 

As for live text, I agree with you in general. But I am using InDesign's Paragraph Style: Numbering feature because, as far as I know, that's the only way to automate the numbering. If there's another way that I can have figures, tables, chapters and appendices automatically numbered Figure 1, Figure 2, Figure 3 etc, then believe me, I'm all ears!

 

Thanks again.

Robert at ID-Tasker
Legend
March 23, 2025

This could, in some way, be made a bit easier for you if you would use Book feature - but if you work on Windows - all this and way more of your mundane clicking - can be easily automated using my ID-Tasker tool - but it's not free and Windows only. 

 

With my tool - it could be a one-click-solution for you - first "export" for translation - then "import" - including creation of one combined file with each translation on a separate / dedicated layer - if needed - including copy of the whole Styles Structure, localised images / graphics, etc. 

 

And by "export" I mean full service - separate folders with correctly named files, etc. - including creation of packages - File -> Package and/or ZIP / RAR archive - and - if the translation company has an FTP server - automatic upload - and then download. 

 

And all that - just for starters 😉 

 

And if the translation company isn't "fitting" texts - they only process IDML files without opening them in the InDesign - or you would prefer to do it "in house" - this also can be fully/semi automated - your choice. 

 

Participating Frequently
March 22, 2025

Oops! I just realized that the script would also need to modify TOC styles: [Default], Tables, and Figures.

Cheers,

--Alistair