Hello
Here's a script to convert hyperlinks to urls in current selection in Numbers.
Since Numbers scripting interface does not provide necessary means to extract url from hyperlink, I copy the selection to clipboard, manipulate the rtf data and paste it back to the selection.
Script consists of two files whose source codes are listed below:
• "hyperlink to url.applescript", which is to be saved as a script bundle; and,
• "main.rb", which is to be saved in Contents/Resources directory in script bundle.
# Recipe
1) Copy the code listed as "hyperlink to url.applescript" to new document of AppleScript Editor and save it as script bundle, e.g., "hyperlink to url.scptd".
2) Copy the code listed as "main.rb" to new document of TextEdit and save it as plain text (in UTF-8) file named "main.rb".
3) Show package contents of "hypelink to url.scptd" (via contextual menu) and move the "main.rb" file to Contents/Resources directory in script bundle.
4) Close the package contents window and copy "hyperlink to url.scptd" (or its alias) to ~/Library/Scripts/Applications/Numbers directory so that it appears in script menu in Numbers.
# Usage
Select range(s) in Numbers document and select "hypelink to url" menu item in script menu.
Choose one of the conversion options shown in dialogue: 0 = kill links, 1 = kill links but keep styles, 2 = keep links alive.
# Notes
• It seems rtf data preserves cell structure as well as text font and styles. So it is possible to manipulate table contents by carefully manipulating its rtf representation. However, rtf is so complicated that I don't want to parse it manually. Here I made some use of handy Cocoa methods via RubyCocoa. It could be also done by using AppleScriptObjC if you wish.
• The location to save script bundle in Recipe 4) may vary in 10.7 or later.
• Tested with Numbers 09 v2.0.5 under 10.5.8 and 10.6.5.
# Files
hyperlink to url.applescript
------------------------------------------------------
(*
convert hyperlink to url in selection in Numbers
save this as script bundle or application bundle and
put ruby script in its Contents/Resources with the name used in this script, e.g., main.rb
*)
main()
on main()
script o
property _prompt : "Hyperlink to URL - options:"
property _options : {"0 : kill links", "1 : kill links but keep styles", "2 : keep links alive"}
property _default : 0
-- (1) copy the current selection to clipboard
tell application "System Events"
tell process "Numbers"
set frontmost to true
keystroke "c" using {command down}
end tell
end tell
delay 0.1 -- may need to adjust
-- (2) convent links to urls by modifying rtf data in clipboard
-- -- (2.0) accept conversion option
tell application "Numbers"
set r to choose from list _options with prompt _prompt default items {_options's item (1 + _default)}
end tell
if r is false then error number -128
set _option to r's item 1's character 1 as integer
(*
0 = replace links with urls and kill the links discarding links text colour and underline style
1 = replace links with urls and kill the links preserving links text attributes
2 = replace links with urls and keep the links alive
*)
-- -- (2.1) invoke Contents/Resources/main.rb with _option argument
set rbf to (path to resource "main.rb")'s POSIX path
do shell script rbf's quoted form & " " & _option
-- (3) paste the edited rtf to the current selection
tell application "System Events"
tell process "Numbers"
set frontmost to true
keystroke "v" using {command down}
end tell
end tell
end script
tell o to run
end main
------------------------------------------------------
main.rb
------------------------------------------------------
#!/usr/bin/ruby -w
#
# file
# main.rb
#
# function
# convert hyperlinks to urls in rtf data in clipboard
#
require 'osx/cocoa'
include OSX
def hyperlink_to_url_pboard(option=0)
#
# int option :
# 0 = replace links with urls and kill the links discarding links text colour and underline style
# 1 = replace links with urls and kill the links preserving links text attributes
# 2 = replace links with urls and keep the links alive
#
raise ArgumentError, "invalid option: #{option}" unless [0,1,2].include? option
# get rtf data from clipboard
pb = NSPasteboard.generalPasteboard
data = pb.dataForType('public.rtf')
# make mutable attributed string from rtf data
docattr = OCObject.new
mas = NSMutableAttributedString.alloc.objc_send(
:initWithRTF, data,
:documentAttributes, docattr)
# replace hyperlinks with url strings, optionally preserving or discarding existing attributes
tr = NSMakeRange(0, mas.length)
while tr.length > 0
er = NSRange.new
url = mas.objc_send(
:attribute, NSLinkAttributeName,
:atIndex, tr.location,
:longestEffectiveRange, er,
:inRange, tr)
if url != nil
if option <= 1
# kill the link
mas.objc_send(
:removeAttribute, NSLinkAttributeName,
:range, er)
end
if option == 0
# remove foreground colour from link
mas.objc_send(
:removeAttribute, NSForegroundColorAttributeName,
:range, er)
# remove underline style from link
mas.objc_send(
:removeAttribute, NSUnderlineStyleAttributeName,
:range, er)
end
# replace anchor text with url string
href = url.absoluteString
mas.objc_send(
:replaceCharactersInRange, er,
:withString, href)
# adjust ranges in case href and anchor have different length
delta = href.length - er.length
er.length += delta
tr.length += delta
end
tr = NSMakeRange(NSMaxRange(er), tr.length - er.length)
end
# clean up modified attributed string
r = NSMakeRange(0, mas.length)
mas.fixAttributesInRange(r)
# make rtf data from mutable attributed string
data = mas.objc_send(
:RTFFromRange, r,
:documentAttributes, docattr)
# copy rtf data to the clipboard
pb.objc_send(
:declareTypes, ['public.rtf'],
:owner, nil)
pb.objc_send(
:setData, data,
:forType, 'public.rtf')
end
# main
option = ARGV[0].to_i
hyperlink_to_url_pboard(option)
------------------------------------------------------
Hope this may be of some help,
H