[TxMt] LaTeX & AddressBookMe.plist

Grant Hollingworth grant at antiflux.org
Thu Feb 15 17:12:24 UTC 2007

* Allan Odgaard <throw-away-1 at macromates.com> [2007-02-14 13:40]:
>I seem to recall an AB query shell command from somewhere, might be a  
>possibility to bundle that with TM, so we can use that instead.

The attached command tries the Little Brother's Database[1], contacts, and AppleScript in order.

[1] http://www.spinnaker.de/lbdb/
-------------- next part --------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<string>#!/usr/bin/env ruby -wKU
require 'iconv'

DIALOG = SUPPORT + '/bin/tm_dialog'
ENV['PATH'] = %x{sh -c '. "$BASH_ENV"; echo $PATH'}
require SUPPORT + '/lib/escape'
require SUPPORT + '/lib/plist'
require SUPPORT + '/lib/exit_codes'
search_text = STDIN.read

def found?(executable)
  ENV['PATH'].split(/:/).find do |dir|
    File.executable?(File.join(dir, executable))

# convert between UTF-8 and Mac Roman encoding
macroman = Iconv.new('macroman', 'utf-8')
utf8 = Iconv.new('utf-8', 'macroman')

## these commands are tried in order

# lbdb is The Little Brother's Database
# http://www.spinnaker.de/lbdb/
# it can search Mutt's alias files, abook, LDAP directories, etc.

# contacts searches the Address Book.
# http://gnufoo.org/contacts/
# It returns only one email address for each person.

# Both lbdb and contacts can be easily installed with MacPorts:
# http://www.macports.org/

# The fallback option is querying Address Book with AppleScript.
# Unlike lbdb and contacts, it requires Address Book to be open.

    proc do
      %x{lbdbq "#{search_text}" | tail -n +2}.map do |line|
        line.split(/\t/)[0..1].map {|f| f.strip}.reverse
    proc do
      %x{contacts -Ss -f "%n:%e" "#{macroman.iconv(search_text)}" | tail -n +2}.map do |line|
        line.chomp.split(/:/).map {|field| utf8.iconv(field)}
    proc do
      %x{osascript <<END
tell application "Address Book"
  set matchList to {}
  repeat with oneID in (get id of every person whose name contains "#{search_text}")
    set oneID to contents of oneID
    set dataList to (get every email of person id oneID)
    repeat with oneValue in dataList
      copy (name of person id oneID & tab & value of oneValue) to end of matchList
    end repeat
  end repeat
end tell

set AppleScript's text item delimiters to ASCII character 10
return items of matchList as string
}.map {|line| line.chomp.split(/\t/)}

matches = COMMANDS.find {|command| found? command.first }.last.call

names = matches.map do |name, email|
	{'title' => "#{name} (#{email})", 'email' => "#{name} <#{email}>"} if email
TextMate.exit_show_tool_tip "No matches found" if names.empty?
TextMate.exit_replace_text names[0]['email'] if names.length == 1

plist = { 'menuItems' => names }.to_plist
res = PropertyList::load(`#{e_sh DIALOG} -up #{e_sh plist}`)
TextMate.exit_discard unless res.has_key? 'selectedMenuItem'

print res['selectedMenuItem']['email']</string>
	<string>Find Email Address in Address Book</string>

More information about the textmate mailing list