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

How do I automatically set numbering for paragraph styles in multiple unconnected text boxes?

Guide ,
Sep 14, 2024 Sep 14, 2024

InDesign's numbering feature seems to only support paragraph styles in connected text boxes by default.
In fact, sometimes we have to set automatic numbering for paragraphs in separate text boxes.
How to solve this problem?
Thank you.

005.png

TOPICS
Bug , Feature request , How to , Performance , Scripting
1.1K
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 2 Correct answers

Community Expert , Sep 14, 2024 Sep 14, 2024

Follow the nonobvious but essential InDesign rule  —"Never use [default] anything!"

 

If you create a numbered style and allow it to remain at the [Default] numbering list, it will want to restart in each box. If you create a specific numbering list, it will number across the text boxes. (Only the master Jedi ID developers know why, but this kind of quirk is why you don't use any default style or setting.)

 

JamesGiffordNitroPress_0-1726369882368.png

 

But there's still a catch: you have to get the text boxes in the correct order, as th

...
Translate
Community Expert , Sep 16, 2024 Sep 16, 2024

Haha, so sorry it was a bit complicated! The point was to show a range of examples.

 

But you do make a good point that it would really help to have a UI. I've added one to the version below.

Screenshot 2024-09-17 at 13.12.52.png

I did it fast, so hopefully no bugs! Note: it only does one numbering scheme at a time, but that will be fine for most people. To use it without the UI, just configure `numberings` and set `settings.showUI: false`.

- Mark

 

 

/**
 * @File Apply Numbering.js
 *
 * Searches document for "numberings" which ar
...
Translate
Community Expert ,
Sep 14, 2024 Sep 14, 2024

Follow the nonobvious but essential InDesign rule  —"Never use [default] anything!"

 

If you create a numbered style and allow it to remain at the [Default] numbering list, it will want to restart in each box. If you create a specific numbering list, it will number across the text boxes. (Only the master Jedi ID developers know why, but this kind of quirk is why you don't use any default style or setting.)

 

JamesGiffordNitroPress_0-1726369882368.png

 

But there's still a catch: you have to get the text boxes in the correct order, as the numbering seems to be bound to order of creation.

 

 

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
Guide ,
Sep 14, 2024 Sep 14, 2024

extremely grateful
This seems to be running very hard.
My files are all screwed up.

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
LEGEND ,
Sep 15, 2024 Sep 15, 2024

Why not link those TFs together? Or with the rest of 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
Community Expert ,
Sep 15, 2024 Sep 15, 2024

Hi @dublove, I have made an alternative approach that may be useful sometimes if the built-in numbering is too much trouble.

 

This script applies numbering based on the configured criteria, such as applied Paragraph Style or Character Style. As an example I have configured three different numberings—a Heading numberer, a Figure numberer and a "Footnote-like" symbol numberer (the magenta superscript numbers). See the attached demo.indd.

 

It is a very lightweight approach, and if anything is reordered in your document, you must run the script again to update the numbering. To use it, you must configure the script according to your document, such as entering your heading paragraph style(s) and whether you want the script to prefer horizontal sorting over vertical sorting (the demo uses horizontal, but your example above would need vertical).

- Mark

 

Demo document. None of the frames are threaded.Demo document. None of the frames are threaded.

 

/**
 * @file Apply Numbering.js
 *
 * Searches document for "numberings" which are configured
 * in the script, then sorts the results and applies numbering.
 * 
 * To use, first configure your numberings array to match your document.
 * 
 * Notes:
 * 
 *   - `preferHorizontal` means wether to prefer horizontal sorting
 *     over vertical sorting.
 * 
 *   - `padWithZeros` is the count of how many digits you want, for example
 *     the number 24 with padWithZeros of 4 gives '0024'.
 * 
 *   - `stopAfterFirstNumberInParagraph` means whether to apply numbering
 *     to subsequent numbers found in the same paragraph. For example,
 *     if your heading was "12. The 2024 Economy", we would want it to
 *     leave "2024" untouched, so stopAfterFirstNumberInParagraph = true,
 *     which is the default.
 * 
 * @author m1b
 * @version 2024-09-15
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-do-i-automatically-set-numbering-for-paragraph-styles-in-multiple-unconnected-text-boxes/m-p/14860638
 */
function main() {

    // EDIT YOUR CONFIGURATION BELOW

    /* ------------------------ *
     *  Example numberings      *
     * ------------------------ */
    var numberings = [

        {
            findGrepPreferences: {
                findWhat: '\\b\\d+\\b',
                appliedParagraphStyle: 'Numbered Heading',
            },
            padWithZeros: 3,
            preferHorizontal: true,
        },

        {
            findGrepPreferences: {
                findWhat: '\\b\\d+\\b',
                appliedParagraphStyle: 'Numbered Figure',
            },
            preferHorizontal: true,
        },

        {
            // here we want to number every instance
            // even if it's in the same paragraph
            stopAfterFirstNumberInParagraph: false,
            findGrepPreferences: {
                findWhat: '\\d+\\b',
                appliedCharacterStyle: 'Numbered Symbol',
            },
            preferHorizontal: true,
        },

    ];

    var settings = {

        // text frames that are within 3 pt are considered aligned
        defaultTolerance: 5,

        // whether horizontal sorting should win against vertical sorting
        defaultPreferHorizontal: false,

        // default find grep options
        defaultFindGrepOptions: {
            includeLockedLayersForFind: false,
            includeLockedStoriesForFind: false,
            includeHiddenLayers: false,
            includeFootnotes: true,
            includeMasterPages: false,
            searchBackwards: false,
        },

    };

    // END OF CONFIGURATION

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

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    var doc = app.activeDocument;

    // perform each numbering
    for (var i = 0, numbering, numberables, numberables; i < numberings.length; i++) {

        numbering = numberings[i];

        if (!numbering.findGrepPreferences)
            continue;

        app.findGrepPreferences = NothingEnum.NOTHING;
        app.findGrepPreferences.properties = numbering.findGrepPreferences;
        app.findChangeGrepOptions.properties = numbering.findChangeGrepOptions || settings.defaultFindGrepOptions;

        // find the numbers
        numberables = doc.findGrep();

        // remove illegal numbers
        if (false !== numbering.stopAfterFirstNumberInParagraph)
            numberables = getFirstFoundInParagraph(numberables);

        // sort
        numberables.sort(getSorter({
            tolerance: numbering.tolerance || settings.defaultTolerance,
            preferHorizontal: numbering.preferHorizontal || settings.defaultPreferHorizontal,
        }));

        // apply numbering
        for (var len = numberables.length, j = len - 1, n = len; j >= 0; j--, n--) {

            numberables[j].contents = numbering.padWithZeros
                ? ('00000000' + n).slice(-numbering.padWithZeros)
                : String(n);

        }

    }

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Apply Numbering');

/**
 * Returns a sorting function suitable
 * for sorting numberable text.
 * 
 * Numberables with x or y values that are
 * within `tolerance` pts are considered aligned.
 * 
 * @author m1b
 * @version 2024-09-15
 * @param {Number} tolerance - the x or y distance in pts.
 * @returns {Function}
 */
function getSorter(options) {

    options = options || {};

    return (function (tolerance, preferHorizontal) {

        return function sortTextByFramePosition(a, b) {

            // compare same story index
            if (a.parentStory.id === b.parentStory.id)
                return a.index - b.index;

            // compare page index
            if (a.parentTextFrames[0].parentPage.documentOffset !== b.parentTextFrames[0].parentPage.documentOffset)
                return a.parentTextFrames[0].parentPage.documentOffset - b.parentTextFrames[0].parentPage.documentOffset;

            // compare top left of text frame
            var ab = a.parentTextFrames[0].geometricBounds,
                bb = b.parentTextFrames[0].geometricBounds,
                dx = Math.abs(ab[1] - bb[1]),
                dy = Math.abs(ab[0] - bb[0]),
                result;

            if (!preferHorizontal) {

                if (dy > tolerance)
                    result = ab[0] - bb[0];

                if (!result && dx > tolerance)
                    result = ab[1] - bb[1]

            }

            else {

                if (dx > tolerance)
                    result = ab[1] - bb[1];

                if (!result && dy > tolerance)
                    result = ab[0] - bb[0]

            }

            return result || 0;

        };

    })(options.tolerance || 0, true === options.preferHorizontal);

};

/**
 * Returns an array of only the first text
 * instance of `found` in each paragraph.
 * Note: assumes that `found` is in the
 * usual findGrep order.
 * @author m1b
 * @version 2024-09-15
 * @param {Array<Text>} found - the text to filter.
 * @returns {Array<Text>}
 */
function getFirstFoundInParagraph(found) {

    var firstOnly = [];

    for (var j = 0, para = undefined; j < found.length; j++) {

        if (found[j].paragraphs[0] !== para)
            firstOnly.push(found[j])

        para = found[j].paragraphs[0];

    }

    return firstOnly;

};

 

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
Guide ,
Sep 15, 2024 Sep 15, 2024

@m1b 

You're too great.

Thank you.
But it's a bit complicated, I just want to change the numbering of a certain paragraph style.
And of course you have a script that sets the numbering of the character styles, which is great.

But without the panel, it's not easy to control.

Can't I select a paragraph style, or a character style, and run it and have it automatically numbered?

It's too much trouble to edit the script every time.

 

How come there's still a purple superscript?
There shouldn't normally be a need for such complexity.
Keeping it simple would be fine.
Character styles and paragraph styles are independently controllable and optional.

 

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 ,
Sep 16, 2024 Sep 16, 2024

Haha, so sorry it was a bit complicated! The point was to show a range of examples.

 

But you do make a good point that it would really help to have a UI. I've added one to the version below.

Screenshot 2024-09-17 at 13.12.52.png

I did it fast, so hopefully no bugs! Note: it only does one numbering scheme at a time, but that will be fine for most people. To use it without the UI, just configure `numberings` and set `settings.showUI: false`.

- Mark

 

 

/**
 * @File Apply Numbering.js
 *
 * Searches document for "numberings" which are configured
 * in the script, then sorts the results and applies numbering.
 *
 * To use, either configure script to show UI for figuring ONE
 * numbering scheme, or set `settings.showUI` to false if you
 * want to configure multiple numberings at once.
 *
 * Notes:
 *
 *   - `preferHorizontal` means wether to prefer horizontal sorting
 *     over vertical sorting.
 *
 *   - `padWithZeros` is the count of how many digits you want, for example
 *     the number 24 with padWithZeros of 4 gives '0024'.
 *
 *   - `onlyFirstNumberInParagraph` means whether to stop after applying
 *     numbering to the first found number in a paragraph. For example,
 *     if your heading was "12. The 2024 Economy", we would want it to
 *     leave "2024" untouched, so onlyFirstNumberInParagraph = true,
 *     which is the default. However, for footnote-type numbering, you
 *     would set it to false because a paragraph could have several.
 * 
 *   - change the values in `settings.defaultFindGrepOptions` to configure
 *     the find grep options.
 *
 * @author m1b
 * @version 2024-09-17
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-do-i-automatically-set-numbering-for-paragraph-styles-in-multiple-unconnected-text-boxes/m-p/14860638
 */
function main() {

    // EDIT YOUR CONFIGURATION BELOW

    var settings = {

        // text frames that are within 3 pt are considered aligned
        defaultTolerance: 5,

        // whether horizontal sorting should win against vertical sorting
        defaultPreferHorizontal: false,

        // default find grep options
        defaultFindGrepOptions: {
            includeLockedLayersForFind: false,
            includeLockedStoriesForFind: false,
            includeHiddenLayers: false,
            includeFootnotes: true,
            includeMasterPages: false,
            searchBackwards: false,
        },

        // whether to show the UI, but if so,
        // only the first numbering will execute
        showUI: true,

    };

    /* --------------------------------- *
     *  Example numberings               *
     * --------------------------------- *
     * Note: if using the UI, then only  *
     * the first example will be active. *
     * --------------------------------- */
    var numberings = [

        {
            findGrepPreferences: {
                findWhat: '\\b\\d+\\b',
                appliedParagraphStyle: 'Numbered Heading',
            },
            padWithZeros: 3,
            preferHorizontal: true,
        },

        {
            findGrepPreferences: {
                findWhat: '\\b\\d+\\b',
                appliedParagraphStyle: 'Numbered Figure',
            },
            preferHorizontal: true,
        },

        {
            // this numbering example is for "footnote" style
            // numbering, where we want to number every instance
            // even if it's in the same paragraph
            findGrepPreferences: {
                findWhat: '\\d+\\b',
                appliedCharacterStyle: 'Numbered Symbol',
            },
            onlyFirstNumberInParagraph: false,
            preferHorizontal: true,
        },

    ];

    // END OF CONFIGURATION

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

    var doc = settings.doc = app.activeDocument;
    settings.numberings = numberings;
    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    if (settings.showUI) {

        var result = ui(settings);

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

        if (undefined != settings.cleanup) {
            settings.cleanup();
            delete settings.cleanup;
        }

    }

    // perform each numbering
    for (var i = 0, numbering, found, found; i < settings.numberings.length; i++) {

        numbering = settings.numberings[i];

        if (!numbering.findGrepPreferences)
            continue;

        app.findGrepPreferences = NothingEnum.NOTHING;
        app.findGrepPreferences.properties = numbering.findGrepPreferences;
        app.findChangeGrepOptions.properties = numbering.findChangeGrepOptions || settings.defaultFindGrepOptions;

        // find the numbers
        found = doc.findGrep();

        // remove illegal numbers
        if (false !== numbering.onlyFirstNumberInParagraph)
            found = getFirstFoundInParagraph(found);

        // sort
        found.sort(getSorter({
            tolerance: numbering.tolerance || settings.defaultTolerance,
            preferHorizontal: numbering.preferHorizontal || settings.defaultPreferHorizontal,
        }));

        // apply numbering
        for (var len = found.length, j = len - 1, n = len; j >= 0; j--, n--) {

            found[j].contents = numbering.padWithZeros
                ? ('00000000' + n).slice(-numbering.padWithZeros)
                : String(n);

        }

    }

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Apply Numbering');

/**
 * Returns a sorting function suitable
 * for sorting numberable text.
 *
 * Numberables with x or y values that are
 * within `tolerance` pts are considered aligned.
 *
 * @author m1b
 * @version 2024-09-15
 * @Param {Number} tolerance - the x or y distance in pts.
 * @Returns {Function}
 */
function getSorter(options) {

    options = options || {};

    return (function (tolerance, preferHorizontal) {

        return function sortTextByFramePosition(a, b) {

            // compare same story index
            if (a.parentStory.id === b.parentStory.id)
                return a.index - b.index;

            // compare page index
            if (a.parentTextFrames[0].parentPage.documentOffset !== b.parentTextFrames[0].parentPage.documentOffset)
                return a.parentTextFrames[0].parentPage.documentOffset - b.parentTextFrames[0].parentPage.documentOffset;

            // compare top left of text frame
            var ab = a.parentTextFrames[0].geometricBounds,
                bb = b.parentTextFrames[0].geometricBounds,
                dx = Math.abs(ab[1] - bb[1]),
                dy = Math.abs(ab[0] - bb[0]),
                result;

            if (!preferHorizontal) {

                if (dy > tolerance)
                    result = ab[0] - bb[0];

                if (!result && dx > tolerance)
                    result = ab[1] - bb[1]

            }

            else {

                if (dx > tolerance)
                    result = ab[1] - bb[1];

                if (!result && dy > tolerance)
                    result = ab[0] - bb[0]

            }

            return result || 0;

        };

    })(options.tolerance || 0, true === options.preferHorizontal);

};

/**
 * Returns an array of only the first text
 * instance of `found` in each paragraph.
 * Note: assumes that `found` is in the
 * usual findGrep order.
 * @author m1b
 * @version 2024-09-15
 * @Param {Array<Text>} found - the text to filter.
 * @Returns {Array<Text>}
 */
function getFirstFoundInParagraph(found) {

    var firstOnly = [];

    for (var j = 0, para = undefined; j < found.length; j++) {

        if (found[j].paragraphs[0] !== para)
            firstOnly.push(found[j])

        para = found[j].paragraphs[0];

    }

    return firstOnly;

};


/**
 * Shows UI for Apply Numbering script,
 * allowing for only one numbering scheme.
 * @Param {Object} settings - the settings to adjust.
 * @Returns {1|2} - result code
 */
function ui(settings) {

    // the UI only handles one numbering scheme
    if (settings.numberings.length > 1)
        settings.numberings.splice(1, settings.numberings.length - 1)

    // try to load numbering from document
    var key = 'm1b_applyNumbering',
        savedValues = settings.doc.extractLabel(key);

    if (savedValues && savedValues.length > 0)
        settings.numberings[0] = reviveNumbering(savedValues);

    var w = new Window("dialog", 'Apply Numbering', undefined, { closeButton: false }),

        // numberings
        numberingsGroup = w.add("group {orientation:'column', alignment:['fill','top'], margins: [0,0,0,0] }"),
        numberingUI = numberingUI(numberingsGroup, 0, settings.numberings[0]),

        bottomUI = w.add("group {orientation:'row', alignment:['fill','top'], margins: [0,0,0,0] }"),
        extraControls = bottomUI.add("group {orientation:'row', alignChildren: ['left','center'] alignment:['fill','center'] }"),
        saveInDocCheckBox = extraControls.add("CheckBox { text: 'Save these settings in document', alignment:['left','bottom'] }"),
        buttons = bottomUI.add("group {orientation:'row', alignment:['right','top'], alignChildren:'right' }"),
        cancelButton = buttons.add('button', undefined, 'Cancel', { name: 'cancel' }),
        applyButton = buttons.add('button', undefined, 'Apply', { name: 'ok' });

    // event handling
    applyButton.onClick = apply;

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

    /**
     * Executes the numbering by closing
     * dialog with return code 1.
     */
    function apply() {

        // update numbering
        settings.numberings = [numberingUI.getNumbering()];

        if (saveInDocCheckBox.value) {
            settings.cleanup = function () {
                // save values in document
                settings.doc.insertLabel(key, serializeNumbering(settings.numberings[0]));
            };
        }

        // finished with dialog
        w.close(1);

    };

    /**
     * Returns a default numbering.
     * @Returns {Object}
     */
    function defaultNumbering() {

        return {
            findGrepPreferences: { findWhat: '\\b\\d+\\b', appliedParagraphStyle: 'X' },
            preferHorizontal: false,
            padWithZeros: 0,
            onlyFirstNumberInParagraph: true,
        };

    };

    /**
     * Creates the UI for a numbering.
     * @Param {SUI Group|SUI Window} container - the location of the new numbering group.
     * @Param {Number} numIndex - the index to the numberings array.
     * @Param {Object} numbering - the numbering object.
     * @Returns {SUI Group?}
     */
    function numberingUI(container, numIndex, numbering) {

        var styleMenu,
            targets = ['Character Style', 'Paragraph Style'],
            suppressTriggers = false;

        var group = container.add("group {orientation:'column', margins:[5,5,5,0] }"),
            panel = group.add("panel {orientation:'row', alignChildren: ['left','center'], alignment:['fill','top'], margins: [5,5,5,0] }"),
            column1 = panel.add("group {orientation:'column', alignment:['fill','top'], margins: [20,20,20,20] }"),
            row1 = column1.add("group {orientation:'row', alignChildren: ['left','center'] alignment:['fill','top'] }"),
            row2 = column1.add("group {orientation:'row', alignChildren: ['left','center'] alignment:['fill','top'] }"),

            findWhatLabel = row1.add('statictext', undefined, 'Find Numbers Grep:'),
            findWhatField = row1.add('edittext'),
            inLabel = row1.add('statictext { text:" in ", alignment:["left","center"], preferredSize:[25,-1] }'),
            targetMenu = row1.add('dropDownList { preferredSize:[120,-1] }'),
            styleMenu = row1.add("Dropdownlist {alignment:['left','center']}"),

            // checkboxes
            onlyFirstNumberCheckbox = row2.add("CheckBox { text: 'Only First Number In Paragraph' }"),

            // radio button
            sortPreferenceGroup = row2.add('group {orientation:"row", alignment:["fill","center"], alignChildren:["left","center"], margins:[25,2,0,0] }'),
            marginGroup = sortPreferenceGroup.add('group {orientation:"row", alignment:["center","center"], margins:[0,0,0,5]}'),
            sortPreferenceLabel = marginGroup.add('statictext { text:"Sorting Preference", alignment:["left","center"] }'),
            preferHorizontalRadio = sortPreferenceGroup.add('radiobutton {text:"Horizontal"}'),
            preferVerticalRadio = sortPreferenceGroup.add('radiobutton {text:"Vertical"}'),

            padWithZerosGroup = row2.add("group {orientation:'row', alignChildren: ['right','center'] alignment:['fill','center'], margins:[0,0,0,4] }"),
            padWithZerosLabel = padWithZerosGroup.add('statictext', undefined, 'Pad With Zeros:'),
            padWithZerosField = padWithZerosGroup.add('edittext {preferredSize: [30,-1]}');

        group.index = numIndex;

        // add targets
        for (var i = 0; i < targets.length; i++)
            targetMenu.add('item', targets[i]);

        // set sizes
        var labelWidth = 120,
            fieldWidth = 200;

        findWhatLabel.preferredSize.width = labelWidth;
        findWhatField.preferredSize.width = fieldWidth;
        targetMenu.preferredSize.width = labelWidth;
        styleMenu.preferredSize.width = fieldWidth;

        targetMenu.onChange = function (ev) { updateTarget(this.selection.index) };
        group.update = updateNumberingUI;
        group.getNumbering = getNumbering;

        /**
         * Returns a numbering object derived from the UI.
         * @Returns {Object}
         */
        function getNumbering() {

            var numbering = {
                findGrepPreferences: {
                    findWhat: findWhatField.text,
                },
                padWithZeros: Number(padWithZerosField.text),
                preferHorizontal: true === preferHorizontalRadio.value,
                onlyFirstNumberInParagraph: true == onlyFirstNumberCheckbox.value,
            };

            if (isNaN(numbering.padWithZeros))
                numbering.padWithZeros = 0;

            // add the applied style name
            var findGrepKey = ['appliedCharacterStyle', 'appliedParagraphStyle'][targetMenu.selection.index];
            numbering.findGrepPreferences[findGrepKey] = styleMenu.selection.text;

            return numbering;

        };

        /**
         * Update UI from `numbering` object.
         */
        function updateNumberingUI() {

            findWhatField.text = numbering.findGrepPreferences.findWhat;
            preferHorizontalRadio.value = true === numbering.preferHorizontal;
            preferVerticalRadio.value = true !== numbering.preferHorizontal;
            padWithZerosField.text = String(numbering.padWithZeros || 0);
            onlyFirstNumberCheckbox.value = false !== numbering.onlyFirstNumberInParagraph;

        };

        if (numbering.findGrepPreferences.appliedCharacterStyle)
            updateTarget(0);
        else
            updateTarget(1);


        /**
         * Populates the target menu.
         * @Param {0|1} targetType - character styles or paragraph styles.
         */
        function updateTarget(targetType) {

            if (suppressTriggers)
                return;
            else
                suppressTriggers = true;

            var things,
                targetProp;

            if (0 === targetType) {
                // target: character styles
                things = settings.doc.allCharacterStyles
                targetProp = 'appliedCharacterStyle';
            }

            else {
                // target: paragraph styles
                things = settings.doc.allParagraphStyles
                targetProp = 'appliedParagraphStyle';
            }

            var list = getThingsWithGetter(things, excludeBracketItems);

            if (0 === list.length)
                throw new Error('Could not find ' + targetProp + '.');

            var value = numbering.findGrepPreferences[targetProp] || list[0];

            // clear the existing menu
            styleMenu.removeAll();

            for (var i = 0; i < list.length; i++)
                styleMenu.add('item', list[i]);

            targetMenu.selection = targetType;

            // set menu index
            var menuIndex;
            for (var i = 0; i < list.length; i++) if (value === list[i]) { menuIndex = i; break; };
            styleMenu.selection = menuIndex || 0;

            suppressTriggers = false;

        };

        // updateTarget();
        group.update();

        return group;

    };

};

/**
 * Returns source string from a stringified RegExp.
 * eg, '/^Z.*$/gi' -> '^Z.*$'
 * @Param {String/RegExp} obj - the object to parse.
 * @Returns {?String}
 */
function regexSource(obj) {

    var parts = String(obj).match(/^\/(.*)\/([gimsuy]*)$/) || {};

    if (parts[1])
        return parts[1];

}

/**
 * Returns an array of things by applying `getter` function.
 *
 * Example getter:
 *   function (thing, index) {
 *     if (/^[/.test(thing.name))
 *       return thing;
 *   }
 *
 * @author m1b
 * @version 2024-09-16
 * @Param {Array|Collection} things - the things to look through.
 * @Param {Function} getter - a function that returns a thing to get.
 * @Returns {Array<*>} - the things found.
 */
function getThingsWithGetter(things, getter) {

    var found = [];

    for (var i = 0, thing; i < things.length; i++) {

        thing = getter(things[i], i);

        if (thing)
            found.push(thing);

    }

    return found;

};

/**
 * Filter to exclude item's whose name
 * starts with square bracket, eg. '[None]'.
 * @Param {*} thing - a thing with a `name`.
 * @Returns {*?}
 */
function excludeBracketItems(thing) {
    if (!/^\[/.test(thing.name))
        return thing.name;
};

function serializeNumbering(numbering) {

    var targetProperty = numbering.findGrepPreferences.appliedCharacterStyle ? 'appliedCharacterStyle' : 'appliedParagraphStyle',
        targetType = numbering.findGrepPreferences.appliedCharacterStyle ? 0 : 1,
        styleName = numbering.findGrepPreferences[targetProperty],
        findWhat = numbering.findGrepPreferences.findWhat,
        preferHorizontal = true === numbering.preferHorizontal ? 1 : 0,
        padWithZeros = numbering.padWithZeros || 0,
        onlyFirstNumber = true === numbering.onlyFirstNumberInParagraph ? 1 : 0;

    return [
        targetType,
        styleName,
        findWhat,
        padWithZeros,
        preferHorizontal,
        onlyFirstNumber,
    ].join('###');

};

function reviveNumbering(serialized) {

    var values = serialized.split('###'),

        numbering = {
            findGrepPreferences: {
                findWhat: values[2],
            },
            padWithZeros: Number(values[3]),
            preferHorizontal: '1' === values[4],
            onlyFirstNumberInParagraph: '1' === values[5],
        };

    if (isNaN(numbering.padWithZeros))
        numbering.padWithZeros = 0;

    // add the applied style name
    var findGrepKey = ['appliedCharacterStyle', 'appliedParagraphStyle'][Number(values[0])];
    numbering.findGrepPreferences[findGrepKey] = values[1];

    return numbering;

};

 

 

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
Guide ,
Sep 18, 2024 Sep 18, 2024
LATEST

Tried it and it's great.
Awesome.
Very impressive.
Thank you very much.

 

Suggests splitting into three options:
① the current selection
② the same article (connected text box)
③ the entire document (now for the entire document)

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