IIRC, the ‘is a link’ attribute is something we get from the underlying Rich Text format, so my starting assumption was that this was something that could be accomplished by working that angle.
From a few minutes looking at OmniOutliner and TextEdit’s script dictionaries, I’m beginning to think it’s a feature request. Both offer rich text classes, but I don’t see an obvious way to link-ify something.
(At the very least, if it does turn out to be possible, it could be easier/more obvious. Will file!)
If you wrap the link in HTML you can then convert that to RTF and paste into an OO cell by shelling out to textutil,
See, for example:
or by using the NSAttributedString interface:
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
-- rtfFromHTML :: String -> Either String String
on rtfFromHTML(strHTML)
set ca to current application
set s to ca's NSString's stringWithString:strHTML
set d to (s)'s dataUsingEncoding:(ca's NSUTF8StringEncoding)
set attStr to ca's NSAttributedString's alloc()'s initWithHTML:d documentAttributes:(missing value)
if attStr is missing value then
|Left|("String could not be parsed as HTML")
else
set {rtfData, err} to attStr's ¬
dataFromRange:{location:0, |length|:attStr's |length|()} ¬
documentAttributes:{DocumentType:"NSRTF"} ¬
|error|:(reference)
if (missing value = rtfData) or (missing value is not err) then
|Left|(err's localizedDescription() as text)
else
|Right|((ca's NSString's alloc()'s ¬
initWithData:rtfData encoding:(ca's NSUTF8StringEncoding)) as text)
end if
end if
end rtfFromHTML
-- Left :: a -> Either a b
on |Left|(x)
{type:"Either", |Left|:x, |Right|:missing value}
end |Left|
-- Right :: b -> Either a b
on |Right|(x)
{type:"Either", |Left|:missing value, |Right|:x}
end |Right|
-- bindLR (>>=) :: Either a -> (a -> Either b) -> Either b
on bindLR(m, mf)
if missing value is not |Right| of m then
mReturn(mf)'s |λ|(|Right| of m)
else
m
end if
end bindLR
or, using JS:
// rtfFromHTML :: String -> Either String String
const rtfFromHTML = strHTML => {
const
as = $.NSAttributedString.alloc
.initWithHTMLDocumentAttributes($(strHTML)
.dataUsingEncoding($.NSUTF8StringEncoding), 0
);
return bindLR(
typeof as
.dataFromRangeDocumentAttributesError !== 'function' ? (
Left('String could not be parsed as HTML')
) : Right(as),
// Function bound if Right value obtained above:
htmlAS => {
let error = $();
const rtfData = htmlAS
.dataFromRangeDocumentAttributesError({
'location': 0,
'length': htmlAS.length
}, {
DocumentType: 'NSRTF'
},
error
);
return Boolean(ObjC.unwrap(rtfData) && !error.code) ? Right(
ObjC.unwrap($.NSString.alloc.initWithDataEncoding(
rtfData,
$.NSUTF8StringEncoding
))
) : Left(ObjC.unwrap(error.localizedDescription));
}
);
};
// Left :: a -> Either a b
const Left = x => ({
type: 'Either',
Left: x
});
// Right :: b -> Either a b
const Right = x => ({
type: 'Either',
Right: x
});
// bindLR (>>=) :: Either a -> (a -> Either b) -> Either b
const bindLR = (m, mf) =>
undefined !== m.Left ? (
m
) : mf(m.Right);
Try this. It’s also derived from the ‘Selecting text and…’ post. It will deposit the subject of a message (and a link to it) into the first empty child of the first topic. I hope this is basically what you’re looking for.
I got the ‘message’ URL format from this page: ‘message:’ URLs in Leopard Mail
There are several variants. I picked the second one. You can read why there.
tell application "Mail"
-- pick a message, any message
third message of mailbox 1 of account 2
set targetMess to third message of mailbox 1 of account 2
-- get subject and message ID
set subLine to subject of targetMess
set messID to message id of targetMess
-- create message URL for desired email
set fUrl to "message://%3c" & messID & "%3e"
end tell
tell application "OmniOutliner"
-- a place to save the link
set d1 to document 1
set c1 to first child of child 1 of d1 whose topic is ""
-- make (subject and message url) into (topic with link)
set topic of c1 to subLine
set c1's topic's style's attribute "link"'s value to fUrl
end tell
set currentItem to make new row at first row of front document with properties {topic:("email link" as text)}
set currentItem's topic's style's attribute "link"'s value to "message://<" & theMessageId & ">" as text