5 Replies Latest reply on Sep 3, 2014 7:25 AM by cchimi

    JavaScript property to tell if text is in a continued table

    cchimi Level 2

      Hi,

      Is there any way to determine if text in a textframe is within a table, even if that table has been threaded through multiple text frames? I can check the tables count for the text frame where the table begins to see if it has a table, and then work from there for that frame. However, subsequent text frames have a tables.length of 0. Individual characters within the table, when selected, have a parent of Cell, but in my case I need to be able to check the first character in the frame and move forward based on whether that cell is in a table. For reasons that aren't clear to me, that character is never the child of Cell. And, if I pull subsequent characters from the (let's say) textFrame.characters collection, I only get characters that appear after the table (source line or caption). I'm obviously missing something about how the table is referenced in the DOM, but I can't figure out what it is.

       

      What I want:

      - Given a textFrame, determine if it begins with a table (so, check first character in textFrame for "table-ness")

       

      What I'm getting

      - The table itself seems invisible to the textFrame object.

       

      I hope this question is clear enough. I'm having a little trouble expressing the problem. Thank you!

        • 1. Re: JavaScript property to tell if text is in a continued table
          TᴀW Adobe Community Professional & MVP

          Hi,

           

          The short answer is, you're out of luck.

           

          The longer answer is, there is virtually no way of knowing what page a

          character in a table is on, if that table happens to extend over several

          pages.

           

          It's the same for footnotes that extends over 2 or more pages. There is

          virtually no way of knowing what page any given character in the

          footnote is on in such a case.

           

          I say no way because I seem to remember some trick involving anchored

          objects, whereby you insert an anchored object after a given character,

          then release it, and then check which page it lands up on.

           

          The way a table works is like this:

           

          A table lives inside a single character (which is not to say that the

          parent of a table is a character -- go figure!). You can get hold of the

          insertionPoint before that character with myTable.storyOffset. No matter

          how long the table is -- 1000 pages or more -- it still lives inside

          that single character.

           

          So when a table extends over several text frames, then, indeed, you will

          find that the table count for all subsequent text frames except the

          first is zero. In fact, if there is nothing in them but the continuation

          of a table, you will find that their character count and insertionPoint

          count is also zero. This is a limitation of the InDesign's scripting

          DOM. InDesign itself is perfectly aware that the text frame is not empty

          in such a case, but querying it via scripting gets you the wrong answer.

           

          A table contains cells. That is, the parent of a cell is a table, not a

          text frame. So let's say you've selected text inside the 500th cell in

          your table, on the 10th page of a multi-page table. You will have no way

          of knowing what page that cell is on, because if you check

          myCell.parent.parent, you'll get the textFrame of the character

          containing the entire table, and if you check myCell.parent.storyOffset

          you'll get the insertionPoint before the character containing the table,

          which again is on the first page of the table.

           

          Perhaps if you tell us exactly what you're trying to achieve, we might

          come up with a workaround.

           

          Ariel

          • 2. Re: JavaScript property to tell if text is in a continued table
            cchimi Level 2

            Thank you! That was extremely informative. I'm going to mull this information over and perhaps pop back in with a better description of what I need to do. Again, appreciate the thoroughness. I do a fair bit of scripting but there are corners of the DOM where I'm practically blind.

            • 3. Re: Re: JavaScript property to tell if text is in a continued table
              cchimi Level 2

              So, I came up with a bit of a workaround that I figured I'd share. It's all very first/second draft now and surely requires some refining. My specific need is to find the topmost text frame on a page (taking into consideration some known exceptions like running heads) and insert some text at the beginning of it. Because tables have their insertion points within cells I had already been checking text frames for tables; but I didn't realize that multi-frame tables lose their "table-ness" as you move through the frames.

               

              So, I have two functions. The first determines if the textframe has a table, and if so, returns it. To do this, I check the document offset of the last character in the previous table to see if it falls on or after my textframe's page. This assumes two things that I'm still confirming: a) that the textframe where a table starts has at least one character (based on what Ariel stated and my own observations, this seems guaranteed) and b) that the textframe where a table ends has at least one character if it flows into another textframe. This is harder to confirm; but I've been unable to create a scenario where this isn't the case. If one comes up this will need some reworking to accommodate that case. So far it always seems to have at least a final paragraph return.

               

              function firstTableinTFrame(funcTFrame)
              {
                  if (funcTFrame.parentStory.tables.length == 0) {return null;}
                  else if (funcTFrame.previousTextFrame !== null)
                  {
                      var prevTFrame = funcTFrame.previousTextFrame;
                      if (prevTFrame.characters.length == 0)
                      {
                          while (prevTFrame.previousTextFrame !== null)
                          {
                              prevTFrame = prevTFrame.previousTextFrame;
                              if (prevTFrame.characters.length > 0) {break;}
                          }
                      }
                      if (prevTFrame.tables.length == 0 && funcTFrame.tables.length == 0) {return null;}
                      else if (prevTFrame.tables.length == 0) {return funcTFrame.tables[0];}
                      else if (prevTFrame.tables[-1].cells[-1].characters[-1].parentTextFrames[0].parentPage.documentOffset >= funcTFrame.parentPage.documentOffset) {return prevTFrame.tables[-1];}
                      else {return null;}
                  }
                  else {return null;}
              }
              
              

              The second function returns the first cell in a table that appears within a particular textframe by comparing the parentTextFrame of the first insertion point to my textframe.

               

               

              function getFirstCellinTFrame(funcTable, funcTFrame)
              {
                  for (var i = 0; i < funcTable.rows.length; i++)
                  {
                      var funcRow = funcTable.rows[i];
                      if (funcRow.cells[0].insertionPoints[0].parentTextFrames[0] === funcTFrame) {return funcRow.cells[0];}
                  }
                  return null;
              }
              
              

              I have some concerns about row/colspans and how they might affect this, and I'm also halfway convinced that there's a quicker way to move through those rows. But this is working in my early testing.

               

              Anyway, very draft-y, as I said, but it was an interesting problem so I thought I'd share. Suggestions or improvements or admonitions welcome.

              • 4. Re: Re: Re: JavaScript property to tell if text is in a continued table
                Laubender Adobe Community Professional & MVP

                Also worth mentioning: A different approach would be to duplicate the textFrame you want to get information of. Parts of a threaded table would be duplicated with it as a new table not threaded. *Now* you can tell, if the textFrame has a table from the dup.

                 

                var myDupTextFrame = myTextFrame.duplicate();
                

                 

                If the original text frame is anchored (its parent is a character) or if it is threaded to an anchored text frame, you have to move the duplicate to the position of the original one.

                 

                var myTextFrame = app.selection[0];
                var myProperties = myTextFrame.properties;
                
                myTextFrame.duplicate().properties = 
                    {
                        geometricBounds:myProperties.geometricBounds, 
                        fillColor:"Magenta" 
                        /*etc.*/
                    };
                

                 

                Uwe

                • 5. Re: Re: Re: JavaScript property to tell if text is in a continued table
                  cchimi Level 2

                  Thank you for that idea, it's certainly cleaner in a lot of ways. I happen to have a requirement that I don't change the content while I'm working on it (other than adding my text) for reasons beyond the scope of this question. But that is good information to have.