0 Replies Latest reply on Nov 16, 2011 8:01 AM by Mahesh_JW

    InDesign Table Fit (Clear overflow, Height and Row fit)

    Mahesh_JW Level 1

      Hi All,

       

      I am using MagicFit.jsx for fit the table. But it does not clear the overflow and it does not fit the Height. I want to do all of this.

      Plz suggest.

       

       

       

      MagicFit.jsx

       

       

      function MagicFit(){

          app.scriptPreferences.version = 4.0;          //Because I am using CS5

          MagicFit_1()

          app.scriptPreferences.version = 6.0;

      }

       

      function MagicFit_1(){

          /***********************************************************************

       

              MagicFit 2.1b for InDesign CS / CS2 -- 01/18/06               

       

              Fits to content the WIDTH of the selected text container(s)   

       

              Features:                                                     

              - Fits selected TextFrame(s) width to content                 

              - 1st call: "strict" fitting (preserve each lines length)    

              - 2nd call (within 2 secs) : "fluid" fitting (preserve height)

              - (NEW) Alternate fitting of table column(s) if selected      

              - (NEW) Compute a minimal width by parsing embedded objects   

              - (NEW) Runs on selected frames, CELLS, groups, insertion pt  

       

              Installation & usage:                                         

       

              0) !! CS2 users only !!                                       

                 Rename this script file with .jsx extension                

                 (activating extend script features)                        

       

              1) Put the present file into the Presets/Scripts/ subdir      

       

              2) Run InDesign, open a document and select object(s) to fit  

                 (or put insertion point into)                              

       

              3) Run the script via Window > Automation > Scripts           

                 and double-clic on MagicFit.js                             

                 Alternate way: assign a keyboard shortcut to the script via

                 Edit > Keyboard Shortcuts... > Product area:"Scripts"      

       

              Help (FR) : http://marcautret.free.fr/geek/indd/magicfit/     

                  (sorry, thats a french web page!)                      

       

                      Feedbacks : marcautret@free.fr                    

       

          ***********************************************************************/

       

          //----------------------------------------------------------

          //            SETTINGS

          //----------------------------------------------------------

       

          var LATENCE = 2;         // in seconds (default:2)

          var PRECISION = 0.5;    // in pts (default:0.5)

          var APP_INT_VERSION = parseInt(app.version);

       

          //----------------------------------------------------------

          //            TOOLBOX FUNCTIONS

          //----------------------------------------------------------

       

          /*void*/ function exitMessage(/*exception*/ ex){

              alert("Error:\n" + ex.toString());

              exit();

          }

       

          //----------------------------------------------------------

          //            DOCUMENT METHODS

          //----------------------------------------------------------

       

          /*void*/ Document.prototype.setUnitsTo = function(/*units*/ newUnits){        // units can be single value (horiz=vert) or array(horizUnits, vertUnits)

              var arrUnits = (newUnits.length) ? newUnits : new Array(newUnits,newUnits);

              this.viewPreferences.horizontalMeasurementUnits = arrUnits[0];

              this.viewPreferences.verticalMeasurementUnits = arrUnits[1];

          }

       

          /*arr2*/ Document.prototype.getUnits = function(){

              return(Array(

                  this.viewPreferences.horizontalMeasurementUnits,

                  this.viewPreferences.verticalMeasurementUnits));

          }

       

          /*bool*/ Document.prototype.withinDelay = function(){

              if (this.label)

                  return( (Date.parse(Date())-this.label) <= LATENCE*1000 );

       

       

              return(false);

          }

       

          /*void*/ Document.prototype.storeTimeStamp = function(){

              this.label = Date.parse(Date()).toString();

          }

       

          //----------------------------------------------------------

          //            GENERIC METHODS (OBJECT LEVEL)

          //----------------------------------------------------------

       

       

          // Returns the "fittable-container" corresponding to THIS

          // Return array or collection HorizFit-compliant

          // NULL if failure

          /*arr*/ Object.prototype.asObjsToFit = function(){

              switch(this.constructor.name){

                  case "TextFrame" :            // textframe -> singleton this

                      return(Array(this));

       

                  case "Cell" :                // cells -> parent columns

                      var r = new Array();

                      // !! [CS1] Cell::parentColumn === Cell !!

                      // !! [CS2] Cell::parentColumn === Column !!

                      // !! [CS2] Cells::lastItem().parentColumn BUG !!

                      var c0 = this.cells.firstItem().name.split(":")[0];

                      var c1 = this.cells.lastItem().name.split(":")[0];

                      for (var i=c0 ; i<=c1; i++)

                          r.push(this.parent.columns[i]);

                      return(r);

       

                  case "Table" /*CS2*/ :        // table -> columns

                      return(this.columns);

       

                  case "Group" :                // group -> textFrames

                      return((this.textFrames.length>0) ? this.textFrames : null);

       

                  case "Text" :                // selection is Text or InsertionPoint

                  case "InsertionPoint" :        // -> run on container

                      var textContainer = this.getTextContainer();

                      return((textContainer) ? textContainer.asObjsToFit() : null);

       

                  default:

                      return(null);

              }

          }

       

          // Returns Text's or InsertionPoint's container :

          // Type returned: TextFrame or Cell - NULL if failure

          /*obj*/ Object.prototype.getTextContainer = function(){

              try{ // try...catch because of CS2 behaviour

                  if (this.parent.constructor.name == "Cell")           

                      return(this.parent);

                  if (this.parentTextFrames)        // plural in CS2

                      return(this.parentTextFrames[0]);       

                  if (this.parentTextFrame)    // single in CS1

                      return(this.parentTextFrame);

       

                  return(null);

              }catch(ex) {return(null);}

          }

       

          // Parse embedded "objects": tables, pageitems [including graphics]

          // and returns the max width

          // !! All parsed objects have to provide a computeWidth method !!

          /*int*/ Object.prototype.computeIncludedObjectsWidth = function(){

              var objsNames = new Array("pageItems","tables"); // could be extended

              var objsWidth = 0;

              var w = 0;

       

              for (var j=objsNames.length-1 ; j>=0 ; j--){

                  for (var i=this[objsNames[j]].length-1 ; i>=0 ; i--){

                      try{

                          w = this[objsNames[j]][i].computeWidth({VISIBLE:true});

                      }catch(ex){

                          w=0;

                      }

       

                      if (w > objsWidth) objsWidth=w;

                  }

              }

       

              return(objsWidth);

          }

       

          // Generic computeWidth method for bounded objects

          // VISIBLE true -> external width

          // VISIBLE false -> internal width

          /*int*/ Object.prototype.computeWidth = function(/*bool*/ VISIBLE){

              if (VISIBLE){

                  if (this.visibleBounds)

                      return(this.visibleBounds[3]-this.visibleBounds[1]);

              }

              else{

                  if (this.geometricBounds)

                      return(this.geometricBounds[3]-this.geometricBounds[1]);

              }

       

              return(0);

          }

       

          // Override Object::computeWidth for Table : returns simply the width

          /*int*/ Table.prototype.computeWidth = function(){

              return(this.width);

          }

       

          // Returns chars count for each LINE of this (-> array)

          // empty array  IF  this.lines==NULL  OR  this.lines.length==0

          /*arr*/ Object.prototype.createLinesSizesArray = function(){

              r = new Array();

              if (this.lines)

                  for (var i=this.lines.length-1; i>=0 ; i--)

                      r.unshift(this.lines[i].characters.length);

              return(r);

          }

       

          // Compare chars count beetween THIS and arrSizes argument

          // (generic method just presuming that THIS have lines prop.)

          // -> TRUE if isoceles, FALSE if not

          /*bool*/ Object.prototype.isoceleLines = function(/*arr*/ arrSizes){

              if (this.lines.length != arrSizes.length) return(false);

              for (var i=arrSizes.length-1 ; i>=0 ; i--)

                  if (arrSizes[i] != this.lines[i].characters.length)

                      return(false);

              return(true);

          }

       

       

          //----------------------------------------------------------

          //            TEXTFRAME METHODS

          // intanciate the part of the abstract process for TextFrames

          //----------------------------------------------------------

       

          /*bool*/ TextFrame.prototype.isEmpty = function(){

              return(this.characters.length==0);

          }

       

          /*bool*/ TextFrame.prototype.isOverflowed = function(){

              return(this.overflows);

          }

       

          /*int*/ TextFrame.prototype.getWidth = function(){

              return(this.computeWidth({VISIBLE:false}));

          }

       

          // Redim the frame in width by widthOffset

          /*void*/ TextFrame.prototype.resizeWidthBy = function(/*int*/ widthOffset){

              this.geometricBounds = Array(

                  this.geometricBounds[0],

                  this.geometricBounds[1],

                  this.geometricBounds[2],

                  this.geometricBounds[3] + widthOffset);

          }

       

          // Returns the minWidth of the frame according to embedded content

          // and inner space

          // inner width space

          /*int*/ TextFrame.prototype.computeMinWidth = function(){

              var inSpace = this.textFramePreferences.insetSpacing;

              var inWidth = (inSpace.length) ?

                  inSpace[1] + inSpace[3] :    // distinct left & right inspace

                  2*inSpace;                    // global inspace

       

              return(this.computeIncludedObjectsWidth() + inWidth);

          }

       

          /*int*/ TextFrame.prototype.getCharsCount = function(){

              return(this.characters.length);

          }

       

          /*int*/ TextFrame.prototype.getLinesCount = function(){

              return(this.lines.length);

          }

       

          // Return chars count BY LINE (-> array)

          /*arr*/ TextFrame.prototype.getLinesSizes = function(){

              return(this.createLinesSizesArray());

          }

       

          // YES -> -1  , NOT -> 1

          /*int*/ TextFrame.prototype.preserveCharsCount = function(/*int*/ charsCount){

              return( (this.characters.length != charsCount) ? 1 : -1 );

          }

       

          // Indicates whether:

          // - chars count equals linesCount

          // - frame DOES NOT overflow

          // YES -> -1  , NOT -> 1

          /*int*/ TextFrame.prototype.preserveLinesCount = function(/*int*/ linesCount){

              return( ((this.overflows) || (this.lines.length != linesCount)) ? 1 : -1 );

          }

       

          // Indicates whether:

          // each x line isoceles linesSizes[x]

          // YES -> -1  , NOT -> 1

          /*int*/ TextFrame.prototype.preserveLinesSizes = function(/*arr*/ linesSizes){

              return( (this.isoceleLines(linesSizes)) ? -1 : 1 );

          }

       

       

          //----------------------------------------------------------

          //            COLUMN METHODS

          // intanciate the part of the abstract process for Columns

          //----------------------------------------------------------

       

       

          /*bool*/ Column.prototype.isEmpty = function(){

              for (var i=this.cells.length-1; i>=0 ; i--)

                  if (this.cells[i].characters.length>0) return(false);

       

              return(true);

          }

       

          // Indicates whether AT LEAST a cell overflows

          // !! We can't trust Column::overflows !!

          /*bool*/ Column.prototype.isOverflowed = function(){

              for (var i=this.cells.length-1 ; i>= 0 ; i--)

                  if (this.cells[i].overflows) return(true);

       

              return(false);

          }

       

          /*int*/    Column.prototype.getWidth = function(){

              return(this.width);

          }

       

          // Redim the column width by widthOffset

          // !! we HAVE TO update the display after resizing !!

          /*void*/ Column.prototype.resizeWidthBy = function(/*int*/ widthOffset){

              this.width += widthOffset;

       

              // updates the display

              if (APP_INT_VERSION > 3)        // CS2+

                  this.recompose();

              else{

                  // CS -- thx to Tilo for this hack --

                  for(var i = this.cells.length - 1 ; i >= 0 ; i-- ){

                      // Comparing the cell contents against null

                      // seems to internally recompose the cell!

                      if (this.cells[i].contents == null) {}

                  }

              }

          }

       

       

          // Returns the minWidth of the column according to embedded content

          // and inner space

          /*int*/ Column.prototype.computeMinWidth = function(){

              var iCell = null;

              var w = 0;

              var r = 0;

       

              for (var i=this.cells.length-1 ; i>= 0 ; i--){

                  iCell = this.cells[i];

                  w = iCell.computeIncludedObjectsWidth() +

                      iCell.leftInset + iCell.rightInset;

                  if (w > r) r = w;

              }

       

              return(r);

          }

       

          // Returns SIGNED chars count BY CELL (negatif if overflows)

          /*arr*/ Column.prototype.getCharsCount = function(){

              var r = new Array();

              var sgn = 0;

              for (var i=this.cells.length-1 ; i>= 0 ; i--){

                  sgn = (this.cells[i].overflows) ? -1 : 1;

                  r.unshift(sgn * this.cells[i].characters.length);

              }

       

              return(r);

          }

       

          // Returns lines count BY CELL

          /*arr*/ Column.prototype.getLinesCount = function(){

              var r = new Array();

              for (var i=this.cells.length-1 ; i>= 0 ; i--)

                  r.unshift(this.cells[i].lines.length);

       

              return(r);

          }

       

          // Matrix: returns the chars count BY LINE / BY CELL

          /*bi-arr*/ Column.prototype.getLinesSizes = function(){

              var r = new Array();

              for (var i=this.cells.length-1 ; i>= 0 ; i--)

                      r.unshift(this.cells[i].createLinesSizesArray());

       

              return(r);

          }

       

          // Indicates whether:

          // overflow sign BY CELL x equals sgn(charsCount[x])

          // YES -> -1  , NO -> 1

          /*int*/ Column.prototype.preserveCharsCount = function(/*arr*/ charsCount){

              var sgn = 0;

              for (var i=this.cells.length-1 ; i>= 0 ; i--){

                  sgn = (this.cells[i].overflows) ? -1 : 1;

                  if (sgn * charsCount[i] < 0) return(1);

              }

       

              return(-1);

          }

       

          // Indicates whether:

          // - lines count BY CELL x equals linesCount[x]

          // - no cell overflows

          // YES -> -1  , NO -> 1

          /*int*/ Column.prototype.preserveLinesCount = function(/*arr*/ linesCount){

              for (var i=this.cells.length-1 ; i>= 0 ; i--){

                  if (this.cells[i].overflows) return(1);

                  if (this.cells[i].lines.length != linesCount[i]) return(1);

              }

       

              return(-1);

          }

       

          // Indicates whether:

          // - in each CELL x, each LIGNE y isoceles linesSizes[x][y]

          // (if a cell overflows, returns 1)

          // YES -> -1  , NO -> 1

          /*int*/ Column.prototype.preserveLinesSizes = function(/*bi-arr*/ linesSizes){

              for (var i=this.cells.length-1 ; i>= 0 ; i--){

                  if (this.cells[i].overflows) return(1);

                  if (this.cells[i].isoceleLines(linesSizes[i]) == false) return(1);

              }

       

              return(-1);

          }

       

          //----------------------------------------------------------

          //            METHODES CENTRALES

          //----------------------------------------------------------

       

          // !! [CS2 only] Prevents a strange crash on wide table columns selection !!

          // !! Thx to Tilo for this hack --

          /*void*/ Object.prototype.manageFit = function(/*bool*/ FLUIDFITTING){

              if (APP_INT_VERSION>=4){

                  $.gc();

              }

       

              // NOP if empty object

              if (this.isEmpty()) return;

       

              // min width to preserve

              var minWidth = this.computeMinWidth();

       

              // let's go!

              this.processFit(FLUIDFITTING, minWidth);

          }

       

          // Fits this object

          // if FLUIDFITTING -> fluid fitting, else: strict fitting

          // minWidth sets the threshold

          /*void*/ Object.prototype.processFit = function(/*bool*/ FLUIDFITTING, /*int*/ minWidth){

              if (FLUIDFITTING){ // FLUID FITTING

                  if (this.isOverflowed()){ // NB : overflowed CELLS are "transparent"

                      var charsCount = this.getCharsCount();

                      var evalFlag = function(thisObj){return(thisObj.preserveCharsCount(charsCount));}

                  }

                  else{

                      var linesCount = this.getLinesCount();

                      evalFlag = function(thisObj){return(thisObj.preserveLinesCount(linesCount));}

                  }

              }

              else{ // STRICT FITTING

                    // NB : overflowed columns are "intouchable"

       

                  if ((this.constructor.name=="Column") && (this.isOverflowed()))

                      return;

       

                  var linesSizes = this.getLinesSizes();

                  var evalFlag = function(thisObj){return(thisObj.preserveLinesSizes(linesSizes));}

              }

       

              // DICHOTOMIC LOOP

              var sgnFLAG = -1;

              var w = ( this.getWidth() - minWidth ) / 2;

       

              while (w >= PRECISION){

                  // resize width by +/- w

                  this.resizeWidthBy(sgnFLAG*w);

       

                  // +1 = increase | -1 = reduce

                  sgnFLAG = evalFlag(this);

       

                  // divide

                  w = w/2;

              }

       

              // exit with sgnFLAG==+1 -> undo last reduction -> +2w

              if (sgnFLAG>0) this.resizeWidthBy(2*w);

          }

       

       

          //----------------------------------------------------------

          // MAIN PROGRAM

          //----------------------------------------------------------

       

          if ( app.documents.length > 0 ){

              if ( app.activeWindow.selection.length > 0 ){

                  try{

                      var thisDoc = app.activeDocument;

                      var FLUIDFLAG = thisDoc.withinDelay();

       

                      var memUnits = thisDoc.getUnits();

                      thisDoc.setUnitsTo(MeasurementUnits.points);

       

                      var selObjs = app.activeWindow.selection;

                      var objsToFit = null;

                      for (var i=selObjs.length-1 ; i>=0 ; i--){

                          objsToFit = selObjs[i].asObjsToFit();

                          if (objsToFit){

                              for (var j=objsToFit.length-1 ; j>=0 ; j--)

                                  objsToFit[j].manageFit(FLUIDFLAG);

                          }

                      }

       

                      thisDoc.setUnitsTo(memUnits);

                      thisDoc.storeTimeStamp();

                  }catch(ex){

                      thisDoc.setUnitsTo(memUnits);

                      exitMessage(ex);

                  }

              }

       

              else

                  alert("No object selected!");

          }

          else

              alert("No document opened!");

      }