Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Export Address Book entries to HTML via AppleScript Apps
For several years now, I've been using mostly Mac OS X, both as at home and at work, and I'm quite satisfied with it. However, it's still quite far from perfect, and lots of features are missing or buggy. Buggy features are worse than missing ones, because they almost work, so they are even more frustrating.

One of these very frustrating buggy features is Address Book's printing function, which is basically just unusable. It would be great if one could just print one's Address Book, for example to get a pocket phone book, or to get a paper backup, or whatever. But it doesn't work...

After browsing maybe half of the web, I was right about to give up when I finally found HTMLize Address Book, a piece of AppleScript that turned out to do almost what I needed. So I tweaked it a little for my needs (view scriptview CSS file), and cheers -- I was finally able to get my printed address book.

[robg adds: I tested this script, and it works (though it can take a while to run if you've got a large address book). To use, download both the AppleScript and the associated CSS file. Paste the script's contents into Script Editor, and then click Run. When asked for a filename, provide one, and save the file into the same folder as the CSS file. After a few minutes (for my 300-ish entry Address Book), the script will finish, and you can open the resulting HTML file in your favorite browser. Tweak the CSS file to your liking. This hint is based on the author's original blog entry, but I've mirrored the files here, because as noted on the blog, they may vanish from his site at some point.]
    •    
  • Currently 3.25 / 5
  You rated: 5 / 5 (4 votes cast)
 
[13,406 views]  

Export Address Book entries to HTML via AppleScript | 6 comments | Create New Account
Click here to return to the 'Export Address Book entries to HTML via AppleScript' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Export Address Book entries to HTML via AppleScript
Authored by: jonn8n on May 01, '08 11:19:50PM
If you want to export your AB data for viewing on the web (not necessarily for print though it could certainly be used for that), the script below is what I would use. This script differs from the original as it better handles multi-line values, allows you to specify URI schemes for the various data types, adds a hyperlinked index, embeds the css directly in the file, somewhat improves the HTML output, and has a host of other script optimizations. While optimized, it is still painfully slow (the script takes roughly 5 minutes for about 200 contacts on my Mac OS X 10.5.2 MBP).

--adjust these values for the different URI schemes for handling the AB data, leave blank for no URL for the specified data item
property phone_uri : "dialectic://dial?number=" --sends the number to be dialed by Dialectic <http://www.jonn8.com/dialectic/>
property email_uri : "mailto:"
property web_uri : "http://"
property aim_uri : "aim:"
property yahoo_uri : "aim:"
property icq_uri : "aim:"
property msn_uri : "aim:"
property jabber_uri : "aim:"
property postal_uri : ""
property note_uri : ""

property default_name : "ab.html"
property ab_data : {}

property ASCII_10 : ASCII character 10

set ab_data to {}
try
	set filename to (choose file name with prompt "Please specify a filename:" default name default_name) as Unicode text
on error
	beep
	return display dialog "You must specify a file name to continue. Please try again." buttons {"OK"} default button 1 with icon 0 giving up after 20
end try

set start_time to (current date)
set end of ab_data to {"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"", "        \"http://www.w3.org/TR/html4/loose.dtd\">", "<html>", "<head>", "	<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"}
set end of ab_data to "	<style type=\"text/css\" title=\"text/css\" media=\"all\">
		.card { /* border:1px solid black; */ margin-bottom:12px; }
		.name { margin-top:3px; display:table; font-weight:bold; font-family:Helvetica, sans-serif; font-size:14px; }
		.label { display:inline-table; padding-right:3px; width:4em; text-align:right; color:#808080; font-family:Helvetica, sans-serif; font-size:12px; vertical-align:top; text-transform:lowercase; }
		.value { display:inline-table; font-family:Helvetica, sans-serif; font-size:12px; vertical-align:top; } 
		.phone { display: block; }
		.email { display: block; }
		.birthday { display:block; }
		.instantmessage { display:block; }
		.postal { display:block; }
		#toc_box { background-color:#f2f2f2; position:fixed; top:0px; left:0px; width:100%; height:1.2em; float:left; padding-top:-2px; border-bottom:1px solid #bfbfbf; z-index:1; }
		#toc { position:absolute; top:3px; left:15px; padding-right:15px; z-index:1; font-family:Helvetica, sans-serif; font-size:12px; text-transform:uppercase; font-weight:bold; }
		a { text-decoration:none; }
		a:hover { text-decoration:underline; }
		a.toc_link { text-transform:uppercase; text-decoration:none; }
		a.toc_link:hover { text-decoration:underline; }
		a.toc_anchor { margin-top:12px; margin-bottom:12px; font-family:Helvetica, sans-serif; font-size:18px; text-transform:uppercase; font-weight:bold; color:#bfbfbf; }
	</style>"
set end of ab_data to {"</head>", "<body>"}
set end of ab_data to {"<div id=\"toc_box\"><div id=\"toc\"><<toc>></div></div>", "<div>&nbsp;</div>"}
set the_toc to {}
set last_anchor to ""

tell application "Address Book"
	repeat with ln in my sort(get last name of people)
		set the_initial to character 1 of ln
		ignoring case
			if (last_anchor is not the_initial) then
				set last_anchor to the_initial
				set end of the_toc to last_anchor
				set end of ab_data to "<a class=\"toc_anchor\" name=\"toc_" & last_anchor & "\">" & last_anchor & "</a>"
			end if
		end ignoring
		repeat with p in (people whose last name is ln)
			tell p
				set end of ab_data to "<div class=\"card\">"
				set end of ab_data to "	<div class=\"name value\">" & my clean_value(name) & "</div>"
				repeat with i in phones
					my add_data_item("phone", i's label, phone_uri, i's value)
				end repeat
				repeat with i in emails
					my add_data_item("email", i's label, email_uri, i's value)
				end repeat
				if (exists birth date) then my add_data_item("birthday", "birthday", "", date string of (get birth date))
				if (exists home page) then my add_data_item("homepage", "homepage", web_uri, home page)
				repeat with i in AIM Handle
					my add_data_item("instantmessage", i's label, aim_uri, i's value)
				end repeat
				repeat with i in Yahoo handle
					my add_data_item("instantmessage", i's label, yahoo_uri, i's value)
				end repeat
				repeat with i in ICQ handle
					my add_data_item("instantmessage", i's label, icq_uri, i's value)
				end repeat
				repeat with i in MSN handle
					my add_data_item("instantmessage", i's label, msn_uri, i's value)
				end repeat
				repeat with i in Jabber handle
					my add_data_item("instantmessage", i's label, jabber_uri, i's value)
				end repeat
				repeat with i in addresses
					my add_data_item("postal", i's label, postal_uri, i's formatted address)
				end repeat
				if (exists note) then my add_data_item("note", "note", note_uri, note)
				set end of ab_data to "</div>"
			end tell
		end repeat
	end repeat
end tell
set end of ab_data to {"</body>", "</html>"}
set ab_data to my list_to_string(ab_data, ASCII_10)
repeat with i from 1 to (count the_toc)
	set this_init to item i of the_toc
	set item i of the_toc to "<a class=\"toc_link\" href=\"#toc_" & this_init & "\">" & this_init & "</a>"
end repeat
set the_toc to my list_to_string(the_toc, " ")
set ab_data to my snr(ab_data, "<<toc>>", the_toc)

do shell script "echo " & (quoted form of ab_data) & " > " & (quoted form of POSIX path of filename)
set ab_data to {}
beep 2
return {processing_time:"" & ((current date) - start_time) & " seconds", filename:filename}

on add_data_item(c, t, u, v)
	if u = "" then
		set v to my clean_value(v)
	else
		set v_for_url to my snr(v, " ", "%20") --more encoding could be used here for extended entity encoding
		if v_for_url does not start with u then set v_for_url to (u & v_for_url)
		set v to "<a href=\"" & v_for_url & "\">" & my clean_value(v) & "</a>"
	end if
	set end of ab_data to "	<div class=\"" & c & "\"><span class=\"label\">" & t & "</span><span class=\"value\">" & v & "</span></div>"
end add_data_item

on sort(l)
	tell (a reference to my text item delimiters)
		set {o, contents} to {contents, ASCII_10}
		set {l, contents} to {"" & l, o}
	end tell
	return (do shell script "echo " & quoted form of l & " | sort -fu")'s paragraphs
end sort

on list_to_string(l, d)
	tell (a reference to my text item delimiters)
		set {o, contents} to {contents, d}
		set {l, contents} to {"" & l, o}
	end tell
	return l as Unicode text
end list_to_string

on snr(the_string, search_string, replace_string)
	tell (a reference to my text item delimiters)
		set {old_tid, contents} to {contents, search_string}
		set {the_string, contents} to {the_string's text items, replace_string}
		set {the_string, contents} to {the_string as Unicode text, old_tid}
	end tell
	return the_string
end snr

on clean_value(v)
	set v to my snr(v, return, "<br>")
	set v to my snr(v, ASCII_10, "<br>")
	set v to my snr(v, "&", "&")
end clean_value
Jon Nathan

[ Reply to This | # ]
Export Address Book entries to HTML via AppleScript
Authored by: wallybear on May 02, '08 02:27:00AM
I noted that the script stops with an error with badly formatted addresses, so I made this change to your script in the address retrieval part:

repeat with i in addresses
  try
    set tmp_addr to formatted address of i
  on error
    set tmp_addr to i's street & return & i's zip & " " & i's city & " " & i's state & return & i's country
    replaceStrings of tmp_addr to " " instead of "missing value"
  end try
 my add_data_item("postal", label of i, postal_uri, tmp_addr)
end repeat
and added the following method at the end of the script:

to replaceStrings of t to r instead of s
	set d to text item delimiters
	set text item delimiters to s
	set t to t's text items
	set text item delimiters to r
	tell t to set t to item 1 & ({""} & rest)
	set text item delimiters to d
	t
end replaceStrings


[ Reply to This | # ]
Export Address Book entries to HTML via AppleScript
Authored by: jonn8n on May 02, '08 09:22:37AM
It's probably a good idea to wrap more sections in try blocks in case there is a problem with the data. In case of an error with the formatted postal address, I'd construct it manually (this follows the US's convention for formatting postal addresses, update to your country's format as desired):

repeat with i in addresses
	try
		set tmp_addr to formatted address of i
	on error
		set tmp_addr to {}
		set {_street, _city, _state, _zip, _country} to i's {street, city, state, zip, country}
		if _street is not in {"", missing value} then set end of tmp_addr to {_street, return}
		if _city is not in {"", missing value} then set end of tmp_addr to {_city, ", "}
		if _state is not in {"", missing value} then set end of tmp_addr to {_state, " "}
		if _zip is not in {"", missing value} then set end of tmp_addr to {_zip}
		if _country is not in {"", missing value} then set end of tmp_addr to {return, _country}
		set tmp_addr to tmp_addr as Unicode text
	end try
	my add_data_item("postal", label of i, postal_uri, tmp_addr)
end repeat
Jon

[ Reply to This | # ]
Export Address Book entries to HTML via AppleScript
Authored by: jonn8n on May 04, '08 04:55:20PM
I've looked at the script a bit more and realized there was a glaring error. The original script only included contacts that actually have a last name. This means contacts identified as companies and not individuals would not be included in the output. I've corrected this issue in my version, added properties at the top of the script for including/excluding the data items (e.g., phone, email, etc.) as desired, and added the option to also include any images associated with contacts in Address Book.app. All of this makes the script pretty slow (maybe at some point I'll port the whole thing to Objective-C) so if you run it, be prepared to go do something else while the script processes your data.

Instead of posting the whole script here, I've put it online at:

http://www.jonn8.com/html/Address_Book_to_HTML.html

Jon

[ Reply to This | # ]
Export Address Book entries to HTML via AppleScript
Authored by: Gyom on May 05, '08 06:05:30AM

Hi all,

and thanks for your appreciation about the script. I've updated it to take into account the corrections and enhancements that I found in the above comments (embedded CSS, better handling of malformed postal addresses, inclusion of contacts identified as companies). However, I did not add the features that I definitely do not need, such as picture retrieval, nor extensive use of shell scripts, because the script is already slow enough.

By the way, Jonn8n, it would have been nice to credit me, as well as the original author somewhere in your version of the script. To paraphrase something does not make you the author of it.

Bye,
-G




[ Reply to This | # ]
Thanks, Guillaume.
Authored by: mael on Jun 16, '08 07:36:34AM

Thank you, Guillaume.

And you are absolutely right to criticize Jonathan Nathan.
I've just downloaded his version as well, and it still does not give credit, in fact, he's even asking for money ("Gratuities Appreciated").

Self-important, preposterous ape. Forget him.



[ Reply to This | # ]