Resize Pages Graphics by Percent
Conspicuously missing from Pages is the ability to resize graphic objects by specific percents. You can say “make this graphic 2 inches wide,” but you can’t say “make this graphic 30% of its current width.” So, I wrote a script to do the dirty work for me:
It resizes the selected graphics by the specified percentage.
Download
The “Recenter” version keeps the graphic centered at its original location, which I have found to be rather annoying. Install in ~/Library/Scripts/Applications/Pages/
and invoke with a script runner of your choice.
Notes
Unfortunately, there doesn’t seem to be a scriptable way to determine whether the “Constrain proportions” options is set for a particular graphic. Since this option affects size changes, I simply make the assumption that it is set. It is, by default, for inserted images. For other graphics, check the “Metrics” inspector pane:
Note that images are not necessarily inserted at their original size. If you want to resize an image to some percentage of its actual size, be sure to click the “Original Size” button before resizing.
This script was written with Pages’ page layout mode in mind, but it should work with graphics in word processing mode, too. There are some rough edges, particularly where handling different sorts of selections is concerned.
Here is a video demonstration.
Posted on Monday, September 24th, 2007. Tags: applescript, mac, pages.
Script Runners
Rather than repeatedly explaining how to launch each script I write, I’m going to use this post as a generic reference.
AppleScripts are typically little bits of code that extend or connect your applications’ functionality. As such, they are not necessarily invoked like normal programs. Many fine utilities exist which provide convenient ways to run scripts, including LaunchBar, Butler, QuickSilver, Keyboard Maestro, and others. Here, however, I will describe the simple script runners I prefer, one of which is even built in to Mac OS X.
FastScripts
I favor FastScripts, which utilizes the same script folders as Apple’s Script Menu. It features assignable keyboard shortcuts, which help scripts act more like natural extensions of your applications. The FastScripts menu looks like this:
Apple Script Menu
To enable the Script Menu, open “AppleScript Utility” (in /Applications/AppleScript/
) and check the “Show Script Menu in menu bar” option:
A “script” icon will appear in your menu bar. It displays a menu like this:
Scripts stored in ~/Library/Scripts/Applications/Finder/
are listed in the “Finder Scripts” section, which appears only when the Finder is the frontmost application. Scripts stored in ~/Library/Scripts/
are listed in the unlabeled section and are always accessible. You can create application subfolders for application-specific scripts yourself. The tilde (~
) represents your home folder.
Here is a video demonstration of the Script Menu.
Posted on Monday, September 24th, 2007. Tags: applescript, fastscripts, mac.
User Interfaces for ThisService Scripts
ThisService is arguably — and appropriately — oriented towards text-processing and other “faceless” services. However, with a little imagination it is easy to conjure uses for the basic user interaction capabilities provided by AppleScript’s Standard Additions. Incorporating these commands in a service script requires a little extra sleight of hand, as it may be necessary to direct them to whatever application is active when the service is invoked.
I have had variable success in my various attempts to do this. Here is a summary of how it can be done, combined with an account of problems I’ve encountered with certain configurations.
Finding the Name of the Frontmost Application
In his example word count service, John Gruber demonstrates how to use System Events to determine the name of the frontmost application:
tell application "System Events" set _app to the name of the first process whose frontmost is true end tell
Another method discussed at the Mac OS X Hints forums also seems to work, even though the .app
extension is included in the application name:
set _app to name of (info for (path to frontmost application))
Now the frontmost application (whatever it may be) can be directed to do something.
tell application _app to ...
This is useful because we don’t necessarily know what application will be active when our service is invoked.
An Interface for Input Services: A Predictable Success
ThisService can generate three kinds of scripts: those that act on input, those that produce output, and those that do both (filters). Gruber’s word count service acts on input, as does my save selection service. The AppleScript that powers these kinds of services looks something like this:
on process(_input) tell application "System Events" to set _app to the name of the first process whose frontmost is true tell application _app to display alert "Input: " & _input end process
When text is selected and the service is invoked, an alert reports the selected text.
An Interface for Output Services: A Disappointing Surprise
Here is the code for a simple service that produces output. Via the same mechanism as the input service, it attempts to report the name of the frontmost application and return that string:
on process() tell application "System Events" to set _app to the name of the first process whose frontmost is true tell application _app to display alert "Output: " & _app return _app end process
Running this service causes the frontmost application to become unresponsive for an abnormal length of time. Spin Control indicates that the service executable also hangs, although I don’t know how to interpret the report. The alert subsequently appears, but the service fails: the script’s return value is not inserted. A relevant message appears in the Console:
2007-09-12 21:45:28.621 TextEdit[2721] tossing reply message sequence 9 on thread 0x306a90
An Interface for Filter Services: Beating a Dead Horse
This filter service exhibits the same problem as the example output service.
on process(_input) tell application "System Events" to set _app to the name of the first process whose frontmost is true tell application _app to display alert "Input: " & _input & return & "Output: " & _app return _app end process
The alert appears after an extended delay, but no output is received.
An Interface Compromise for Output and Filter Services
One way to circumvent the issue is to tell System Events to display the interface itself. This eliminates the delay and allows the service to return successfully.
on process() tell application "System Events" set _app to the name of the first process whose frontmost is true activate display alert "Output: " & _app end tell return _app end process
Unfortunately, this approach has the unresolved side effect of stealing focus from the frontmost application’s windows. Explicitly restoring focus would require something like tell application _app to activate
, which exhibits the problematic behavior.
on process(_input) tell application "System Events" set _app to the name of the first process whose frontmost is true activate display alert "Input: " & _input & return & "Output: " & _app end tell return _app end process
Without activate
, System Event’s alert wouldn’t receive focus, either.
Inconclusive Conclusions
The method described above allows output and filter services to present simple user interfaces, but it is an imperfect and somewhat annoying solution. If you want to provide a robust interface for an arbitrary service, you should probably write the service from scratch. On the other hand, tell application _app
’s compatibility with input services suggests the same idiom ought to be possible with the other kinds of services produced by ThisService.
It is also possible that I have overlooked or misunderstood some aspect of AppleScript, services, or Mac OS X which explains the perceived discrepancy between service types. Elucidation is welcome.
Posted on Wednesday, September 12th, 2007. Tags: code.
Tcl:: Language Module
TextWrangler includes basic support for Tcl syntax highlighting and procedure recognition. Procedures are listed in a popup menu that makes it easy to navigate around large files. Unfortunately, this mechanism does not recognize procedures defined in a namespace with the concise namespace::procedure
syntax. The intervening “::
” characters are not among those TextWrangler normally recognizes as valid identifier characters.
For example, “Bar” appears in the function menu when a procedure is defined like this:
namespace eval Foo { proc Bar {} { puts "Hello, World!" } }
I prefer this syntax:
proc Foo::Bar {} { puts "Hello, World!" }
but procedures defined this way don’t appear in the function menu:
Rather than forfeit the convenience of the function popup or conform to a more cumbersome convention, I created a codeless language module that essentially duplicates TextWrangler’s built-in Tcl support. The only distinction is that I’ve added the colon to the “Identifier and Keyword Characters” string. As a result, TextWrangler recognizes strings containing colons as valid procedure names:
Unfortunately, this approach appears to prevent recognition of the nested syntax. Ideally I would like to support both styles.
Download
I believe this module should be compatible with BBEdit as well as TextWrangler.
Tcl:: Codeless Language Module 1k .zip
Installation
Put Tcl.plist
in ~/Library/Application Support/TextWrangler/Language Modules/
and restart TextWrangler. The module identifies itself as “Tcl::” to differentiate it from TextWrangler’s internal “Tcl” mode, which remains available. It may be necessary to tweak your language preferences to use this module by default, as shown here.
Please share any problems you encounter with this module, particularly those related to the colon’s promoted status.
Posted on Thursday, September 6th, 2007. Tags: code.
Tcl starting points for ThisService
Waffle Software has released ThisService 2.0, a utility that bundles simple scripts as services accessible throughout Mac OS X. Jesper has included example scripts written in a variety of popular languages to help service authors get started. I like Tcl (have you met?), so I have prepared similar templates for Tcl programmers.
Download Tcl service starting points 2.3K
Tcl supports Unicode intrinsically, so, as with the other starting points, these templates should handle whatever text you throw at them without complaint.
Posted on Thursday, September 6th, 2007. Tags: code.
Yojimbo Script Updates
Minor updates to a few Yojimbo AppleScripts are available: Export with Comment Tags, Archive Bookmarks, and Backdate Items. These updates allow the scripts to act on items even when Yojimbo’s item list pane does not have input focus. This means you can run the scripts when editing items as well as when selecting them.
Posted on Friday, August 31st, 2007. Tags: applescript, mac, yojimbo.
Yojimbo Export with Comment Tags
In response to this query, I wrote a script which allows Yojimbo items to be exported with their tags preserved as Spotlight comments. I don’t really use Spotlight, so I’m not sure if the comment format is ideal, but it works fine for a first draft.
Now updated for compatibility with Mac OS X 10.5.
Download ExportwithCommentTags.scpt.zip 1.2 4k
Put the script in ~/Library/Scripts/Applications/Yojimbo
, select some items, and choose “Export with Comment Tags” from your script menu.
Posted on Thursday, August 30th, 2007. Tags: applescript, mac, yojimbo.
“Open As” Pseudo-Stationery Finder AppleScript
Update: Now located at https://github.com/anoved/Finder-Scripts/tree/master/Open%20As
Use this AppleScript to create and open an explicitly named copy of the selected file or folder. You will be prompted to specify the name and location of the new copy. Clicking “Save” will duplicate the item and open the new duplicate.
This script is the result of dissatisfaction with some applications’ lack of support for Stationery Pad files. Specifically, the default behavior appears to be for the Finder to create and open a generic duplicate with “copy [#]” appended to the original base filename. I find it more convenient to name the new instance directly, so that is the functionality this script provides. Stationery pads are not required as it works with regular files.
Rigorous testing has not been performed. Be advised that duplication is performed with cp, which ignored the resource fork in early versions of Mac OS X. Therefore, Mac OS X 10.4 is strongly recommended for compatibility with all files.
Download FinderOpenAs.scpt.zip 3.4K
I suggest saving the script in ~/Library/Scripts/Applications/Finder
and assigning it the keyboard shortcut Shift-Command-O via FastScripts.
Posted on Friday, August 17th, 2007. Tags: applescript, finder, mac.
Brickshelver Development Release
Brickshelver is a small utility I have written to simplify the process of uploading files to Brickshelf, a popular site for LEGO hobbyists.
When you start Brickshelver, you log in using your Brickshelf account. Brickshelver maintains a list of your Brickshelf folders, but it takes a few moments to conduct this inventory. You can skip this step after the first run for faster logins, but in this case Brickshelver will not be aware of any new folders created via the regular web interface.
You can add files to the list of files to upload by clicking the “+” button or by dragging them to Brickshelver’s Dock icon. The files will all be uploaded to the indicated folder, which can be an existing folder or a new folder created with Brickshelver.
Clicking “Upload” will automatically zip the files and upload them to Brickshelf, creating a new folder if necessary. Upload status is reported in the space to the left of the “Upload” button.
Important Notes
This release consists of a stand-alone application for Mac OS X. This application exhibits many inconsistent or unconventional behaviors, as Brickshelver is actually a Tcl/Tk script bundled in a generic application wrapper. There are a large number of issues that need to be addressed and features that need to be improved, including but not limited to:
- Quit via File→Close or by closing the window, but not via Brickshelver→Quit
- Can’t drag files into the actual window
- Localization
- Layout and appearance quirks
- File type validation
- Cross platform support (specifically, zip and preferences mechanisms)
- Full paths look dopey in file list
I am content with Brickshelver in its current state, but I caution others that it is alpha quality software. Further development depends on the reaction to this release; how to proceed is clear, but I am eager to work on other projects instead.
Download Brickshelver Development Release 2.6MB .tar.gz
Your folder inventory and account information (including unencrypted Brickshelf password) are stored on your computer in ~/Library/Preferences/net.anoved.brickshelver.plist
. The format of this file may change in any future releases.
Posted on Monday, August 6th, 2007. Tags: LEGO.
Archive Yojimbo Bookmarks
Yojimbo can catalog bookmarks as well as web archives, which are basically local copies of web sites. This script creates web archives from existing bookmarks you select.
tell application "Yojimbo" -- get the selected items, if any set _items to selection if _items is missing value then return -- archive all the selected bookmark items repeat with _item in _items if class of _item is bookmark item then -- bookmark properties the archive should inherit set _name to name of _item set _url to location of _item set _tags to tags of _item -- archive the bookmarked page try set _archive to make new web archive item with contents _url with properties {name:_name} add tags _tags to _archive end try end if end repeat end tell
Download ArchiveYojimboBookmarks.scpt.zip 1.1 3k
Install the script in ~/Library/Scripts/Applications/Yojimbo
. The script does not check whether there is already a web archive for the bookmarked location, but it could be done.
Posted on Sunday, July 15th, 2007. Tags: applescript, mac, yojimbo.