Skip to main content
dublove
Brainiac
December 19, 2024
Answered

How do I ensure bottom alignment for documents with tables? Row alignment?

  • December 19, 2024
  • 3 replies
  • 1540 views

otice in the example I gave that
When there is no table:
The bottom of the left page is aligned.
When the table is inserted, the bottom of the right page is not aligned.
In the past I would adjust the line spacing before and after the table to roughly align, but with 100 tables I'm at a loss. And the client is always changing it around, making you go crazy a few firsts.

 

I tried the first row baseline, but it is difficult to achieve automatic alignment because of the variable number of tables and rows per page.

 

Finally I tried grid layout and the bottom automatically aligns.
But another problem comes, the table is fixed in the grid, you can't move him, sometimes the table before and after spacing is not the same, it's hard to see.

You can only adjust the row height, the space before and after the table.

 

Do you guys have a good solution, can you share it.
Thank you very much.

Correct answer Peter Spier

For a document like this I would suggest setting the baseline grid to the same value as your body text leading and set the body text styles to align the first line to the grid.

3 replies

m1b
Community Expert
December 19, 2024

Hi @dublove, here is a script that vertically justifies each frame by adding space before and after each table. Is that what you need?

- Mark

/**
 * @file Justify By Spacing Tables.js
 *
 * Usage:
 *   1. Select some text or text frame(s).
 *   2. Run script.
 *
 * Will attempt to add space, before and after, to each table
 * so that the text frame(s) are vertically justified.
 *
 * @author m1b
 * @version 2024-12-20
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-do-i-ensure-bottom-alignment-for-documents-with-tables-row-alignment/m-p/15048920
 */
function main() {

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    var doc = app.activeDocument,
        selectedTables = getTables(doc.selection);

    // get textFrames
    var frames = [],
        already = {};

    for (var i = 0; i < selectedTables.length; i++) {
        var frame = selectedTables[i].parent;
        if (!already[frame.id]) {
            frames.push(frame);
            already[frame.id] = true;
        }
    }

    // process each text frame
    for (var i = 0; i < frames.length; i++) {

        var frame = frames[i],
            lineCount = frame.lines.length,
            tables = frame.tables,
            firstSpace = tables[0].spaceBefore,
            space = 0;

        // calculate the excess space
        while (frame.lines.length === lineCount)
            tables[0].spaceBefore += 3;

        while (frame.lines.length !== lineCount)
            tables[0].spaceBefore -= 0.5;

        // measure space
        space = tables[0].spaceBefore - firstSpace;

        // reset
        tables[0].spaceBefore = firstSpace;

        // space out tables evenly
        var spacingAmount = space / (tables.length * 2);

        for (var j = 0; j < tables.length; j++) {
            tables[j].spaceBefore += spacingAmount;
            tables[j].spaceAfter += spacingAmount;
        }

    }

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Justify By Spacing Tables');

/**
 * Get tables from `items`.
 * @author m1b
 * @version 2024-12-20
 *
 * Finds tables inside different objects,
 * eg. selection, page, text frame, story.
 * Supply a filter function to narrow down
 * the table(s) even more.
 *
 * @param {Document|Page|PageItem|TextFrame|Cell|Text} items - item, collection or array to get tables from
 * @param {Boolean} [onlyFirst] - only return the first table found
 * @param {Function} [filter] - only match tables that pass this filter function
 * @param {Array[Table]} [found] - results (private argument for recursive calls)
 * @returns {Array[Table]} - the found table(s) * if onlyFirst flag then can be {Table}
 */
function getTables(items, onlyFirst, filter, found) {

    // sanity
    if (items == undefined)
        return [];

    if (found == undefined)
        found = [];

    else if (
        onlyFirst
        && found.constructor.name == 'Table'
    )
        // immediately return the table
        return found;

    if (!items.hasOwnProperty('0'))
        // put in array to process
        items = [items];

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

        var item = items[i];

        if (item.constructor.name == 'Table') {

            if (
                filter == undefined
                || filter(item) === true
            ) {

                // item is a table
                if (onlyFirst)
                    return item;

                else
                    found.push(item);

            }
        }

        else if (item.constructor.name == 'TextFrame') {

            var textFrameTables = item.tables.everyItem().getElements();

            if (
                item.hasOwnProperty('textFrames')
                && item.textFrames.length > 0
            )
                // check in anchored text frames
                textFrameTables = textFrameTables.concat(getTables(item.textFrames, onlyFirst, filter));

            found = found.concat(textFrameTables);

        }

        else if (
            item.hasOwnProperty('tables')
            && item.tables.length > 0
        )
            // item contains tables
            found = found.concat(getTables(item.tables, onlyFirst, filter));

        else if (
            item.hasOwnProperty('parent')
            && item.parent.constructor.name == 'Cell'
        )
            // parent is a table cell
            found = found.concat(getTables(item.parent.parent, onlyFirst, filter));

        else if (
            item.hasOwnProperty('paragraphs')
            && item.paragraphs.length > 0
            && item.paragraphs[0] !== item
        )
            // is in a story, which may contain tables
            found = found.concat(getTables(item.paragraphs, onlyFirst, filter));

        else if (
            item.hasOwnProperty('parentTextFrames')
            && item.parentTextFrames.length > 0
        )
            // is in a story, which may contain tables
            found = found.concat(getTables(item.parentTextFrames, onlyFirst, filter));

        else if (
            item.hasOwnProperty('parentStory')
        )
            // is in a story, which may contain tables
            found = found.concat(getTables(item.parentStory, onlyFirst, filter));

        else if (
            item.hasOwnProperty('pageItems')
            && item.pageItems.length > 0
        )
            // contains page items, which may be tables
            found = found.concat(getTables(item.pageItems, onlyFirst, filter));

        else if (
            item.hasOwnProperty('parent')
            && item.parent.constructor.name != 'Document'
            && item.parent.constructor.name != 'Spread'
        )
            // has a parent which might be a table
            found = found.concat(getTables(item.parent, onlyFirst, filter));

    }

    return found;

};

 

dublove
dubloveAuthor
Brainiac
December 20, 2024

@m1b  

Thank you very much.
That's pretty awesome that you can use a script for that.
The function of this script seems to be similar to the text box “Align ends”?

Maybe James Gifford-NitroPress is right, there is no shortcut.

 

Help me out with this one sometime, it should be very useful. Use the same script to control alignable images and textboxes to specific boundaries.

https://community.adobe.com/t5/indesign-discussions/looking-for-a-good-script-one-click-to-hold-up-to-type-area-columns-and-pages/m-p/14989721#M598131 

James Gifford—NitroPress
Brainiac
December 20, 2024

By your comment, I will assume that I misunderstood what you needed.

 

I had a look at the other thread—and one linked from that one—but to be honest, you haven't specified your needs well enough for me to be bothered helping with that. The key is always to do as much work as possible yourself to make it easy for people to help you.

 

It is common when helping someone with scripting that you write a script that solves the problem, and then the OP says yes but my document has <some extra whatever> and it needs to handle that, too. So the first script is, perhaps, useless and needs to be re-written totally, or maybe no script is possible and my time is wasted.

 

So when I see a request that is impossible to understand, I shrug and move on. Sorry.

- Mark


This is a great example of why I sigh a bit when someone jumps in with a script to fix something, especially from somewhat loose examples and requests. Don't misunderstand  — although I'm not a script guy myself (which is a little odd; ID is just about the only venue in which I don't do low-level coding and so forth!) I appreciate the many standard scripts out there and the willingness of the script types to jump in. And the sheer power scripts can bring to complex projects.

 

But.

 

Unless they are massive and "error trapped" to the walls, and fully tested on a variety of documents, scripts tend to solve one (1) problem under either ideal or narrow conditions. Sometimes that's all that's needed — run script, some manuscript-wide glitch vanishes or a complicated change is made. But when it comes to more general problems, mostly to do with optimal formatting under workaday conditions... all too often, it takes too many rounds of adjusting the script, or accepting that what it does is closer to hack than fix, to get to a useful result.

 

Often, all that effort seems greater, sometimes, than just using skill and ID's tools to fix the issue.

 

And in this case, where a whole book needs to be formatted according to a single rule (even bottom alignment) simply hacking at table heights isn't really a good solution. There may be some automation, tool, helper (like selective use of Vertical Justification, or text-fitting by slightly tweaking top/bottom spacing on one table on the occasional page) or technique that makes it easier than my hard-road summary above... but learning to do that meticulous style and page adjustment to get page alignment as an organic result, rather than being sloppy and applying a quick band-aid fix (which will likely cause cascading problems that then need to be fixed in turn)... I'd suggest that effort put into honing a skill is better spent than effort spent building a one-shot, fixed-result patch.

 

Especially when the scope of the project is not fully understood and a quick tweak of table spacing might not be the right approach at all.

 

There's also a gap between those who can compose a script on the fly, from exceptional skill, and those who are somewhere lower on that knowledge ladder. I'm not sure it's useful for "Einstein to do your math homework for you," as it were — it sure won't lead to the user learning much of use for the next, or slightly variant problem.

 

Scripting is a wonderful asset, no question. But I feel like too many reach for it like a hack or band-aid, too quickly, sometimes.

James Gifford—NitroPress
Brainiac
December 19, 2024

You have to make all vertical (line space/leading/cell height/table spacing) elements some value that always adds up to your total text frame height, so that no matter how you mix text and tables, they have the same total height.

 

Things to adjust to meet this common spacing include:

  • Body text leading plus any space before or after
  • Table cell text height plus cell margins top and bottom
  • Table space before and space after

 

....and this will have to be continued for things like list items (bullet or numbered), headings and other content elements.

 

There is no simple, automated feature that can do more than help with this; it's an art and requires careful planning and meticulous adjustment of all the styles. And then you will have to accommodate variations such as 2-line table cells.

 

Look at it as a vertical grid, and make every element fit a vertical grid space. There's no real shortcut to that.

Peter Spier
Peter SpierCorrect answer
Community Expert
December 19, 2024

For a document like this I would suggest setting the baseline grid to the same value as your body text leading and set the body text styles to align the first line to the grid.

dublove
dubloveAuthor
Brainiac
December 20, 2024

Yes, there may be some headings where limiting the number of mandatory lines is better.
I'll look into it.
Thank you very much.