19 Replies Latest reply on Jun 26, 2008 3:43 PM by Brad Walrod

    Shrink current text frame by "one guide"?

    Brad Walrod Level 1
      Would it be possible for a script to reduce the depth of a selected text frame so that the bottom of the frame snaps to the next highest guide on the page? (I'm in CS3 on a Mac.)

      It would no doubt be simpler to do something just for the job I'm working on now, where I know the location of the guide as well as how many points smaller the frame needs to be; but it would be more interesting to do something for all jobs where I'm balancing spreads by setting them a line short, and I'll always have a guide in place.

      Brad
        • 1. Re: Shrink current text frame by "one guide"?
          sstanleyau Level 4
          You'd need to get the location of all horizontal guides on the page (and<br />probably its master), sort them, then get the location of the first one<br />higher than the bottom of your frame.<br /><br />Hmmm, looks like it's a bit more complicated because there can be guides on<br />the page of the master, and guides belonging to another page of the master<br />but extending across the spread.<br /><br />This should do what you want:<br /><br />tell application "Adobe InDesign CS3"<br />    tell document 1<br />        tell page 1<br />            set {y1, x1, y2, x2} to geometric bounds of text frame 1 --<br />whatever<br />            --  get guides on page<br />            try<br />                set theNums1 to location of guides whose orientation is<br />horizontal<br />            on error<br />                set theNums1 to {}<br />            end try<br />            set theSide to side<br />            -- guides on page via master<br />            try<br />                set theNums2 to location of guides of (get page 1 of applied<br />master whose side is theSide) whose orientation is horizontal<br />            on error<br />                set theNums2 to {}<br />            end try<br />            -- guides on page via master spread<br />            try<br />                set thenums3 to location of guides of applied master whose<br />orientation is horizontal and fit to page is false<br />            on error<br />                set thenums3 to {}<br />            end try<br />            set theNums to theNums1 & theNums2 & thenums3<br />            <br />            set minumumDiff to 10000 -- distance to guide; start high<br />            set theValue to 0 -- store the location value<br />            repeat with i from 1 to count of theNums<br />                -- calculate difference<br />                set theDiff to (y2 - (item i of theNums))<br />                -- check it's above the bottom of the frame<br />                if theDiff > 0 then<br />                    -- check it's closer than any so far<br />                    if theDiff < minumumDiff then<br />                        set minumumDiff to theDiff<br />                        set theValue to item i of theNums<br />                    end if<br />                end if<br />            end repeat<br />            set geometric bounds of text frame 1 to {y1, x1, theValue, x2}<br />        end tell<br />    end tell<br />end tell<br /> <br /><br />-- <br />Shane Stanley <sstanley@myriad-com.com.au>
          • 2. Re: Shrink current text frame by "one guide"?
            Level 1
            Shucks! Shane beat me to it. Here's a JavaScript to do the job:
            //DESCRIPTION: Reduce height of selected text frame to next guide
            

            if (app.documents.length > 0 && app.selection.length > 0) {
              reduceTFtoNextGuide(app.selection[0]);
            }

            function reduceTFtoNextGuide(sel) {
              if (sel instanceof TextFrame && sel.parent instanceof Page) {
                var bounds = sel.geometricBounds;
                var guides = sel.parent.guides;
                var next = bounds[0];
                for (var j = guides.length - 1; j >= 0; j--) {
                  if (guides[j].orientation == HorizontalOrVertical.horizontal) {
                    var loc = guides[j].location;
                    if (loc > next && loc < bounds[2]) {
                      next = Math.max(next, loc);
                    }
                  }
                }
                if (next > bounds[0]) {
                  bounds[2] = next;
                  sel.geometricBounds = bounds;
                } else {
                  alert("No suitable guide found.");
                }
              } else {
                alert("Script requires one free-standing text frame be selected.");
              }
            }
            Dave
            • 3. Re: Shrink current text frame by "one guide"?
              sstanleyau Level 4
              On 26/6/08 11:10 AM, "Dave Saunders" <member@adobeforums.com> wrote:<br /><br />>     var guides = sel.parent.guides;<br /><br />I think you need to include guides on applied masters, too.<br /><br />-- <br />Shane Stanley <sstanley@myriad-com.com.au>
              • 4. Re: Shrink current text frame by "one guide"?
                Brad Walrod Level 1
                Admittedly, it took me a while to get that "whatever" meant that I'd
                need to further define the selected box. Based on the Event Log
                (below), I'm guessing it's currently picking up my running head text
                frame.

                Perhaps that's why (if I'm reading the log correctly) it's not
                finding any guides. In a perfect world, it would just act on the
                parent(?) frame of the insertion point, as I'll likely have the text
                tool selected.

                And you're right that I need master page guides, as that's where the
                line-short guides reside.

                This was a lot more complicated a problem than I expected. Thanks for
                the code. Off to try Dave's JS.

                Brad

                --------

                tell application "Adobe InDesign CS3"
                get geometric bounds of text frame 1 of page 1 of document 1
                {0.0, 5.25, 18.5, 30.75}
                get location of every guide of page 1 of document 1 whose
                orientation = horizontal
                get side of page 1 of document 1
                left hand
                get page 1 of applied master of page 1 of document 1 whose side =
                left hand
                page id 524 of master spread id 519 of document "03_The
                Invitation.indd"
                get location of every guide of page id 524 of master spread id 519
                of document "03_The Invitation.indd" whose orientation = horizontal
                get location of every guide of applied master of page 1 of document
                1 whose orientation = horizontal and fit to page = false
                set geometric bounds of text frame 1 of page 1 of document 1 to
                {0.0, 5.25, 0, 30.75}
                "Adobe InDesign CS3 got an error: Unable to set bounding box."
                • 5. Re: Shrink current text frame by "one guide"?
                  Brad Walrod Level 1
                  This works well if I have the frame selected with the Selection tool,
                  but not with the cursor in the text. (Admittedly, my original message
                  just spoke of the selected frame!)

                  But Shane's right that it needs to check for master page frames.
                  Works great if I've drawn a frame on the page, tho. Thanks so much.

                  Brad


                  On Jun 25, 2008, at 9:10 PM, Dave Saunders wrote:

                  > Shucks! Shane beat me to it. Here's a JavaScript to do the job:
                  • 6. Re: Shrink current text frame by "one guide"?
                    sstanleyau Level 4
                    On 26/6/08 11:34 AM, "Brad Walrod" <member@adobeforums.com> wrote:<br /><br />> In a perfect world, it would just act on the  parent(?) frame of the insertion<br />> point, as I'll likely have the text  tool selected.<br /><br /><br />I was assuming you'd refine it for your target. You want something like:<br /><br />tell application "Adobe InDesign CS3"<br />    set theFrame to item 1 of parent text frames of insertion point 1 of<br />selection<br />    set thePage to parent of theFrame<br />    repeat<br />        -- ignore frames off the page<br />        if class of thePage is page then<br />            exit repeat<br />        else<br />            set thePage to parent of thePage<br />        end if<br />    end repeat<br />    <br />    tell thePage<br />        set {y1, x1, y2, x2} to geometric bounds of theFrame -- whatever<br />        --  get guides on page<br />        try<br />            set theNums1 to location of guides whose orientation is<br />horizontal<br />        on error<br />            set theNums1 to {}<br />        end try<br />        set theSide to side<br />        -- guides on page via master<br />        try<br />            set theNums2 to location of guides of (get page 1 of applied<br />master whose side is theSide) whose orientation is horizontal<br />        on error<br />            set theNums2 to {}<br />        end try<br />        -- guides on page via master spread<br />        try<br />            set thenums3 to location of guides of applied master whose<br />orientation is horizontal and fit to page is false<br />        on error<br />            set thenums3 to {}<br />        end try<br />        set theNums to theNums1 & theNums2 & thenums3<br />        <br />        set minumumDiff to 10000 -- distance to guide; start high<br />        set theValue to 0 -- store the location value<br />        repeat with i from 1 to count of theNums<br />            -- calculate difference<br />            set theDiff to (y2 - (item i of theNums))<br />            -- check it's above the bottom of the frame<br />            if theDiff > 0 then<br />                -- check it's closer than any so far<br />                if theDiff < minumumDiff then<br />                    set minumumDiff to theDiff<br />                    set theValue to item i of theNums<br />                end if<br />            end if<br />        end repeat<br />        set geometric bounds of theFrame to {y1, x1, theValue, x2}<br />    end tell<br />end tell<br /><br /><br />-- <br />Shane Stanley <sstanley@myriad-com.com.au>
                    • 7. Re: Shrink current text frame by "one guide"?
                      Brad Walrod Level 1
                      And I really appreciate your refining that for me. I was pretty sure
                      there were "parents" and insertion points" involved, but getting all
                      the words in the right order, well . . .

                      This works fantastic. Thanks again.

                      Brad


                      On Jun 25, 2008, at 9:51 PM, Shane Stanley wrote:

                      > I was assuming you'd refine it for your target. You want something
                      > like:
                      >
                      > tell application "Adobe InDesign CS3"
                      > set theFrame to item 1 of parent text frames of insertion point
                      > 1 of selection
                      • 8. Re: Shrink current text frame by "one guide"?
                        Level 1
                        Again, for the record, here's a JavaScript version:
                        //DESCRIPTION: Reduce height of selected text frame to next guide
                        

                        if (app.documents.length > 0 && app.selection.length > 0) {
                          reduceTFtoNextGuide(app.selection[0]);
                        }

                        function reduceTFtoNextGuide(sel) {
                          if (sel.hasOwnProperty("baseline")) {
                            sel = sel.parentTextFrames;
                            if (sel.length > 0) {
                              sel = sel[0];
                            }
                          }
                          if (sel instanceof TextFrame && sel.parent instanceof Page) {
                            var bounds = sel.geometricBounds;
                            var guides = sel.parent.guides.everyItem().getElements().concat(
                                sel.parent.appliedMaster.guides.everyItem().getElements());
                            var next = bounds[0];
                            for (var j = guides.length - 1; j >= 0; j--) {
                              if (guides[j].orientation == HorizontalOrVertical.horizontal) {
                                var loc = guides[j].location;
                                if (loc > next && loc < bounds[2] - 0.0001) {
                                  next = Math.max(next, loc);
                                }
                              }
                            }
                            if (next > bounds[0]) {
                              bounds[2] = next;
                              sel.geometricBounds = bounds;
                            } else {
                              alert("No suitable guide found.");
                            }
                          } else {
                            alert("Script requires one free-standing text frame be selected.");
                          }
                        }
                        Notice that I had to add a fudge-factor to the comparison; without it, one of the guides I'd set had become a filter -- the text frame wouldn't move past it presumably because of a rounding error.

                        Also, this is the first time I've ever used that mechanism to get a single array holding all the guides from both the page and its master spread.

                        Dave
                        • 9. Re: Shrink current text frame by "one guide"?
                          Level 1
                          Hmm. That last error message isn't entirely accurate any more because the selection can be text. I've included a check to make sure its not overset -- if it is, you get that error alert.

                          Dave
                          • 10. Re: Shrink current text frame by "one guide"?
                            Brad Walrod Level 1
                            I was hoping you'd post a tweaked version. It's especially
                            interesting to compare the two approaches of both scripting languages
                            (as well as both scripters ;-).

                            Your and Shane's scripts work on recto and verso pages, with the text
                            or selection tools chosen, on guides on the document or master pages,
                            and both can be undone with a simple Cmd-Z. These will be used
                            heavily for years to come, and I thank you both!

                            Brad


                            On Jun 26, 2008, at 6:55 AM, Dave Saunders wrote:

                            > Again, for the record, here's a JavaScript version:
                            >
                            > //DESCRIPTION: Reduce height of selected text frame to next guide
                            >
                            • 11. Re: Shrink current text frame by "one guide"?
                              sstanleyau Level 4
                              The trouble with getting all the guides of the master spread is that, for<br />example, if the page is recto you will get any guides applied only to the<br />verso page of the master. So I think you need to filter the master spread<br />ones for those that cross the spread, and then add in those on the actual<br />page used from the master that don't necessarily cross the spread.<br /><br />-- <br />Shane Stanley <sstanley@myriad-com.com.au>
                              • 12. Re: Shrink current text frame by "one guide"?
                                Level 1
                                Ah, you're right. I think this might be the first time I've ever written a script that (deliberately) worked with guides. And this is a case where AppleScript's whose clause beats JavaScript. I was hoping to use the index of the page but that breaks on the first page of the document if it is a right-page.

                                Well, this is all happening on one of my busiest ever days, so I'm going to not attempt to fix this until this evening at the earliest.

                                Thanks,

                                Dave
                                • 13. Re: Shrink current text frame by "one guide"?
                                  sstanleyau Level 4
                                  An "all guides" property would have made things a lot simpler. It's a<br />classic example of one of those things that looks simple until you get into<br />the details.<br /><br />-- <br />Shane Stanley <sstanley@myriad-com.com.au>
                                  • 14. Re: Shrink current text frame by "one guide"?
                                    Brad Walrod Level 1
                                    As it happens, neither of the scripts are working on the first
                                    (recto) page of the file I'm in now.

                                    Dave's can't find a "suitable" guide, and yours is yanking my main
                                    text frame (the third in a chain that starts with a chap num frame
                                    followed by one for the chap title) all the way up to the top of the
                                    page.

                                    From your discussion, I think I know why Dave's is failing. Not
                                    quite sure what it is with yours, but I'd guess it's the fact that
                                    it's the third frame, no?

                                    Brad


                                    On Jun 26, 2008, at 8:22 AM, Shane Stanley wrote:

                                    > An "all guides" property would have made things a lot simpler. It's a
                                    > classic example of one of those things that looks simple until you
                                    > get into
                                    > the details.
                                    • 15. Re: Shrink current text frame by "one guide"?
                                      Brad Walrod Level 1
                                      Arrgh. I spoke too soon. The problem wasn't because I was on the
                                      first page of the doc.

                                      The problem was that the guide on the first page was a non-overridden
                                      one from a master that the first page's master was based on.

                                      This chapter happens to be one that requires a different running head
                                      frame, so *all* it's pages use a master that's based on the main text
                                      master page. Neither script was working until I overrode the guide on
                                      the master page that's based on another master.

                                      Crazy stuff!

                                      Brad


                                      On Jun 26, 2008, at 8:22 AM, Shane Stanley wrote:

                                      > An "all guides" property would have made things a lot simpler. It's a
                                      > classic example of one of those things that looks simple until you
                                      > get into
                                      > the details.
                                      • 16. Re: Shrink current text frame by "one guide"?
                                        Harbs. Level 6
                                        Hi Brad,<br /><br />Here's a build-off of Dave's script which should do the trick...<br /><br /><br /><br />//DESCRIPTION: Reduce height of selected text frame to next guide<br /><br />if (app.documents.length > 0 && app.selection.length > 0) {<br />    reduceTFtoNextGuide(app.selection[0]);<br />}<br /><br />function reduceTFtoNextGuide(sel) {<br />    if (sel.hasOwnProperty("baseline")) {<br />        sel = sel.parentTextFrames;<br />        if (sel.length > 0) {<br />            sel = sel[0];<br />        }<br />    }<br />    if (sel instanceof TextFrame && sel.parent instanceof Page) {<br />        var page = sel.parent;<br />        var bounds = sel.geometricBounds;<br />        var index =  page== page.parent.pages[0] ? 0:1;<br />        index=page==app.documents[0].pages[0]? 1:index;<br />        var guides = GetGuides(page,index);<br /><br />        var next = bounds[0];<br />        for (var j = guides.length - 1; j >= 0; j--) {<br />            if (guides[j].orientation == HorizontalOrVertical.horizontal) {<br />                var loc = guides[j].location;<br />                if (loc > next && loc < bounds[2] - 0.0001) {<br />                    next = Math.max(next, loc);<br />                }<br />            }<br />        }<br />        if (next > bounds[0]) {<br />            bounds[2] = next;<br />            sel.geometricBounds = bounds;<br />        } else {<br />            alert("No suitable guide found.");<br />        }<br />    } else {<br />        alert("Script requires one free-standing text frame be selected.");<br />    }<br />}<br />function AsArray(collection){<br />    if(collection instanceof Array){return collection.slice(0)}<br />    else{return collection.everyItem().getElements().slice(0)}<br />    }<br />function GetGuides(page,index){<br />    var retVal=AsArray(page.guides);<br />    var spreadGuides = AsArray(page.parent.guides);<br />    for(var i=0;i<spreadGuides.length;i++){<br />        if(! spreadGuides[i].fitToPage){retVal.push(spreadGuides[i])}<br />        }<br />    if(page.appliedMaster){<br />        retVal = <br />retVal.concat(GetGuides(page.appliedMaster.pages[index],index));<br />        }<br />    return retVal;<br />    }<br /><br />Harbs
                                        • 17. Re: Shrink current text frame by "one guide"?
                                          sstanleyau Level 4
                                          On 27/6/08 4:20 AM, "Brad Walrod" <member@adobeforums.com> wrote:<br /><br />> Neither script was working until I overrode the guide on<br />> the master page that's based on another master.<br /><br />Masters based on masters can be a pain in scripting -- they're so easy to<br />overlook.<br /><br />For completeness' sake, this should cover it, and includes Dave's correction<br />value:<br /><br />tell application "Adobe InDesign CS3"<br />    set theFrame to item 1 of parent text frames of insertion point 1 of<br />selection<br />    set thePage to parent of theFrame<br />    repeat<br />        -- ignore frames off the page<br />        if class of thePage is page then<br />            exit repeat<br />        else<br />            set thePage to parent of thePage<br />        end if<br />    end repeat<br />    <br />    set {y1, x1, y2, x2} to geometric bounds of theFrame -- whatever<br />    --  get guides on page<br />    try<br />        set theNums to location of guides of thePage whose orientation is<br />horizontal<br />    on error<br />        set theNums to {}<br />    end try<br />    set theSide to side of thePage<br />    repeat while applied master of thePage is not nothing -- allow for<br />nested masters<br />        -- guides on page via master<br />        try<br />            set end of the theNums to location of guides of (get page 1 of<br />applied master of thePage whose side is theSide) whose orientation is<br />horizontal<br />        end try<br />        -- guides on page via master spread<br />        try<br />            set end of theNums to location of guides of applied master of<br />thePage whose orientation is horizontal and fit to page is false<br />        end try<br />        set thePage to page 1 of applied master of thePage whose side is<br />theSide<br />    end repeat<br />    <br />    set minumumDiff to 10000 -- distance to guide; start high<br />    set theValue to 0 -- store the location value<br />    set y2 to y2 - 1.0E-4 -- so it won't stay at one guide<br />    repeat with i from 1 to count of theNums<br />        -- calculate difference<br />        set theDiff to (y2 - (item i of theNums))<br />        -- check it's above the bottom of the frame<br />        if theDiff > 0 then<br />            -- check it's closer than any so far<br />            if theDiff < minumumDiff then<br />                set minumumDiff to theDiff<br />                set theValue to item i of theNums<br />            end if<br />        end if<br />    end repeat<br />    set geometric bounds of theFrame to {y1, x1, theValue, x2}<br />end tell<br /><br /><br /><br />-- <br />Shane Stanley <sstanley@myriad-com.com.au>
                                          • 18. Re: Shrink current text frame by "one guide"?
                                            Brad Walrod Level 1
                                            Indeed it does. The freaky thing is I was just starting (unbeknownst
                                            to me) a page that required this when I decided to switch over to
                                            Mail (to take a break).

                                            No need to go in and override the guides on based-on masters for this
                                            chapter . . .

                                            When I get a chance, I'll compare the two scripts to see if I can
                                            figure out the difference(s)!

                                            Thanks.

                                            Brad


                                            On Jun 26, 2008, at 7:07 PM, Harbs wrote:

                                            > Here's a build-off of Dave's script which should do the trick...
                                            >
                                            • 19. Re: Shrink current text frame by "one guide"?
                                              Brad Walrod Level 1
                                              And now this one works great, too!

                                              (And I'll compare this one with the last version as soon as I come up
                                              for air.)

                                              Thanks again.

                                              Brad


                                              On Jun 26, 2008, at 7:25 PM, Shane Stanley wrote:

                                              > Masters based on masters can be a pain in scripting -- they're so
                                              > easy to
                                              > overlook.