31 Replies Latest reply on Feb 1, 2012 1:59 AM by thedesmodus

    Set table row height

    thedesmodus Level 1

      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

        • 1. Re: Set table row height
          John Hawkinson Level 5

          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[i];
                  contentLength = row.contents.join("").length;
                  // $.writeln("Row "+i+" has height "+  row.height+" "+contentLength+" <"+table.rows[i].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[i]);  
              }
          }
          
          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:>
          
          1 person found this helpful
          • 2. Re: Set table row height
            thedesmodus Level 1

            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

            • 3. Re: Set table row height
              [Jongware] Most Valuable Participant

              John (a quick post 'cause I'm supposed to be working ),

               

              This pseudo-code ought to have worked:

               

              row.height = 7;

              while (row.overflows)

                row.height += 7;

               

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

              • 4. Re: Set table row height
                John Hawkinson Level 5

                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[i];
                        contentLength = row.contents.join("").length;
                        if (debug > 1) {
                            $.writeln("Row "+i+" has height "+  row.height+" "+contentLength+" <"+table.rows[i].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[i], 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[i], false)) {
                                overflowingTables++;
                            }
                        }
                    }
                }
                
                main();
                
                1 person found this helpful
                • 5. Re: Set table row height
                  thedesmodus Level 1

                  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!

                  • 6. Re: Set table row height
                    John Hawkinson Level 5

                    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;
                            }
                    
                    • 7. Re: Set table row height
                      thedesmodus Level 1

                      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[i];
                              contentLength = row.contents.join("").length;
                              if (debug > 1) {
                                  $.writeln("Row "+i+" has height "+  row.height+" "+contentLength+" <"+table.rows[i].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[i], 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[i], false)) {
                                      overflowingTables++;
                                  }
                              }
                          }
                      }
                      
                      main();
                      
                      
                      • 8. Re: Set table row height
                        John Hawkinson Level 5

                        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.

                        • 9. Re: Set table row height
                          thedesmodus Level 1

                          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[i];
                                  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[i].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[i], 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[i], false)) {
                                          overflowingTables++;
                                      }
                                  }
                              }
                          }
                          
                          main();
                          
                          
                          • 10. Re: Set table row height
                            John Hawkinson Level 5

                            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?

                            • 11. Re: Set table row height
                              thedesmodus Level 1

                              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

                              • 12. Re: Set table row height
                                John Hawkinson Level 5

                                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...

                                • 13. Re: Set table row height
                                  thedesmodus Level 1

                                  Amazing

                                   

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

                                  • 14. Re: Set table row height
                                    thedesmodus Level 1

                                    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

                                    • 15. Re: Set table row height
                                      John Hawkinson Level 5

                                      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...

                                      • 16. Re: Set table row height
                                        thedesmodus Level 1

                                        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[i];
                                                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[i].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;
                                        }
                                        
                                        
                                        • 17. Re: Set table row height
                                          John Hawkinson Level 5
                                          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 {
                                          
                                          • 18. Re: Set table row height
                                            John Hawkinson Level 5

                                            How're we doing? All set?

                                            • 19. Re: Set table row height
                                              thedesmodus Level 1

                                              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[i];
                                                      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[i].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[i], 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[i], false)) {
                                                              overflowingTables++;
                                                          }
                                                      }
                                                  }
                                              }
                                              
                                              main();
                                              
                                              

                                               

                                              Thanks again for all the help!!

                                              • 20. Re: Set table row height
                                                thedesmodus Level 1

                                                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?

                                                • 21. Re: Set table row height
                                                  John Hawkinson Level 5

                                                  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...).

                                                  • 22. Re: Set table row height
                                                    John Hawkinson Level 5

                                                    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.

                                                    1 person found this helpful
                                                    • 23. Re: Set table row height
                                                      thedesmodus Level 1

                                                      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?

                                                      • 24. Re: Set table row height
                                                        John Hawkinson Level 5

                                                        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[i];
                                                                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[i].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[i], 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[i], false)) {
                                                                        overflowingTables++;
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        
                                                        main();
                                                        

                                                         

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

                                                        • 25. Re: Set table row height
                                                          thedesmodus Level 1

                                                          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.

                                                          • 26. Re: Set table row height
                                                            John Hawkinson Level 5

                                                            Err...I'm afraid you'll need to supply a copy of the document that causes the failure...the script I posted works on the last one you supplied...

                                                            (sorry for the delay)

                                                            • 27. Re: Set table row height
                                                              thedesmodus Level 1

                                                              Here is a copy of part of the document. I think it indeed goes wrong at split cells.

                                                              http://www.hofhuis.org/transfer/table_sample.zip

                                                              • 28. Re: Set table row height
                                                                John Hawkinson Level 5

                                                                My goodness, that's rather weird. So yes, when your table contains cells that are merged/split in this fashion, InDesign considers the 2nd row (row #1) to be the four cells  starting with "Carrying amount." For some reason, you are not allowed to evaluate the "overflows" property on this alleged row, and attempting to do so produces an error ("overflows"). Instead, when you get this error, you must evaluate the "overflows" property on each of the cells within the row.

                                                                 

                                                                I don't really see why this should be the case, and wonder why it is not a bug (maybe it is). But in any case, the workaround is easy enough, if annoyingly increasing the complexity of the script: we have to try to evaluate row.overflows and detect the error. If there is no error, we save the result in a variable, which we use everywhere that we used to use row.overflows. If we get the error, we evaluate every cell's overflows property, and if any of them are true, we set our variable to true.

                                                                 

                                                                Here's the whole thing again, with that change:

                                                                 

                                                                 

                                                                var debug = 0;
                                                                
                                                                function fitTable(table, initial) {
                                                                    var i, row, contentLength, styleName, rowContents, styles, style,
                                                                        noOverflow = true, overflows, cellOverflows;
                                                                
                                                                    for (i=0; i<table.rows.length; i++) {
                                                                        row = table.rows[i];
                                                                        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[i].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 {
                                                                            var overflows;
                                                                            overflows = false;
                                                                            try {
                                                                                if (row.overflows) { overflows = true; }
                                                                            }
                                                                            catch (e) { 
                                                                                if (e.message === "overflows") {
                                                                                    if (debug>1) { $.writeln("CAUGHT ERROR"+ e); }
                                                                                    cellOverflows = row.cells.everyItem().overflows;
                                                                                    while (cellOverflows.length) {
                                                                                        if (cellOverflows.pop()) {
                                                                                            overflows = true;
                                                                                            break;
                                                                                        }
                                                                                    }
                                                                                } else {
                                                                                    throw(e);
                                                                                }
                                                                            }
                                                                            if (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 "+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[i], 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[i], false)) {
                                                                                overflowingTables++;
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                                
                                                                main();
                                                                
                                                                • 29. Re: Set table row height
                                                                  thedesmodus Level 1

                                                                  Thanks! it now goes great with the split cells.

                                                                  But oddly enough it seems to fail at recomposing other cells. For instance if the Note column in my latest example holds more lines, it does not expand.

                                                                   

                                                                  Maybe I am asking to much from the scripting capability of InDesign?

                                                                  • 30. Re: Set table row height
                                                                    John Hawkinson Level 5

                                                                    But oddly enough it seems to fail at recomposing other cells. For instance if the Note column in my latest example holds more lines, it does not expand.

                                                                    Maybe I am asking to much from the scripting capability of InDesign?

                                                                    Well, maybe you're asking too much of me

                                                                     

                                                                    It looks like InDesign doesn't exactly have the simplest model of these split and merged cells, and "goofy ****" seems to happen with them.

                                                                    I guess we can unconditionally check the overflows property of the constituent cells. This'll slow down the script, but it's probably no big deal. Better to be correct than to be fast.

                                                                     

                                                                    Replace the try/catch blocks with:

                                                                     

                                                                                cellOverflows = row.cells.everyItem().overflows;
                                                                                while (cellOverflows.length) {
                                                                                    if (cellOverflows.pop()) {
                                                                                        overflows = true;
                                                                                        break;
                                                                                    }
                                                                                  } 
                                                                    
                                                                    1 person found this helpful
                                                                    • 31. Re: Set table row height
                                                                      thedesmodus Level 1

                                                                      Great! That does the trick.

                                                                       

                                                                      I tested it on a 150 page document filled with tables, and it did indeed take a while, but no errors and all seems well.

                                                                       

                                                                      Thanks a bunch!!