14 Replies Latest reply on Dec 12, 2011 12:08 PM by [Jongware]

    Align object to a line of text

    peterkemp47

      Back in the early to mid 90s, there was a really cool utility for QUark produced by Hell (not the location, the scanner company). You could click on a pint on an object and then click on a line of type in a paragraph and the program would align the object with the baseline of that line of type. I realize you could do that with the baseline grid in ID but that would mean your text would have to be using snap to baseline. It seems like this is something that could be done with a script in ID.

       

      Do any of the old timers remember this utility? Has anyone ever done anything like this or is it even possible? It was a very useful utility.

        • 1. Re: Align object to a line of text
          [Jongware] Most Valuable Participant

          peterkemp47 wrote:

          You could click on a p[o]int on an object and then click on a line of type in a paragraph and the program would align the object with the baseline of that line of type.

           

          Can you mock up a dummy showing what it should look like?

           

          Use this to insert an image in your post:

          Screen Shot 2011-12-10 at 8.39.21 PM.png

          • 2. Re: Align object to a line of text
            peterkemp47 Level 1

            Thanks for the reply. Hope this example makes sense.

             

            BTW, really enjoyed your piece on IndesignSecrets about begining Java scripting. Really makes me want to give it a try.Sanp to baseline example.jpg

            • 3. Re: Align object to a line of text
              [Jongware] Most Valuable Participant

              Okay, my first thought is this is going to require some more thinking.

               

              Scripts do not support point-and-then-click somewhere else -- if your image is selected and you click on the textline, the image gets deselected and the script won't know what to move there. Equally, clicking the image, then running the script and then clicking somewhere else won't work either, as a script cannot wait for a while in the background for your next move.

              • 4. Re: Align object to a line of text
                Marijan Tompa [tomaxxi] Level 4

                Jongware,

                 

                I think this can be done by using simple ScriptUI palette with two buttons. Select the image, click the first button, script grabs container ID or something, then click inside text, click on second button, script grabs text baseline, and moves image container by Y difference between image bottom and baseline. Furthermore, maybe script can watch which reference point is selected, and use it instead of just using bottom one.

                 

                --

                Marijan (tomaxxi)

                http://tomaxxi.com

                • 5. Re: Align object to a line of text
                  [Jongware] Most Valuable Participant

                  Oh but I'm terrible with palettes ...

                   

                  I'm also terrible with target engines, so I don't know if using one of these could work? (It would require you to run the script twice, which is also Not Very Nice.)

                  • 6. Re: Align object to a line of text
                    Haakenlid Level 3

                    This isn't what you asked for, but it would be quite simple to write a script that adds a guide at the baseline of the selected text or insertion point.

                    • 7. Re: Align object to a line of text
                      [Jongware] Most Valuable Participant

                      Aah, now that gave me an idea.

                       

                      Peter: click your text cursor into a text line and then run this script. It will scan the images on the current page and determine which one is closest above the text cursor. If it finds one, it will move it down to fit snugly on your baseline. In general, it should be obvious which image will move, but as it only does one move you can always undo it if the wrong one slides down.

                       

                      This is a Javascript so save as "moveImageToBaseline.jsx" in your Scripts folder.

                       

                      Extensive commenting is free today.

                       

                      //DESCRIPTION:Move image nearest to the current text selection down to baseline.
                      // A Jongware Script 11-Dec-2011
                      
                      // Check if we're anywhere inside a line:
                      // Any document at all?
                      if (app.documents.length > 0 &&
                                // A single selection -- the text cursor?
                                app.selection.length == 1 &&
                                // ... anywhere on a text line?
                                app.selection[0].hasOwnProperty("baseline"))
                                // ... finally, do something!
                                {
                                          // Grab the baseline position
                                          verticalPosition = app.selection[0].baseline;
                                          // Get a handle to all images on this page
                                          images = app.activeWindow.activePage.allGraphics;
                                          // If it's only one, we're using it
                                          if (images.length == 1)
                                                    image = images[0];
                                          else          // Find one above our line
                                          {
                                                    // Sort by bottom y; lowest should come first
                                                    images.sort (function(x,y) { return x.geometricBounds[2] - y.geometricBounds[2]; });
                                                    // Find nearest above the vertical position
                                                    while (images.length > 0)
                                                    {
                                                              image = images.pop();
                                                              if (image.geometricBounds[2] < verticalPosition)
                                                                        break;
                                                    }
                                                    // Check if the last image was also too low
                                                    if (image.geometricBounds[2] >= verticalPosition)
                                                              image = null;
                                          }
                                          // Did we find a valid one?
                                          if (image != null)
                                          {
                                                    // Move the image to this position. Important: for an
                                                    // image we have to use 'parent' to move its *frame*!
                                                    image.parent.move (undefined, [0, verticalPosition - image.geometricBounds[2]]);
                                          }
                                }
                      
                      • 8. Re: Align object to a line of text
                        Marijan Tompa [tomaxxi] Level 4

                        Nice one Jongware!

                         

                        Here is something different.

                        It requires InDesign CS5 or newer.

                        First, select frame with image inside,

                        start the script and click somewhere inside text.

                         

                        #targetengine tomaxxiENGINE
                        
                        if(parseInt(app.version) >= 7){
                            if(app.selection.length == 1
                                && app.selection[0].hasOwnProperty("graphics")
                                && app.selection[0].graphics.length === 1){
                                    var myObj = app.selection[0];
                                    app.addEventListener("afterSelectionChanged", moveImage);
                            }
                        }else{
                            alert("This script requires Adobe InDesign CS5 or newer!", "Error!", true);
                        }
                        
                        function moveImage(e){
                            app.removeEventListener("afterSelectionChanged", moveImage);
                            if(app.selection.length
                                && app.selection[0].hasOwnProperty("baseline")
                                && myObj.parentPage === app.selection[0].parentTextFrames[0].parentPage){
                                    var tB = app.selection[0].baseline;
                                    myObj.move(
                                        [myObj.geometricBounds[1],
                                            tB + (function(){
                                                    var tP = app.activeWindow.transformReferencePoint.toString();
                                                        if(tP.indexOf("BOTTOM") != -1){
                                                            return myObj.geometricBounds[0] - myObj.geometricBounds[2];
                                                        }else if(tP.indexOf("CENTER") != -1){
                                                            return (myObj.geometricBounds[0] - myObj.geometricBounds[2])/2;
                                                        }
                                                    return 0;
                                            }())
                                        ]
                                    );
                            }
                        }
                        

                         

                        --

                        Marijan (tomaxxi)

                        http://tomaxxi.com

                        • 9. Re: Align object to a line of text
                          peterkemp47 Level 1

                          Jongware

                           

                          That does the job. Very nice. I don't want to take up any more of your time and I appreciate very much what you have done. I was originally trying to see if a script existed and didn't intend for you or Marljan to spend time coming up with one.

                           

                          If you are interested in taking this thing any further, how difficult would it be for the script to align other types of objects such as a line or even a line of text in another text box?

                           

                          Thanks again for your efforts.

                           

                          Peter

                          • 10. Re: Align object to a line of text
                            peterkemp47 Level 1

                            Marijan

                             

                            Thanks for the coming up with this example. I'm running CS5 but when I try to execute the script, I get an error saying

                             

                            Cannot execute script in target engine 'tomaxxiENGINE'!

                            (#57) Engine 'tomaxxiENGINE' does not exists!

                             

                            Is tomaaiENGINE something I need from your web site.

                             

                            BTW, just went to your site and it's really cool. Adding it to my bookmarks.

                             

                            Thanks again for your effort.

                             

                            P

                            • 11. Re: Align object to a line of text
                              Marijan Tompa [tomaxxi] Level 4

                              You are welcome Peter!

                               

                              You are probably trying to start this script from ExtendScript Toolkit.

                              It's better for you to save it and run it from scripts panel inside InDesign.

                              Here is the link for the script: http://bit.ly/s7qcT9

                               

                              Hope that helps.

                               

                              --

                              Marijan (tomaxxi)

                              • 12. Re: Align object to a line of text
                                peterkemp47 Level 1

                                That's what I was doing. Works now. I guess it would take a UI to be able to select what part of the object you want to have align with the baseline.

                                 

                                Thanks again for the response and effort.

                                 

                                P

                                 

                                 

                                Peter Kemp Designer & Computer Advisor

                                 

                                address: 1216 Cannes Place | Carrollton, TX 75006-2919

                                 

                                phone: 972.245.0731 | email: peterkemp@pkdesign.org

                                • 13. Re: Align object to a line of text
                                  Marijan Tompa [tomaxxi] Level 4

                                  Try changing transform reference point

                                  Also, it works with multiple images selected as well!

                                  • 14. Re: Align object to a line of text
                                    [Jongware] Most Valuable Participant

                                    All it takes is determine which vertical position you want to relate to. In this case I used the baseline of a selected text; but, sure, you can use whatever you like.

                                     

                                    For a horizontal line, selected, you could use

                                     

                                    verticalPosition = app.selection[0].geometricBounds[0]

                                     

                                    -- this also works with all other objects that has a geometricBounds property, of which element #0 is the top y position.

                                     

                                    Theoretically my version should work just fine with text in a text box.