<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Joy of Appscript</title>
	<atom:link href="http://thejoyofappscript.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://thejoyofappscript.com</link>
	<description>The sound of one script clapping</description>
	<lastBuildDate>Tue, 15 Mar 2011 00:31:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Things: Procrastinate</title>
		<link>http://thejoyofappscript.com/2011/03/things-procrastinate/</link>
		<comments>http://thejoyofappscript.com/2011/03/things-procrastinate/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 00:24:47 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[things]]></category>

		<guid isPermaLink="false">http://thejoyofappscript.com/?p=319</guid>
		<description><![CDATA[Why on Earth anyone would do anything immediately is beyond me. Hence the invention of this simple little script, which will resechedule your currently selected To Dos in Things for tomorrow. As is often the case with application scripting, a large part of the challenge is wrapping your head around the app&#8217;s unique nomenclature – every [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-322" title="things" src="http://thejoyofappscript.com/wp-content/uploads/2011/03/things.png" alt="An inbox with an attractive tick on it (like the symbol for a tick, not a little beastie that latches on to your leg and gives you Legionnaire's Disease or something)" width="32" height="32" />Why on Earth anyone would do anything immediately is beyond me. Hence the invention of this simple little script, which will resechedule your currently selected To Dos in Things for tomorrow.</p>
<p>As is often the case with application scripting, a large part of the challenge is wrapping your head around the app&#8217;s unique nomenclature – every program has its own cat-skinning inclination. I spent some time trying to &#8220;move&#8221; the selected items to the &#8220;scheduled&#8221; list, to no avail. However, thanks to the excellent AppleScript documentation provided by Cultured Code (<a href="http://culturedcode.com/things/wiki/index.php/Welcome" title="Welcome - Things Wiki">available here</a>), I eventually figured out that they had a special verb for me: schedule. </p>
<p>As usual, my preferred way of running all these scripts is with Red Sweater Software&#8217;s <a href="http://www.red-sweater.com/fastscripts/" title="FastScripts">FastScripts</a>, and attaching a dynamic, attractive keyboard shortcut to &#8216;em (historians may note that for this particular script I have chosen control-right arrow. My mnemonic: get away from me).</p>
<blockquote><p> Download <a href="http://ianhaigh.appscript.s3.amazonaws.com/Procrastinate.rb.zip">Procrastinate.rb.zip</a>.</p></blockquote>
<p>The source code is dozing amongst those fern fronds, just over there.</p>
<p><span id="more-319"></span></p>
<pre class="brush:ruby">
#!/usr/bin/env ruby -wKU

require "rubygems"
require 'appscript'
require "date"

things = Appscript.app('Things.app')
tomorrow = DateTime.now.next_day

things.selected_to_dos.get.each { |todo| things.schedule(todo, :for => tomorrow) }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://thejoyofappscript.com/2011/03/things-procrastinate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Things: Add NetNewsWire Headline</title>
		<link>http://thejoyofappscript.com/2011/03/things-add-netnewswire-headline/</link>
		<comments>http://thejoyofappscript.com/2011/03/things-add-netnewswire-headline/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 23:22:52 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[things]]></category>

		<guid isPermaLink="false">http://thejoyofappscript.com/?p=312</guid>
		<description><![CDATA[While hacking my way through the RSS jungle in NetNewsWire, I often find something interesting that I don&#8217;t have time to look at right now. Instapaper takes care of long form articles, but if the media in question is a little richer – a video of a skateboarding dog, say – you&#8217;ll need another way to come [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-322" title="things" src="http://thejoyofappscript.com/wp-content/uploads/2011/03/things.png" alt="An inbox with an attractive tick on it (like the symbol for a tick, not a little beastie that latches on to your leg and gives you Legionnaire's Disease or something)" width="32" height="32" />While hacking my way through the RSS jungle in NetNewsWire, I often find something interesting that I don&#8217;t have time to look at <em>right now</em>. Instapaper takes care of long form articles, but if the media in question is a little richer – a video of a skateboarding dog, say – you&#8217;ll need another way to come back to it.</p>
<p>This script (which is based on <a href="http://mph.puddingbowl.org/2010/07/creating-links-in-the-body-of-a-note-in-things/">this one</a> by Mike Hall) creates a new To Do in <a href="http://culturedcode.com/things/">Things</a> based on the currently selected headline, gives it a couple of tags to make it easy to find again, and embeds the URL in the notes section. So you can save up all your Internetistractions (and yes, that is a clumsy neologism/portmanteau of my own creation) and consume them when you&#8217;re not <em>supposed to be working</em>.</p>
<blockquote><p>Download <a href="http://ianhaigh.appscript.s3.amazonaws.com/Add%20to%20Things.rb.zip">Add to Things.rb.zip</a></p></blockquote>
<p>The source code is hastily finishing its breakfast and pulling on its gumboots, just south of here.</p>
<p><span id="more-312"></span></p>
<pre class="brush:ruby">#!/usr/bin/env ruby
# coding: utf-8

# Ian Haigh - thejoyofappscript.com

# Make a new To Do in Things, based on the name and URL of the currently
# selected item in NetNewsWire. The new To Do goes slap bang into the "Someday"
# category. Handy for temporary bookmarks for things that you want to check
# out later but aren't suitable for Instapaper, like video.

# Based on this script by Mike Hall:
# http://mph.puddingbowl.org/2010/07/creating-links-in-the-body-of-a-note-in-things/

TAGS = "nnw, watch"
# tags that get added to the new To Do

def create_to_do(name, source, link)
	if link == ""
		note = name
	else
		note = "[url=#{link}]#{name} - #{source}[/url]"
	end

	task = @things.make(:at =&gt; app.lists["Someday"].beginning, :new =&gt; :to_do, :with_properties =&gt; {
		:name =&gt; "#{source} – #{name}",
		:tag_names =&gt; TAGS,
		:notes =&gt; note,
	})
end

require 'rubygems'
require 'appscript'
include Appscript

nnw = app("NetNewsWire")
@things = app("Things")

name = nnw.selectedHeadline.title.get
link = nnw.selectedHeadline.URL.get
source = nnw.selectedHeadline.subscription.givenName.get

create_to_do(name, source, link)

#`growlnotify -p 1 -m "Added \"#{name}\" to things."`

# uncomment the previous line if you've got Growl installed
# and you want a pretty message to pop up.</pre>
]]></content:encoded>
			<wfw:commentRss>http://thejoyofappscript.com/2011/03/things-add-netnewswire-headline/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Illustrator: Delete Invisible Layers</title>
		<link>http://thejoyofappscript.com/2011/01/illustrator-delete-invisible-layers/</link>
		<comments>http://thejoyofappscript.com/2011/01/illustrator-delete-invisible-layers/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 05:26:45 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[illustrator]]></category>

		<guid isPermaLink="false">http://thejoyofappscript.com/?p=302</guid>
		<description><![CDATA[A pretty descriptive name, yeah? This script is similar to Illustrator&#8217;s &#8220;Flatten Layers&#8221;, but it will leave your visible layers intact, rather than squishing everything onto one. n.b. if you&#8217;ve carefully locked certain layers, this will reset everything to unlocked. The script could certainly be tweaked (by someone less lazy than me) to remember which [...]]]></description>
			<content:encoded><![CDATA[<p>A pretty descriptive name, yeah? This script is <em>similar</em> to Illustrator&#8217;s &#8220;Flatten Layers&#8221;, but it will leave your visible layers intact, rather than squishing everything onto one.</p>
<p>n.b. if you&#8217;ve carefully locked certain layers, this will reset everything to unlocked. The script could certainly be tweaked (by someone less lazy than me) to remember which layers were locked.</p>
<blockquote><p>Download <a href="http://ianhaigh.appscript.s3.amazonaws.com/Delete%20invisible%20layers.rb.zip">Delete invisible layers.rb.zip</a></p></blockquote>
<p>What I like about this is the use of <code>Appscript.its</code> to operate on a bunch of items at once, rather than having to loop through them. I suspect (though I&#8217;m not sure) that this is an advantage of an Apple Events approach as opposed to ExtendScript, Adobe&#8217;s JavaScript based alternative. For more on the powerful – and sexy – filtering that <code>Appscript.its</code> lets you achieve, check out <a href="http://www.apeth.com/rbappscript/05propel.html#bybooleantest" title="Properties and Elements">this section</a> of Matt Neuberg’s book.</p>
<p>The source code is playfully chasing its shadow in that leafy glade over there.<span id="more-302"></span>
<pre class="brush:ruby">

#!/usr/bin/arch -i386 ruby

# Illustrator won't let me delete hidden layers containing artwork, so we'll
# invert the visibility of all the layers first (visible become invisible and
# vice versa) and then delete the visible ones.

require "rubygems"
require "appscript"

ill = Appscript.app("Adobe Illustrator")
doc = ill.current_document

# first, save a list of the layers we want to keep (i.e. that are currently
# visible)
save_these = doc.layers[Appscript.its.visible.eq(true)].get

# unlock all the layers
begin
	doc.layers[Appscript.its.visible.eq(false)].locked.set(false)
rescue Appscript::CommandError
	puts "There don't seem to be any invisible layers for me to delete."
	exit
end

# turn on visibility of all the layers
doc.layers.visible.set(true)

# loop through our list of layers to save, making them invisible
save_these.each { |l| l.visible.set(false) }

# delete the ones we can see …
doc.layers[Appscript.its.visible.eq(true)].delete

# and turn the others back on again.
doc.layers.visible.set(true)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://thejoyofappscript.com/2011/01/illustrator-delete-invisible-layers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Open for Business, Yes Sir</title>
		<link>http://thejoyofappscript.com/2010/07/open-for-business-yes-sir/</link>
		<comments>http://thejoyofappscript.com/2010/07/open-for-business-yes-sir/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 11:50:52 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[learning]]></category>

		<guid isPermaLink="false">http://thejoyofappscript.com/?p=281</guid>
		<description><![CDATA[You&#8217;d be forgiven, of course, for thinking that this blog&#8217;s maintainer had just been deported to Russia for spying – such is the rate of updates. This, sadly, is not the case. The real reason is far more prosaic: I have been distracted. However, the Internet toils tirelessly whether I&#8217;m paying attention or not. One [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;d be forgiven, of course, for thinking that this blog&#8217;s maintainer had just been deported to Russia for spying – such is the rate of updates. This, sadly, is not the case. The real reason is far more prosaic: I have been distracted.</p>
<p>However, the Internet toils tirelessly whether I&#8217;m paying attention or not. One tireless toiler is <a href="http://mph.puddingbowl.org/about/">Mike Hall</a>, a guy who has more rb-appscript prowess in his little finger than I have in my entire <em>hand</em>. He kindly pointed me in the direction of his blog, which has a terrific array of ruby scripts. It&#8217;s so good that I&#8217;m going to put it on its own line:</p>
<p><a href="http://mph.puddingbowl.org/category/ruby/">http://mph.puddingbowl.org/category/ruby/</a></p>
<p>If you&#8217;re jonesing for more <code>app("Grue").do_some_stuff({:like => "now"})</code> then I highly recommend you check it out. I plan on porting Mike&#8217;s scripts over here too, so that they&#8217;re preserved for posterity, but mainly so I look like I know what I&#8217;m doing.</p>
]]></content:encoded>
			<wfw:commentRss>http://thejoyofappscript.com/2010/07/open-for-business-yes-sir/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finder: Symlink This Window to That One</title>
		<link>http://thejoyofappscript.com/2009/12/finder-symlink-this-window-to-that-one/</link>
		<comments>http://thejoyofappscript.com/2009/12/finder-symlink-this-window-to-that-one/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 06:59:32 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[finder]]></category>

		<guid isPermaLink="false">http://thejoyofappscript.com/?p=270</guid>
		<description><![CDATA[Symlinks! They&#8217;re not just for Christmas. They are, in fact, just like aliases, enabling you to litter your hard drive with shortcuts in no time flat. You can make them in the terminal with the &#8220;ln -s&#8221; command, but if you&#8217;ve got the windows open in the Finder, hell! Why not use &#8216;em? This little [...]]]></description>
			<content:encoded><![CDATA[<p>Symlinks! They&#8217;re not just for Christmas. They are, in fact, just like aliases, enabling you to litter your hard drive with shortcuts in no time flat. You can make them in the terminal with the &#8220;ln -s&#8221; command, but if you&#8217;ve got the windows open in the Finder, hell! Why not use &#8216;em?</p>
<p>This little baby uses the front two Finder windows to figure out the source and destination. Just be careful that they <em>are</em> the front two windows, or you may get unexpected – perhaps terrifying – results. I took the time to build in a confirmation dialog; just edit the code if you feel like living dangerously.</p>
<p>The source code dances a merry jig, over yonder.</p>
<blockquote><p>Download <a href="http://ianhaigh.appscript.s3.amazonaws.com/Symlink-this-window-to-that-one.rb.zip">Symlink-this-window-to-that-one.rb.zip</a>.</p></blockquote>
<p><span id="more-270"></span>
<pre class="brush:ruby">
#!/usr/bin/ruby

# rb-appscript script by Ian Haigh (http://ianhaigh.com/)
# Thu Dec 17 16:50:08 EST 2009

# Looks at the front two Finder windows, and makes a symlink from the first
# window to the second. If there's something selected in the first window, it
# will loop through all the items and make them symlinks in the second.
# Otherwise, it will figure out the target of the first window, and symlink
# that.	Just make sure that the SOURCE WINDOW is the frontmost, and the
# destination window is next in the stacking order.

require 'appscript'
require "osax"
sa = OSAX.osax("standardadditions")

#  set "paranoid" to false if you don't want to confirm the symlink
PARANOID = true

finder = Appscript.app('Finder.app')

if finder.Finder_windows.get.length < 2 then
	sa.display_alert("I need two windows open: frontmost for source, the second for the destination.")
	exit
end

# I can't figure out how to get a bunch of files' paths all at once, without
# having to revert to this "collect" hack
source = finder.selection.get(:result_type => :alias).collect { |item| item.path }

if source.empty?
	# get the front window target instead
	source << finder.Finder_windows.get[0].target.get(:result_type => :alias).path
end

if PARANOID
	source_window = finder.Finder_windows.get[0].target.name.get
	dest_window = finder.Finder_windows.get[1].target.name.get

	plural = (source.length == 1) ? "" : "s"
	confirm_string = %Q{About to symlink #{source.length} item#{plural} from “#{source_window}” to “#{dest_window}”. You wanna go ahead?}

	begin
		result = sa.display_dialog(
		confirm_string,
		:buttons => %w{Cancel OK},
		:default_button => "OK"
		)
	rescue Exception => e
		exit
	end

	# exit unless result[:button_returned] == "OK"
end

destination = finder.Finder_windows.get[1].target.get(:result_type => :alias).path

source.each do |item|
	full_path = File.join(destination, File.basename(item))

	# printf("File.symlink(%s, %s)\n", item, full_path)
	File.symlink(item, full_path)
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://thejoyofappscript.com/2009/12/finder-symlink-this-window-to-that-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Photoshop: Export Layer Comps</title>
		<link>http://thejoyofappscript.com/2009/12/photoshop-export-layer-comps/</link>
		<comments>http://thejoyofappscript.com/2009/12/photoshop-export-layer-comps/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 00:05:28 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[photoshop]]></category>

		<guid isPermaLink="false">http://thejoyofappscript.com/?p=240</guid>
		<description><![CDATA[Web designers, in particular, are famous for making Photoshop files with 134 layers, all named &#8220;Layer 2 copy copy copy copy&#8221;, and spending an hour turning them on and off to show you one iteration of their handiwork. Using Photoshop and not using layer comps is akin to chartering a Gulfstream jet – and then [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://thejoyofappscript.com/wp-content/uploads/2009/12/photoshop.png" alt="photoshop.png" title="photoshop.png" width="32" height="30" class="alignleft size-full wp-image-251" />Web designers, in particular, are famous for making Photoshop files with  134 layers, all named &#8220;Layer 2 copy copy copy copy&#8221;, and spending an hour turning them on and off to show you one iteration of their handiwork. Using Photoshop and not using layer comps is akin to chartering a Gulfstream jet – and then taxiing to your destination. </p>
<p>This script will save all your layer comps separately, in a format of your choosing. &#8220;But,&#8221; I hear you cry, &#8220;Photoshop already comes with a script that already does that already&#8221;. Yes, but this one uses the magnificent &#8220;Save for Web&#8221; command, which performs superior squishing and optimising.</p>
<blockquote><p>Download <a href="http://ianhaigh.appscript.s3.amazonaws.com/Export-layer-comps.rb.zip">Export-layer-comps.rb.zip</a>.
</p></blockquote>
<p>The source code is rubbing its sleepy eyes and yawning, just over there.</p>
<p><span id="more-240"></span>
<pre class="brush:ruby">
#!/usr/bin/env ruby

# rb-appscript script by Ian Haigh (http://ianhaigh.com/)
# Mon Dec 14 10:32:32 EST 2009

# This is a quick &#038; easy way to export all your layer comps to individual
# files. One advantage of this technique is that it uses the "Save for Web…"
# command, which (in my experience) generates smaller, higher quality web
# graphics.

require 'rubygems'
require 'optparse'
require 'appscript'
require "osax"

sa = OSAX.osax('StandardAdditions')

ps = Appscript.app('Adobe Photoshop CS4.app')
finder = Appscript.app("Finder.app")

begin
	comps = ps.current_document.layer_comps.get
rescue Exception => e
	sa.display_alert("Please open a document with at least two layer comps.", :as => :critical )
	exit
end

# Save them into the same directory.
# (This could be modified so the user can choose where to save the files)

begin
	dir = File.dirname(ps.current_document.file_path.get.to_s)
rescue Appscript::CommandError => e
	sa.display_alert("Please ensure the document is saved before running this script.")
	exit
end

format = sa.choose_from_list(
	%w{ jpg png psd },
	:with_title => "Export layer comps",
	:with_prompt => "Choose a format",
	:default_items => ["jpg"],
	:multiple_selections_allowed => false,
	:empty_selection_allowed => false
)[0]

# loop through each comp, applying and saving it as we go
comps.each do |c|
	ps.apply(c)
	file_name = File.basename(ps.current_document.name.get, ".*") + "_" + c.name.get

	case format
	when "jpg"
		ps.export(ps.current_document, :in => "#{dir}/#{file_name}.jpg", :as => :save_for_web,
			  :with_options => {:web_format => :JPEG, :quality => 90})
	when "png"
		ps.export(ps.current_document, :in => "#{dir}/#{file_name}.png", :as => :save_for_web,
			  :with_options => {:web_format => :PNG, :png_eight => true})
	when "psd"
		ps.save(
			ps.current_document,
			:in => "#{dir}/#{file_name}.psd",
			:as => :Photoshop_format,
			:appending => :lowercase_extension,
			:copying => true,
			:with_options => {
				:save_layers => false
			}
		)
	end
end

finder.open(MacTypes::Alias.path(dir))
finder.activate
</pre>
]]></content:encoded>
			<wfw:commentRss>http://thejoyofappscript.com/2009/12/photoshop-export-layer-comps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>InDesign: Update All Modified Images</title>
		<link>http://thejoyofappscript.com/2009/12/indesign-update-all-modified-images/</link>
		<comments>http://thejoyofappscript.com/2009/12/indesign-update-all-modified-images/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 05:03:19 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[indesign]]></category>

		<guid isPermaLink="false">http://appscript.wordpress.com/?p=155</guid>
		<description><![CDATA[This has actually been added as a command in the latest release of InDesign (curse you Adobe, for improving your software and rendering my scripts obsolete). It still serves as a useful example for how to filter a bunch of objects based on a selector. Download Update-all-modified-images.rb.zip. As it&#8217;s only little, I&#8217;ve decided to let [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://thejoyofappscript.com/wp-content/uploads/2009/12/indesign1.png" alt="indesign" title="indesign" width="32" height="30" class="alignleft size-full wp-image-193" />This has actually been added as a command in the latest release of InDesign (curse you Adobe, for improving your software and rendering my scripts obsolete). It still serves as a useful example for how to filter a bunch of objects based on a selector.</p>
<blockquote><p>Download <a href="http://ianhaigh.appscript.s3.amazonaws.com/Update-all-modified-images.rb.zip">Update-all-modified-images.rb.zip</a>.</p></blockquote>
<p>As it&#8217;s only little, I&#8217;ve decided to let this source code live on the front page.</p>
<pre class="brush:ruby">
#!/usr/bin/env ruby

# rb-appscript code by Ian Haigh : http://ianhaigh.com/
# Fri Dec  4 15:54:38 EST 2009

require 'rubygems'
require 'appscript'
include Appscript

ai = Appscript.app('Adobe InDesign CS4.app')

#  Update all modified images
ai.active_document.links[its.status.eq(:link_out_of_date)].update
</pre>
]]></content:encoded>
			<wfw:commentRss>http://thejoyofappscript.com/2009/12/indesign-update-all-modified-images/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>iTunes: Total Size of Current Playlist</title>
		<link>http://thejoyofappscript.com/2009/12/itunes-total-size-of-current-playlist/</link>
		<comments>http://thejoyofappscript.com/2009/12/itunes-total-size-of-current-playlist/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 00:58:43 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[itunes]]></category>

		<guid isPermaLink="false">http://appscript.wordpress.com/?p=148</guid>
		<description><![CDATA[This script, erm, duplicates the functionality of simply looking at the bottom of the iTunes window, where you&#8217;ll find the total size of the current playlist smugly peering up at you. So why did I write this? Your guess is as good as mine. However, in the name of providing examples for would-be iTunes scripters, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://thejoyofappscript.com/wp-content/uploads/2009/12/itunes2.png" alt="itunes" title="itunes" width="32" height="31" class="alignleft size-full wp-image-194" />This script, erm, duplicates the functionality of simply <em>looking at the bottom of the iTunes window</em>, where you&#8217;ll find the total size of the current playlist smugly peering up at you. So why did I write this? Your guess is as good as mine. However, in the name of providing examples for would-be iTunes scripters, I present it here in all its redundant glory.</p>
<blockquote><p>Download <a href="http://ianhaigh.appscript.s3.amazonaws.com/Total-size-of-current-playlist.rb.zip">Total-size-of-current-playlist.rb.zip</a>.</p></blockquote>
<p>The source code is cowering sheepishly around the corner.</p>
<p><span id="more-148"></span>
<pre class="brush:ruby">
#!/usr/bin/env ruby -w

# rb-appscript code by Ian Haigh : http://ianhaigh.com/
# Fri Dec  4 11:53:38 EST 2009

require 'rubygems'
require 'appscript'

class Numeric
  def to_human
    units = %w{B KB MB GB TB}
    e = (Math.log(self)/Math.log(1024)).floor
    s = &quot;%.3f &quot; % (to_f / 1024**e)
    s.sub(/\.?0*$/, units[e])
  end
end

app = Appscript.app(&quot;iTunes.app&quot;)

total = app.browser_windows.view.tracks.get[0].inject(0) { |total, t| total + t.size.get }

puts &quot;#{total.to_human}&quot;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://thejoyofappscript.com/2009/12/itunes-total-size-of-current-playlist/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Illustrator: All Layers Visible</title>
		<link>http://thejoyofappscript.com/2009/12/illustrator-all-layers-visible/</link>
		<comments>http://thejoyofappscript.com/2009/12/illustrator-all-layers-visible/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 00:27:36 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[illustrator]]></category>

		<guid isPermaLink="false">http://appscript.wordpress.com/?p=136</guid>
		<description><![CDATA[Some layers aren't visible? BAM! Now they are.]]></description>
			<content:encoded><![CDATA[<p><img src="http://thejoyofappscript.com/wp-content/uploads/2009/12/illustrator1.png" alt="illustrator" title="illustrator" width="32" height="30" class="alignleft size-full wp-image-192" />The clue is in the title. This is especially handy when you attach a keyboard shortcut with a utility such as – the frankly <em>indispensable</em> – <a href="http://www.red-sweater.com/fastscripts/">FastScripts</a>.</p>
<blockquote><p>Download <a href="http://ianhaigh.appscript.s3.amazonaws.com/All-layers-visible.rb.zip">All-layers-visible.rb.zip</a>.</p></blockquote>
<p>The source code is sheltering from a brief sun shower below.<br />
<span id="more-136"></span>
<pre class="brush:ruby">
#!/usr/bin/ruby

# rb-appscript code by Ian Haigh : http://ianhaigh.com/
# Fri Dec  4 11:21:53 EST 2009

require &quot;rubygems&quot;
require 'appscript'

Appscript.app('Adobe Illustrator.app').current_document.layers.visible.set(true)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://thejoyofappscript.com/2009/12/illustrator-all-layers-visible/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>InDesign: Reveal Links in Finder</title>
		<link>http://thejoyofappscript.com/2009/12/indesign-reveal-links-in-finder/</link>
		<comments>http://thejoyofappscript.com/2009/12/indesign-reveal-links-in-finder/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 00:11:37 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[indesign]]></category>

		<guid isPermaLink="false">http://appscript.wordpress.com/?p=124</guid>
		<description><![CDATA[Loops through all the selected items, attempts to figure out whether any of them are linked images, and opens their containing folders, selecting all of &#8216;em. Download Reveal-links-in-Finder.rb.zip. The source code is bouncing from foot to foot in anticipatory glee, just after the jump. #!/usr/bin/env ruby # rb-appscript code by Ian Haigh : http://ianhaigh.com/ # [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://thejoyofappscript.com/wp-content/uploads/2009/12/indesign1.png" alt="indesign" title="indesign" width="32" height="30" class="alignleft size-full wp-image-193" />Loops through all the selected items, attempts to figure out whether any of them are linked images, and opens their containing folders, selecting all of &#8216;em.</p>
<blockquote><p>Download <a href="http://ianhaigh.appscript.s3.amazonaws.com/Reveal-links-in-Finder.rb.zip">Reveal-links-in-Finder.rb.zip</a>.</p></blockquote>
<p>The source code is bouncing from foot to foot in anticipatory glee, just after the jump.<br />
<span id="more-124"></span>
<pre class="brush:ruby">
#!/usr/bin/env ruby

# rb-appscript code by Ian Haigh : http://ianhaigh.com/
# Fri Dec  4 11:09:29 EST 2009

# loops through all the selected items, attempts to figure out whether any of
# them are linked images, and opens their containing folders, selecting all of
# 'em.

require 'rubygems'
require 'appscript'
include Appscript

def allItemLinks(objList)
	@myList = []

	objList.each do |obj|
		if [:PDF, :image].include?(obj.class_.get) then
			@myList &lt;&lt; obj.item_link.file_path.get
		else
			obj.all_graphics.get.each do |img|
				@myList &lt;&lt; img.item_link.file_path.get
			end
		end
	end
	@myList
end

@id = app('Adobe InDesign CS4.app')
@doc = @id.active_document

x = allItemLinks(@id.selection.get)
@finder = app('Finder.app')

# make an array with every image folder
image_folders = []
x.each { |path| image_folders &lt;&lt; path.slice(/^.+:/) }

# reveal one file first
begin
	@finder.reveal(x[0])
rescue Exception =&gt; e
	puts &quot;Couldn't reveal #{x[0]}&quot;
end

# attempt to select all the files simultaneously
image_folders.uniq.each do |folder|
	begin
		@finder.open(folder)
		files_in_this_folder = x.select { |c| c.include?(folder) }
		@finder.set(:selection, :to =&gt; files_in_this_folder)
	rescue Exception =&gt; e
		puts &quot;Couldn't reveal #{folder}:&quot;
		puts e
	end

end

@finder.activate
</pre>
]]></content:encoded>
			<wfw:commentRss>http://thejoyofappscript.com/2009/12/indesign-reveal-links-in-finder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

