Skip to main content
Participant
July 25, 2024
Question

Indesign Table Script

  • July 25, 2024
  • 1 reply
  • 168 views

Hi Everyone! I am making a book on word search. I made it but I want to add random alphabets in blank table cells! Is there any Sript to solve it.

This topic has been closed for replies.

1 reply

m1b
Community Expert
Community Expert
July 25, 2024

Hi @Kunal98C6, this was a fun question! I've written a script to do this. Please give it a try and let me know how it goes.

- Mark

 

/**
 * @file Add Table Random Letters.js
 *
 * Adds random letters to empty table cells.
 * Chooses more common letters more often.
 *
 * Note: you can run script again and again
 * until you are happy - it shouldn't overwrite
 * your original text. It stores the empty
 * cell coordinates in a label so it knows
 * where to re-populate.
 *
 * @author m1b
 * @version 2024-07-25
 * @discussion https://community.adobe.com/t5/indesign-discussions/indesign-table-script/m-p/14758845
 */
function main() {

    var settings = {

        // these are in order of most common first
        letters: 'ETAOINSHRDLUCMFYWGPBVKXQJZ',

    };

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

    var doc = app.activeDocument,
        table = getTable(doc.selection);

    if (!table)
        return alert('Please select a table and try again.');

    var letters = settings.letters;

    // first collect empty cells
    var emptyCells = table.extractLabel('emptyCells') || [];

    if (0 == emptyCells.length) {

        for (var i = 0; i < table.cells.length; i++)
            if ('' == table.cells[i].contents)
                emptyCells.push(table.cells[i].name);

        table.insertLabel('emptyCells', String(emptyCells));

    }

    else if ('String' === emptyCells.constructor.name) {
        emptyCells = emptyCells.split(',');
    }

    for (var i = 0, xy, cell; i < emptyCells.length; i++) {
        xy = emptyCells[i].split(':');
        cell = table.rows[Number(xy[1])].cells[Number(xy[0])];

        if (!cell.isValid)
            continue;

        cell.contents = letters[weightedRandom(0, letters.length - 1, 5, 1)];

    }

}
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Add Table Random Letters');


/**
 * Attempts to return a Table, given an object.
 * @author m1b
 * @version 2023-02-06
 * @param {InsertionPoint|Text|Cells|Table|TextFrame} obj - an object related to a Cell.
 * @returns {Cell}
 */
function getTable(obj) {

    if (obj == undefined)
        return;

    if ('Array' === obj.constructor.name) {
        for (var i = 0, table; i < obj.length; i++) {
            table = getTable(obj[i]);
            if (table && table.isValid)
                return table;
        }
        return;
    }

    if (obj.constructor.name == 'Cell')
        return obj.parent;

    if (obj.parent.constructor.name == 'Cell')
        return obj.parent.parent;

    if (
        obj.hasOwnProperty('cells')
        && obj.cells.length > 0
    )
        return obj.cells[0].parent;

    if (
        obj.hasOwnProperty('tables')
        && 0 !== obj.tables.length
    )
        return obj.tables[0];

};

/**
 * Returns a number between `min` and `max`,
 * weighted by `minProbability` and `maxProbability`.
 * If `minProbability` `maxProbability` are equal,
 * then there is no weighting.
 * @author m1b, from python code by Peter O. https://stackoverflow.com/questions/67225968/give-lower-values-a-higher-weight-in-a-randint-function/67226933#67226933
 * @version 2023-12-27
 * @param {Number} min - the lowest number you want.
 * @param {Number} max - the highest number you want.
 * @param {Number} minProbability - the likelihood of getting `min`.
 * @param {Number} maxProbability - the likelihood of getting `max`.
 */
function weightedRandom(min, max, minProbability, maxProbability) {

    if (undefined == min)
        min = 0;

    if (undefined == max)
        max = 1;

    if (max == min)
        return min;

    if (
        undefined == minProbability
        || undefined == maxProbability
    )
        throw Error('weightedRandom: bad parameters.');

    while (true) {

        // get the highest weight
        var highestWeight = Math.max(minProbability, maxProbability),

            // generate a random integer in the interval min..max
            r = Math.floor(Math.random() * (max - min + 1)) + min,

            // calculate the weight for this integer
            weight = minProbability + (maxProbability - minProbability) * ((r - min) / (max - min)),

            // generate a random value between 0 and the highest weight
            v = Math.random() * highestWeight;

        // return r when v is less than the weigth
        if (v < weight)
            return r;

    }

};