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

Set table row height

Community Beginner ,
Jan 12, 2012 Jan 12, 2012

I have multiple InDesign files with linked .xls tables. About 150 tables per file, and these files update quite frequently (adding and removing rows etc).

And I was looking for a plugin that could do that, and was told that this should be scriptable.

And since I am not that deep into the scripting scene,does anyone know of script that can do the following?

What I would want to happen is a hight of a row of empty cells to be 7pt.

The hight of a cell with content to be a minimum of 14pt, unless this cell contains multiple lines it should increase by 7pt till it can fit all content (and decrease by 7pt if a line is removed in an update of the .xls file). The reason why we would need 7pt increments is that multiple lines often won't fit in a 14pt cell hight. And most designs call for a grid to work in.

A cell with a certain Cell-style to have a hight of 21pt.

Hope the attached example helps to clarify the question.

Screen+shot+2012-01-11+at+12.02.png

TOPICS
Scripting
11.4K
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 1 Correct answer

LEGEND , Jan 16, 2012 Jan 16, 2012

Also we have cells that should have a set height (subtotal and top-value)

In the above I am talking about cell-styles (subtotal, top-value)

Whoops. I suppose I should have checked, sorry!

Add ", styleName" to the var declaration on line 5, and then add this at line 13, before the "if (initial) {":


        styleName = row.cells[0].appliedCellStyle.name;

        if (styleName === "top-value" ||

             styleName === "subtotal"

        ) {

            continue;

        }

Translate
LEGEND ,
Jan 15, 2012 Jan 15, 2012

Hi, the desmodus:

  I apologize for sending you here from the regular forum (Advanced cell-style plugin?) on Wednesday and then not having the time to respond.

It would have been easier, though, if you had provided an actual document sample to work with, because there are implicit assumptions about font size and whatnot that aren't completely clear from your screenshot.

I'm also unclear why you need to incrementally increase the size of the non-empty rows. Is it not sufficient to set the rows to "at least" 7pt and ensure their leading is 7pt? (Err, I guess you the leading less the vertical cell insets, but still). It's annoying to have the script interact with the composition engine, because it gets slower and you have to force InDesign to do recalculations, and that can be tricky. I would rather avoid it.

Here's a script that basically implements this. Starts with a fitTable() function that, given a table, iterates over the rows and checks for non-zero content. If zero, it sets the height to p7 and turns off autoGrow (unnecessary, I guess, and maybe counterprodutive). If non-zero, it sets the height to p14 and turns on autogrow.

Then, there's the main() function which applies the fitTable() function to every table in every story in the document.

function fitTable(table) {

    var i, row, contentLength;

    for (i=0; i<table.rows.length; i++) {

        row = table.rows;

        contentLength = row.contents.join("").length;

        // $.writeln("Row "+i+" has height "+  row.height+" "+contentLength+" <"+table.rows.contents+">");

        if (contentLength === 0) {

            row.height = "p7";

            row.autoGrow = false;

        } else {

            row.height = "p14";

            row.autoGrow = true;

        }

    }

}

function main() {

    var d=app.activeDocument,

        tables=d.stories.everyItem().tables.everyItem().getElements();

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

        fitTable(tables); 

    }

}

main();

I also exported my test table as InDesign Tagged Text, so you can import that and see what I used it on. If you have troubles that relate to your particular document, a exporting as IDTT or a Snippet and pasting it in here is a great way to communicate about it. Use the Advanced Editor and >> Syntax Highlighting: XML so that the forum doesn't corrupt it.

<ASCII-MAC>

<vsn:7><fset:InDesign-Roman><ctable:=<Black:COLOR:CMYK:Process:0,0,0,1><Paper:COLOR:CMYK:Process:0,0,0,0>>

<dps:NormalParagraphStyle=<Nextstyle:NormalParagraphStyle>>

<dtbls:\[Basic Table\]=>

<pstyle:NormalParagraphStyle>before table

<pstyle:NormalParagraphStyle>

<pstyle:NormalParagraphStyle><tstyle:\[Basic Table\]><tStart:15,2:0:0<tcdct:Text>><coStart:<tcaw:187>><coStart:<tcaw:187>><rStart:<trah:7><tramirs:7><trag:0>><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Non-current assets<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>12<cs:><cl:><cf:><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Inventories<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>14<cs:><cl:><cf:><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Financial assets<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:7><tramirs:7><trag:0>><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Cash<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Assets held for sale<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Current assets<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Total assets<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:19.5><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Equity to the

<cs:><cl:><cf:><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>owners of the company<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Interest<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Total equity<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Interst-bearing borrowings<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Provisions / employee benefits<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><rStart:<trah:14><tramirs:14><trag:1>><estyle:\[None\]><stypri:0><clStart:1,1><pstyle:NormalParagraphStyle><cs:6.000000><cl:7.000000><cf:Helvetica>Other non-current liabilities<cs:><cl:><cf:><clEnd:><estyle:\[None\]><stypri:0><clStart:1,1><clEnd:><rEnd:><tEnd:>

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 Beginner ,
Jan 16, 2012 Jan 16, 2012

Hi John,

No need for apologies at all, this is an open forum and you are going out of your way as is.

This script does the trick, except the growing by 7pt increments. But from what I understand from your post, this messes with the 'composition engine' of InDesign.

Let me try to ellaborate why we want this increment.

In a cell we have a paragraph-style that has lets say an 9pt font with a 10,5 leading. So if there are 2 lines it would be 2x9pt + a 10,5 leading. In theory this would result in a cell height of 28,5pt (depending on the top and bottom padding). In our grid this cell should be a multiple of 7pt, so 35pt.

At the moment we have a list of cell heights (for the non math wizards), from where the operators can choose the height of the cell that would fit the content.

Also we have cells that should have a set height (subtotal and top-value)

I placed a sample table at: http://www.hofhuis.org/transfer/table_sample.zip . Please don't mind the colors in the design, these are for demo purposes here only.

Thank you soo much for your time.

Mark

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 ,
Jan 16, 2012 Jan 16, 2012

Mark:

Let me try to ellaborate why we want this increment.

In a cell we have a paragraph-style that has lets say an 9pt font with a 10,5 leading. So if there are 2 lines it would be 2x9pt + a 10,5 leading. In theory this would result in a cell height of 28,5pt (depending on the top and bottom padding). In our grid this cell should be a multiple of 7pt, so 35pt.

At the moment we have a list of cell heights (for the non math wizards), from where the operators can choose the height of the cell that would fit the content.

OK, I get it. That makes sense.

Try this version. It got a lot longer. (We could probably compress it a bit by making it harder to understand...)

Jongware:

-- but (surreptitious attempt) it seems 'row.overflows' doesn't seem to work as one would have hoped.

I believe it's necessary to execute a document recomposition before you check it. In this implementation we do that once all the rows have been set, before incrementing. I think this is sufficient, but I would not be surprised if it breaks horribly somehow...

Mark:

Also we have cells that should have a set height (subtotal and top-value)

Would you like a pony? How is the script supposed to know [this is a serious question, not a sarcastic one]?

Is there a particular paragraph style these cells have? Particular contents? Particular cell style? Particular position?

Really any of those are easy enough to check, but you haven't specified, so, well, this version of the script does not handle that case.

There are some safety checks and debugging options in this version, too. You should definitely test it on multi-page tables, I worry they may be where things start to go wrong.

var debug = 0;

function fitTable(table, initial) {

    var i, row, contentLength,

        noOverflow = true;

    for (i=0; i<table.rows.length; i++) {

        row = table.rows;

        contentLength = row.contents.join("").length;

        if (debug > 1) {

            $.writeln("Row "+i+" has height "+  row.height+" "+contentLength+" <"+table.rows.contents+">");

        }

        if (initial) {

            if (contentLength === 0) {

                row.height = 7;

            } else {

                row.height = 14;

            }

        } else {

            if (row.overflows) {

                row.height += 7;

                noOverflow = false;

                if (debug > 0) {

                    $.writeln("row "+i+" overflows "+row.overflows);

                }

            }

        }

    }

    return noOverflow;

}

function main() {

    var d=app.activeDocument,

        tables=d.stories.everyItem().tables.everyItem().getElements(),

        overflowingTables, tries=0, safetyValve=10;

    // All units in points. Not a persistent engine, so we need not reset this.

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    // Set the initial size.

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

        fitTable(tables, true); 

    }

    // Recompose the document, then check each row for overflow.

    while (overflowingTables !== 0) {

        if (tries++ >= safetyValve) {

            alert("Exceeded safety valve\n"+

                "Tried to recompose document "+tries+" times, something is wrong.\n"+

                "Try setting debug=1.");

            return false;

        }

        if (debug>0) {

            $.writeln("Composition check with "+overflowingTables+" overflows.");

        }

        overflowingTables=0;

        app.activeDocument.recompose();

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

            if (!fitTable(tables, false)) {

                overflowingTables++;

            }

        }

    }

}

main();

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 Beginner ,
Jan 16, 2012 Jan 16, 2012

Hi John,

Thanks again for your great post, and I stand corrected in one of my questions. I did not make myself clear.. but yes, a pony would be nice

Mark:

Also we have cells that should have a set height (subtotal and top-value)

In the above I am talking about cell-styles (subtotal, top-value)

I will try your script the first thing tomorrow when I am back in the office on the test document.

Thanks again for your great help!

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 ,
Jan 16, 2012 Jan 16, 2012

Also we have cells that should have a set height (subtotal and top-value)

In the above I am talking about cell-styles (subtotal, top-value)

Whoops. I suppose I should have checked, sorry!

Add ", styleName" to the var declaration on line 5, and then add this at line 13, before the "if (initial) {":


        styleName = row.cells[0].appliedCellStyle.name;

        if (styleName === "top-value" ||

             styleName === "subtotal"

        ) {

            continue;

        }

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 Beginner ,
Jan 17, 2012 Jan 17, 2012

Hi John,

I now have made this script, and it works pretty good sofar. I only get a cell height of 14.173 pt at cell-style "top-value" and at 1 of the 2 subtotal fields in my test document I get the correct 21 pt, but at the other one I get 20.239 pt. To me this seems odd, since the height is set to 'exact' in InDesign.

Any idea where it gets these values from?

If I set all cells to an exact height of 50pt, the script resizes all the cells to the correct height, but leaves the cells with Cell-Style names 'top-value' and 'subtotal' at 50pt. So in a way I can do a workaround by setting all the cells to 21pt height, and then running the script (or is this the way it should run?)

---

After testing on some tables I get the following error message (sorry that it is in Dutch):

Screen shot 2012-01-17 at 10.03.50.png

var debug = 0;

function fitTable(table, initial) {

    var i, row, contentLength, styleName,

        noOverflow = true;

    for (i=0; i<table.rows.length; i++) {

        row = table.rows;

        contentLength = row.contents.join("").length;

        if (debug > 1) {

            $.writeln("Row "+i+" has height "+  row.height+" "+contentLength+" <"+table.rows.contents+">");

        }

                    styleName = row.cells[0].appliedCellStyle.name;

                            if (styleName === "top-value" ||

                                 styleName === "subtotal"

                            ) {

                                continue;

                            }

        if (initial) {

            if (contentLength === 0) {

                row.height = 7;

            } else {

                row.height = 14;

            }

        } else {

            if (row.overflows) {

                row.height += 7;

                noOverflow = false;

                if (debug > 0) {

                    $.writeln("row "+i+" overflows "+row.overflows);

                }

            }

        }

    }

    return noOverflow;

}

function main() {

    var d=app.activeDocument,

        tables=d.stories.everyItem().tables.everyItem().getElements(),

        overflowingTables, tries=0, safetyValve=10;

    // All units in points. Not a persistent engine, so we need not reset this.

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    // Set the initial size.

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

        fitTable(tables, true); 

    }

    // Recompose the document, then check each row for overflow.

    while (overflowingTables !== 0) {

        if (tries++ >= safetyValve) {

            alert("Exceeded safety valve\n"+

                "Tried to recompose document "+tries+" times, something is wrong.\n"+

                "Try setting debug=1.");

            return false;

        }

        if (debug>0) {

            $.writeln("Composition check with "+overflowingTables+" overflows.");

        }

        overflowingTables=0;

        app.activeDocument.recompose();

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

            if (!fitTable(tables, false)) {

                overflowingTables++;

            }

        }

    }

}

main();

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 ,
Jan 17, 2012 Jan 17, 2012

Mark:

I now have made this script, and it works pretty good sofar. I only get a cell height of 14.173 pt at cell-style "top-value" and at 1 of the 2 subtotal fields in my test document I get the correct 21 pt, but at the other one I get 20.239 pt. To me this seems odd, since the height is set to 'exact' in InDesign.

Any idea where it gets these values from?

To be honest...no, I have no idea. Perhaps you could post a test document.

The script should be ignoring the height of any rows whose first cell is styled top-value or subtotal, so I wonder if they are pre-existing.

Also, it sets cell heights to 7 or 14 point, and then increments them by 7 points. It's hard to see how you would get 14.173pt or 20.239pt.

14.173pt is 5mm, which might be a clue. 20.239pt is 7.14mm, which is not so much a clue.

Have you run the script with debug=1 or debug=2? It should give you row-by-row insight. And of course you can add more $.writeln() statements in different parts of the script to see what is going on.

If I set all cells to an exact height of 50pt, the script resizes all the cells to the correct height, but leaves the cells with Cell-Style names 'top-value' and 'subtotal' at 50pt. So in a way I can do a workaround by setting all the cells to 21pt height, and then running the script (or is this the way it should run?)

Err, the idea was that top-value and subtotal should be unchanged from where they were at the start. Was that not your intent?

After testing on some tables I get the following error message (sorry that it is in Dutch): [row.contents.join is not a function]

OK, so this line of the script:

        contentLength = row.contents.join("").length;

attempts to determine if a row is empty, and it is failing for some reason. Perhaps involving something with merged cells?

It takes "row.contents," which it assumes to be an array of strings, and joins that array together as a single long string, and measures the length of that string.

According to the documentation, row.contents need not be an array of strings, it can also be a single string, or a special character enumerator or array thereof. So clearly what I wrote wasn't general enough. I guess it needs to be:

  var rowContents;

  ...

  rowContents = row.contents;

  if (rowContents.hasOwnProperty("join")) {

    contentLength = rowContents.join("").length;

  } else {

    contentLength = rowContents.length;

  }

Which takes care of the Array or not-Array problem. I'm not sure what to do about the SpecialCharacters enumerators. I can't seem to find a case where they happen, even with stuff like Frame Break or Page Numbering inserted.  It's probably fine not to worry about them.

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 Beginner ,
Jan 17, 2012 Jan 17, 2012

You sir are a king.

This makes the script work on every table I fire it on. The only thing that it now fails on is the empty rows, instead of setting them to 7pt, it sets them to 14pt.

Did I paste the addition to the code on the correct place?

var debug = 0;

function fitTable(table, initial) {

    var i, row, contentLength, styleName, rowContents,

        noOverflow = true;

    for (i=0; i<table.rows.length; i++) {

        row = table.rows;

        rowContents = row.contents;

                      if (rowContents.hasOwnProperty("join")) {

                        contentLength = rowContents.join("").length;

                      } else {

                        contentLength = rowContents.length;

                      }

        if (debug > 1) {

            $.writeln("Row "+i+" has height "+  row.height+" "+contentLength+" <"+table.rows.contents+">");

        }

                    styleName = row.cells[0].appliedCellStyle.name;

                            if (styleName === "top-value" ||

                                 styleName === "subtotal"

                            ) {

                                continue;

                            }

        if (initial) {

            if (contentLength === 0) {

                row.height = 7;

            } else {

                row.height = 14;

            }

        } else {

            if (row.overflows) {

                row.height += 7;

                noOverflow = false;

                if (debug > 0) {

                    $.writeln("row "+i+" overflows "+row.overflows);

                }

            }

        }

    }

    return noOverflow;

}

function main() {

    var d=app.activeDocument,

        tables=d.stories.everyItem().tables.everyItem().getElements(),

        overflowingTables, tries=0, safetyValve=10;

    // All units in points. Not a persistent engine, so we need not reset this.

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    // Set the initial size.

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

        fitTable(tables, true); 

    }

    // Recompose the document, then check each row for overflow.

    while (overflowingTables !== 0) {

        if (tries++ >= safetyValve) {

            alert("Exceeded safety valve\n"+

                "Tried to recompose document "+tries+" times, something is wrong.\n"+

                "Try setting debug=1.");

            return false;

        }

        if (debug>0) {

            $.writeln("Composition check with "+overflowingTables+" overflows.");

        }

        overflowingTables=0;

        app.activeDocument.recompose();

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

            if (!fitTable(tables, false)) {

                overflowingTables++;

            }

        }

    }

}

main();

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 ,
Jan 17, 2012 Jan 17, 2012

This makes the script work on every table I fire it on. The only thing that it now fails on is the empty rows, instead of setting them to 7pt, it sets them to 14pt.

Did I paste the addition to the code on the correct place?

You're welcome. Yes, you did paste it in the right place.

Set debug=2 and see what is printed out for the empty rows, I guess (or provide a sample document).

Perhaps they are not really "empty" — does Type > Show Hidden Characters show them to really be empty?

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 Beginner ,
Jan 17, 2012 Jan 17, 2012

It prints out that it makes them 14pt.

And they are really empty, I even generated a new row

I placed a sample at: http://www.hofhuis.org/transfer/table_sample.zip

Hope this helps

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 ,
Jan 17, 2012 Jan 17, 2012

Got it. My error. Failed to test rigorously:

Replace:

if (rowContents.hasOwnProperty("join")) {

with

if (rowContents instanceof Array) {

I'm not quiet sure why the test I used didn't work, but so it goes...

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 Beginner ,
Jan 17, 2012 Jan 17, 2012

Amazing

It works like a charm... You have helped me out heaps!!

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 Beginner ,
Jan 18, 2012 Jan 18, 2012

I realise I am asking a lot here, but is it possible to give the

styleName = row.cells[0].appliedCellStyle.name;
                            if (styleName === top-value ||
                                 styleName === subtotal
                            )

a set height of 21 points and then use the same 7pt increment when it's content overflow asks for it.

Learning a lot here... I think a proper Javascript course is looking more and more needed

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 ,
Jan 18, 2012 Jan 18, 2012

I realise I am asking a lot here, but is it possible to give the [top-value and subtotal lines

a set height of 21 points and then use the same 7pt increment when it's content overflow asks for it.

Sure, it's easy. I had not previously understood that was what you wanted.

Keep the styleName=... line where it is (*), and remove the if block. Then, inside the if (initial) block (that includes removing the continue), after the closing brace } of the if (contentLength... block, add the following:

if (styleName === "top-value" ||

     styleName === "subtotal"

) {

    row.height = 21;

}

Edit: Sorry for the premature post, accidently clicked the submission button!

Re-edit: added missing double-quotes

(*): Not sure why I said that. I'll work, but it'd make more sense to move it down to be immediately prior to the newly inserted if (stylename... block. Whatever...

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 Beginner ,
Jan 18, 2012 Jan 18, 2012

From what I understood from your directions I made the following, but it keeps on giving errors.

Sorry if I completely messed up your directions.

function fitTable(table, initial) {

    var i, row, contentLength, styleName, rowContents,

        noOverflow = true;

    for (i=0; i<table.rows.length; i++) {

        row = table.rows;

        rowContents = row.contents;

                      if (rowContents instanceof Array) {

                        contentLength = rowContents.join("").length;

                      } else {

                        contentLength = rowContents.length;

                      }

        if (debug > 1) {

            $.writeln("Row "+i+" has height "+  row.height+" "+contentLength+" <"+table.rows.contents+">");

        }

 

        if (initial) {

            if (contentLength === 0) {

                row.height = 7;

            }

                               styleName = row.cells[0].appliedCellStyle.name;

                              if (styleName === top-value ||

                                   styleName === subtotal

                              ) {

                                  row.height = 21;

                              }

                              else {

                row.height = 14;

            }

        } else {

            if (row.overflows) {

                row.height += 7;

                noOverflow = false;

                if (debug > 0) {

                    $.writeln("row "+i+" overflows "+row.overflows);

                }

            }

        }

    }

    return noOverflow;

}

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 ,
Jan 18, 2012 Jan 18, 2012
From what I understood from your directions I made the following, but it keeps on giving errors.

But what errors? They do have meaning, as well as line numnbers, you know!

Problem 1: Missing double-quotes around "top-value", etc. Somehow you didn't paste them in when you pasted your code and when I modified it on the forum I didn't notice.

Problem 2: When I said after the closing brace of the if (contentLength... block, I meant after the closing brace of the else portion.

You might want to pay closer attention to indentation, also, things are starting to seriously not-line-up. Makes it hard to read.

Correcting those errors, the first part of the if (initial.. block becomes:

if (initial) {

    if (contentLength === 0) {

        row.height = 7;

    } else {

        row.height = 14;

    }

    styleName = row.cells[0].appliedCellStyle.name;

    if (styleName === "top-value" ||

         styleName === "subtotal"

    ) {

        row.height = 21;

    }

} else {

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 ,
Jan 18, 2012 Jan 18, 2012

How're we doing? All set?

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 Beginner ,
Jan 18, 2012 Jan 18, 2012

Yes, all is working like a charm now. Sorry for the late response (timezone differences).

I added a little bit of extra comment to help javascript noobs like myself a bit if they need to alter the values.

var debug = 0;

function fitTable(table, initial) {

    var i, row, contentLength, styleName, rowContents,

        noOverflow = true;

    for (i=0; i<table.rows.length; i++) {

        row = table.rows;

        rowContents = row.contents;

                      if (rowContents instanceof Array) {

                        contentLength = rowContents.join("").length;

                      } else {

                        contentLength = rowContents.length;

                      }

        if (debug > 1) {

            $.writeln("Row "+i+" has height "+  row.height+" "+contentLength+" <"+table.rows.contents+">");

        }

        if (initial) {

                        if (contentLength === 0) {

                            // All empty rows will be 7 points in height

                            row.height = 7;

                        } else {

                            // If there is any content it will result in a cell height of 14 points

                            row.height = 14;

                        }

                        styleName = row.cells[0].appliedCellStyle.name;

                    // Below are the cell-style names that will be 21 points in height

                        if (styleName === "top-value" ||

                             styleName === "subtotal"

                        ) {

                            row.height = 21;

                        }

                    } else {

            if (row.overflows) {

                // If 14 points is not enough to hold the content, it will expand by 7 point increments

                row.height += 7;

                noOverflow = false;

                if (debug > 0) {

                    $.writeln("row "+i+" overflows "+row.overflows);

                }

            }

        }

    }

    return noOverflow;

}

function main() {

    var d=app.activeDocument,

        tables=d.stories.everyItem().tables.everyItem().getElements(),

        overflowingTables, tries=0, safetyValve=18;

    // All units in points. Not a persistent engine, so we need not reset this.

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

    // Set the initial size.

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

        fitTable(tables, true); 

    }

    // Recompose the document, then check each row for overflow.

    while (overflowingTables !== 0) {

        if (tries++ >= safetyValve) {

            alert("Exceeded safety valve\n"+

                "Tried to recompose document "+tries+" times, something is wrong.\n"+

                "Try setting debug=1.");

            return false;

        }

        if (debug>0) {

            $.writeln("Composition check with "+overflowingTables+" overflows.");

        }

        overflowingTables=0;

        app.activeDocument.recompose();

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

            if (!fitTable(tables, false)) {

                overflowingTables++;

            }

        }

    }

}

main();

Thanks again for all the help!!

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 Beginner ,
Jan 26, 2012 Jan 26, 2012

John, right now it seems the script is checking the first column of a table to set the row-height. Is there a way I can change it so it checks all columns?

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 ,
Jan 26, 2012 Jan 26, 2012

John, right now it seems the script is checking the first column of a table to set the row-height. Is there a way I can change it so it checks all columns?

We're talking about the check for the cell style?

I'm afraid I did it the easy way (check only the first cell) because I hoped it was sufficient, and it's a bit awkward to check the rest of them. A combination of Javascript Arrays being annoying to work with, how the InDesign Document Object Model works, etc.

Anyhow, this should do it: Edit: Bah, no it won't. See next post.

var styles;

...

styles = row.cells.everyItem().appliedCellStyle;

while (styleName = styles.pop().name) {

    if (styleName === "top-value" ||

         styleName === "subtotal"

    ) {

        row.height = 21;

        break;

    }

}

This replaces, of course, the existing styleName=... code and the if block that followed it.

We retrieve the styles (not their names, but the style themselves!), from every cell in the current row. This is somewhat of an optimization, but it also makes the code easier to read (maybe) and shorter. Then, we loop over the styles, taking a style off the styles array each time through the loop, and as we pop() a style off the array, we also retrieve its .name property, and assign it to our styleName variable. Then we do the same test as before. If we do find a case where it matches not only do we set the row height to 21pt, but we also break; out of the loop so we don't have to keep checking all the other styles (we could skip that in the interest of clarity, I guess...).

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 ,
Jan 26, 2012 Jan 26, 2012

Whoops. There we go not testing properly. Unfortunately we cannot pop() the style off the array at the same time as we retrieve its name, because on the last time around the loop, the pop() will fail, and thus we try to retrieve undefined.name. So instead:

var styles, style;

...

styles = row.cells.everyItem().appliedCellStyle;

while (style = styles.pop()) {

    styleName = style.name;

    if (styleName === "top-value" ||

         styleName === "subtotal"

    ) {

        row.height = 21;

        break;

    }

}

Well, that's inelegant. Oh well.

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 Beginner ,
Jan 30, 2012 Jan 30, 2012

Thanks again John,

From what I understand from your post, the

                         styleName = row.cells[0].appliedCellStyle.name;

                       // Below are the cell-style names that will be 21 points in height

                        if (styleName === "top-value" ||

                             styleName === "subtotal"

                        ) {

                            row.height = 21;

                        }

                    } else {

            if (row.overflows) {

               // If 14 points is not enough to hold the content, it will expand by 7 point increments

                row.height += 7;

                noOverflow = false;

                if (debug > 0) {

                    $.writeln("row "+i+" overflows "+row.overflows);

                }

            }

part is replaced as a whole by:

styles = row.cells.everyItem().appliedCellStyle;

                              while (style = styles.pop()) {

                                  styleName = style.name;

                                  if (styleName === "top-value" ||

                                       styleName === "subtotal"

                                  ) {

                                      row.height = 21;

                                      break;

                                  }

                              }

Forgive the indenting issues (somehow TextMate messes it up in copy/paste).

If I do this, the 7pt increment part of the script is deleted

If I leave that part of the script, like this:

                                styles = row.cells.everyItem().appliedCellStyle;

                              while (style = styles.pop()) {

                                  styleName = style.name;

                                  if (styleName === "top-value" ||

                                       styleName === "subtotal"

                                  ) {

                                      row.height = 21;

                                      break;

                                  }

                              }

                        if (row.overflows) {

                            // If 14 points is not enough to hold the content, it will expand by 7 point increments

                           row.height += 7;

                           noOverflow = false;

                           if (debug > 0) {

                               $.writeln("row "+i+" overflows "+row.overflows);

                               }

                           }

It gives me the following error message.

Screen shot 2012-01-30 at 09.28.42.png

In the ExtenScript toolkit it stalls at:

Row 0 has height 14 78 <

Financial assets carried  at  fair value,Note,December 31, 2011,December 31, 2010>

Row 1 has height 14 60 <Carrying ,Effect of reasonably ,Carrying ,Effect of reasonably >

Here the table that it seems to have issues with.

Screen shot 2012-01-30 at 09.37.00.png

Could it have something to do with combined and split rows?

It seems that it tries to extend the height of the cell that contains: 'Carrying •', but doing this also requires the first cell to grow as well. And that won't work?

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 ,
Jan 30, 2012 Jan 30, 2012

Thanks again John,

From what I understand from your post, the [...]  part is replaced as a whole by:

Forgive the indenting issues (somehow TextMate messes it up in copy/paste).

Err, no, not that. I think the indentation was indeed throwing you off, replacing more than you should, which was supposed to be a 5-line if block.

I was trying to avoid clutter and to encourage clear thinking by posting small snippets rather than reposting the entire script each time, but that probably led to more pain than it helped. I apologize.

Anyhow, here's the whole thing with the change integrated as I had intended on Thursday. Sorry for making you slave over it:

var debug = 0;

function fitTable(table, initial) {

    var i, row, contentLength, styleName, rowContents, styles, style,

        noOverflow = true;

    for (i=0; i<table.rows.length; i++) {

        row = table.rows;

        rowContents = row.contents;

        if (rowContents instanceof Array) {

            contentLength = rowContents.join("").length;

        } else {

            contentLength = rowContents.length;

        }

        if (debug > 1) {

            $.writeln("Row "+i+" has height "+  row.height+" "+

                      contentLength+" <"+table.rows.contents+">");

        }

        if (initial) {

            if (contentLength === 0) {

                // All empty rows will be 7 points in height

                row.height = 7;

            } else {

                // If there is any content it will result in a cell

                // height of 14 points

                row.height = 14;

            }

            styleName = row.cells[0].appliedCellStyle.name;

            // Below are the cell-style names that will be 21 points in height

            styles = row.cells.everyItem().appliedCellStyle;

            while (style = styles.pop()) {

                styleName = style.name;

                if (styleName === "top-value" ||

                    styleName === "subtotal"

                   ) {

                    row.height = 21;

                    break;

                }

            }

        } else {

            if (row.overflows) {

                // If 14 points is not enough to hold the content, it

                // will expand by 7 point increments

                row.height += 7;

                noOverflow = false;

                if (debug > 0) {

                    $.writeln("row "+i+" overflows "+row.overflows);

                }

            }

        }

    }

    return noOverflow;

}

function main() {

    var d=app.activeDocument,

        tables=d.stories.everyItem().tables.everyItem().getElements(),

        overflowingTables, tries=0, safetyValve=18;

    // All units in points. Not a persistent engine, so we need not reset this.

    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

   

    // Set the initial size.

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

        fitTable(tables, true); 

    }

   

    // Recompose the document, then check each row for overflow.

    while (overflowingTables !== 0) {

        if (tries++ >= safetyValve) {

            alert("Exceeded safety valve\n"+

                  "Tried to recompose document "+tries+

                  " times, something is wrong.\n"+

                  "Try setting debug=1.");

            return false;

        }

        if (debug>0) {

            $.writeln("Composition check with "+overflowingTables+

                      " overflows.");

        }

        overflowingTables=0;

        app.activeDocument.recompose();

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

            if (!fitTable(tables, false)) {

                overflowingTables++;

            }

        }

    }

}

main();

Let me know if I need to go re-test it...

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 Beginner ,
Jan 31, 2012 Jan 31, 2012

No need to apologize at all, I am more then thrilled that you can help me with this issue. Learning heaps here.

Sorry to say that I still get the same "if (row.overflows) {" error, it still seems to stop when it needs to resize a cell that is not in the first column.

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