4 Replies Latest reply on Nov 27, 2013 2:29 PM by [Jongware]

    Getting only the selected tabs

    RobertKyle Level 2

      I have the chore of adusting thousands of tab stops in hundreds of paragraph styles, and have stolen some very handy scripts for resetting tab stops. My thanks to anyone who's ever posted such a snippet.

       

      I thought it would be handy and even easy to write a tab-nudger, the idea being that the user would select a range of text containing tabs and add or subtract a point at a time, but only for the tabs in the selection.

       

      The roadblock is that

       

      app.selection[0].tabStops

       

      returns all of the tab stops in the paragraph, even if the selected text only contains one or two of related tab characters. So I guess the script would somehow have to determine which of the tab stops in the paragraph go with the tab characters in the selection. But the "somehow" part has me stumped.

        • 1. Re: Getting only the selected tabs
          Jump_Over Level 5

          Hi,

           

          As you noticed, each insertionPoint, word, line, text has the same tabStops set as parent paragraph.

          So succesful edit of tabStops related to current selection needs to discover:

          • how many tabs (characters) are inside selection comparing to whole paragraph.
          • how many tabStops are defined for current text selection (supposed to be at least as many as count of tabs found inside paragraph)

           

          Below function return an array with two elements:

          array[0] ==> number of tabStops defined for current selection (maybe there is a need to add some)

          array[1] ==> array with tabStops indexes related to tabs in current selection;

           

          function tabsFromSel() {
                    var 
                              tabStopsArr = [],
                              k, stop;
          
                    if (!app.selection[0].hasOwnProperty ("baselineShift") ) return false;
          
                    app.findTextPreferences.findWhat = "\t";
                    var tabSel = app.selection[0].findText();
          
                    if (!tabSel) return false;
          
                    var 
                              tabTot = app.selection[0].paragraphs[0].findText(),
                              len = tabTot.length,
                              lenSel = tabSel.length,
                              tabStopsDefined = app.selection[0].tabStops.length;
          
                    while (len-->0)
                              if (tabTot[len]===tabSel[0])
                                        break;
          
                    stop = len + lenSel;
                    for (k = len; k < stop; k++)
                              tabStopsArr.push(k);
          
          return [tabStopsDefined, tabStopsArr];
          }
          

           

          So it could be a base for further modifications (i.e. user interaction with dialog)

          Function return false if there is no text_selection or no tabs found inside selection

           

          Jarek

          • 2. Re: Getting only the selected tabs
            RobertKyle Level 2

            Thanks very much, Jarek.

             

            I'm curious about the line concerning baseline shift. It's not an issue here but is something about a baseline shift that messes with this function?

            • 3. Re: Getting only the selected tabs
              Jump_Over Level 5

              That's used to determine if a selection is alike "text" object. If true - that's OK

              Jarek

              • 4. Re: Getting only the selected tabs
                [Jongware] Most Valuable Participant

                RobertKyle,

                 

                To expand on Jarek's answer: InDesign's Object Model is *very* smart on deciding what you got selected. If you run this simple script

                 

                alert (app.selection[0].constructor.name);
                

                 

                with a couple of different selections, you will see it can discern "Word", "Line" and "Paragraph" when selected; the generic "Text" otherwise. The same goes for selections inside a table: it can discern "Table" from "Cell" (and somehow I was convinced it could be "Column" and "Row" too, but can't get that to work right now).

                 

                Jarek's script needs "text"; and the usual Javascript way to check if an object is of a certain type is to use either "xx.constructor.name" or the boolean "xx instanceof yy". That works well for rectangles, text frames, and graphic lines, but you'd have to include a lot of different checks for all possible types of text selection. Not to mention Adobe may one day -- far in the future -- add some new kind of 'text', such as 'Endnote'. "TextColumn" is a recent addition -- and Jarek's trick treats it as 'a sort of text'.

                 

                This trick is to test if the selection has a certain property: xxx.hasOwnProperty("yyy"). You can select any property you like, as long it is one that is shared by all objects of the type you want, and is not one that appears in other objects with the same name. "fillColor", for example, would not qualify, because all text type have a fill color but so do Cells, Circles, and FindTextPreferences.

                 

                It works because a couple of InDesign's internal objects are derived from a common parent, and thus have all of the properties the parent also has (they usually also have a few properties of their own). You can see the derived objects for "Text" on http://jongware.mit.edu/idcs6js/pc_Text.html, in the purple background diagram near the top.

                 

                As it happens, 'baselineShift' is kind of a traditional property to check, and the only reason I can think of why is because Dave Saunders (.. I believe it was him) used it when he introduced this particular method, somewhere around 2004-or-even-earlier.

                1 person found this helpful