How to target a generic suite (Text Suite) of multiple applications

I have some code that converts rich text attribute runs (from the Text Suite) into Markdown. It works equally well with TextEdit and OmniOutliner (and probably other applications that support Text Suite renditions of rich text).

The problem is that I have to target some application’s terminology in order to get all this to compile. Presently, i’m using using terms from application "TextEdit", but this seems fragile. I cannot think of a way of using a particular suite independently from a target application.

Here’s the common code:

on isLink(linkText)
	--	This is a very crude test if a string is a link.
	ignoring case
		return linkText begins with "http:" or ¬
			linkText begins with "https:" or ¬
			linkText begins with "ftp:" or ¬
			linkText ends with ".com"
	end ignoring
end isLink

on isEmail(emailText)
	--	This is a very crude test if a string is an email address.
	ignoring case
		return emailText contains "@" and emailText ends with ".com"
	end ignoring
end isEmail

on isBoldFont(fontName)
	ignoring case
		return fontName contains "Bold"
	end ignoring
end isBoldFont

on isItalicFont(fontName)
	ignoring case
		return fontName contains "Italic"
	end ignoring
end isItalicFont

on richTextToMarkdown(cellRef)
	local markdownText, inBold, inItalic, rowText
	
	set inBold to false
	set inItalic to false
	set rowText to {} --  use an array because its a bit faster
	
	using terms from application "TextEdit"
		repeat with anAttribute in attribute runs of cellRef
			set {runText, runIsBold, runIsItalic} to ¬
				{contents of anAttribute, my isBoldFont(font of anAttribute), my isItalicFont(font of anAttribute)}
			
			--	close any existing attribute runs that have ended
			if inBold and not runIsBold then
				set end of rowText to "**"
				set inBold to false
			end if
			if inItalic and not runIsItalic then
				set end of rowText to "*"
				set inItalic to false
			end if
			
			--	open  new attribute runs
			if not inBold and runIsBold then
				set end of rowText to "**"
				set inBold to true
			end if
			if not inItalic and runIsItalic then
				set end of rowText to "*"
				set inItalic to true
			end if
			
			--	add the attribute run's text
			if my isEmail(runText) then
				set end of rowText to "[" & runText & "](mailto:" & runText & ")"
			else if my isLink(runText) then
				set end of rowText to "[" & runText & "](" & runText & ")"
			else
				set end of rowText to runText
			end if
		end repeat
		
		--	close any existing attribute runs
		if inBold then
			set end of rowText to "**"
			set inBold to false
		end if
		if inItalic then
			set end of rowText to "*"
			set inItalic to false
		end if
	end using terms from

	--	convert the array of Markdown texts into a single string
	set saveTID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {""}
	set markdownText to rowText as text
	set AppleScript's text item delimiters to saveTID
	
	return markdownText
end richTextToMarkdown

and here is some code which uses richTextToMarkdown():

set markdownText to {}

tell application "OmniOutliner"
	tell first document
		repeat with aRow in (get selected rows)
			set targetRow to contents of aRow
			set end of markdownText to my richTextToMarkdown(a reference to topic of targetRow)
			
			if targetRow's note is not "" then
				set end of markdownText to my richTextToMarkdown(a reference to rich text of note cell of targetRow)
			end if
		end repeat
	end tell
end tell

set saveTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {return & return}
set markdownText to markdownText as text
set AppleScript's text item delimiters to saveTID

…and…

tell application "TextEdit"
	my richTextToMarkdown(a reference to document 1)
end tell

Any ideas?

Use pandoc instead? I haven’t done it myself, but this should work in do shell script:

textutil -stdin -convert html -stdout | pandoc --from=html --to=markdown

OTOH, relying on TextEdit doesn’t seem too fragile to me. I mean, if they ever fix the Text Suite you’ll be too surprised to be annoyed :wink:

This is good, but apps like OmniOutliner don’t deal in text files so I have to generate the Markdown myself. In OmniOutliner’s case, there is a plugin that produces Markdown, but it does not operate in the way I need.

The goal of standardized AppleEvent Suites, such as the Text Suite, was to allow code that used such a suite of objects and commands to be portable across applications that supported the suite. But the language really does not facilitate this kind of portability since how have to tie yourself to a given dictionary with a using terms from application "X" block.

Anyway, using TextEdit as the terminology host seems to be working just fine so this is probably a tempest in a teapot.