NWP macro and AppleScript interoperability?

Get help using and writing Nisus Writer Pro macros.
Post Reply
m.danielsson
Posts: 12
Joined: 2014-07-12 03:21:50

NWP macro and AppleScript interoperability?

Post by m.danielsson » 2014-07-29 12:43:11

Hello,

I am trying to convert a short integration Applescript for BBEdit into a macro to make BBAutocomplete (http://c-command.com/bbautocomplete/) compatible with NWP. BBAutocomplete is good because it lets you cycle through completions by invoking BBAutocomplete again à la Emacs’ dabbrev-expand (M-/), which apparently is the inspiration for the program, until you get the right one.

A few problems: I need to convert an NWP-array to an AS-record and pass it to the script to be run from the macro, pass NWP-variables to the script and I need to be able to return an AS-variable from the script to an NWP-variable. Is this possible?

Of course I may also have look over some other detail that makes this whole thing not doable…

Regards,
Martin

Code: Select all

$doc = Documents.active
if ! $doc
Prompt “No Document open!”
exit
end

# to be passed into the script that calls BBAutocomplete
$currentFileText = $doc.text

#Get start offset of word to be completed to be passed into the script that calls BBAutocomplete
Send Selector “moveWordBackwardAndModifySelection:”
$theOffset = $doc.activeSelection.range.location

# Fetch texts from open documents to be converted into an AS-record ‘alsoTexts’
$documentTexts = Array.new
foreach $d in Documents
   $documentTexts.push $d.text
end




# AppleScript parts.

# Convert array $documentTexts into AS-record $alsoTexts.
#
# AS-block copied from handler makeCompletion()
#
# Is this possible?
$AS = “
		tell application "BBAutoComplete"
			set theCompletion to complete word starting at offset $theOffset ¬
				in text $theCurrentFileText also using text $alsoTexts -- or some such thing
		end tell
		-- theCompletion is a record with three items: startOffset, endOffset and completionText  
                return third item of theCompletion“

$error = “”
$completionText = Run AppleScript $AS, $error

if defined $error
Prompt “AppleScript returned error: ” $error
Exit
End


#Replacement of handler applyCompletion().
$selectionRange = Range.new $thetOffset, $thetOffset + $doc.activeSelection.range.length
$doc.deleteInRange $selectionRange
$doc.insertAtIndex $theOffset, $completionText
BBEdit AppleScript:

Code: Select all

(*
	BBEdit integration AppleScript to accompany 
 	BBAutoComplete <http://c-command.com/bbautocomplete>.
 	Copyright © 2002-2012 Michael Tsai, <bbautocomplete@c-command.com>.

	Put this script in BBEdit's Scripts folder.
*)

on canCompleteInWindow(w)
	tell application "BBEdit"
		return class of w is in {shell window, text window, disk browser window, project window, search results browser}
	end tell
end canCompleteInWindow

on windowHasSingleText(w)
	tell application "BBEdit"
		return class of w is in {shell window, disk browser window, results browser, search results browser}
	end tell
end windowHasSingleText

on windowHasMultipleTexts(w)
	tell application "BBEdit"
		return class of w is in {text window, project window}
	end tell
end windowHasMultipleTexts

on makeAlsoTexts()
	tell application "BBEdit"
		set theResult to {}
		-- this will include the first document from window 1, but that's OK
		repeat with w in windows
			if my windowHasSingleText(w) then
				try
					copy text of w to end of theResult
				end try
			else if my windowHasMultipleTexts(w) then
				repeat with d in text documents of w
					copy text of d to end of theResult
				end repeat
			else
				--log "Skipping: " & (name of w)
			end if
		end repeat
		return theResult
	end tell
end makeAlsoTexts

on makeCompletion()
	tell application "BBEdit"
		set theCurrentFileText to contents of window 1
		set theOffset to characterOffset of selection
		set alsoTexts to my makeAlsoTexts()
		tell application "BBAutoComplete"
			set theCompletion to complete word starting at offset theOffset ¬
				in text theCurrentFileText also using text alsoTexts
		end tell
		return theCompletion
	end tell
end makeCompletion

on applyCompletion(c)
	set {startOffset, endOffset, completionText} to c
	tell application "BBEdit"
		if startOffset is not equal to endOffset then
			select characters (startOffset + 1) thru endOffset of window 1
		else
			try
				select insertion point after character endOffset of window 1
			end try
		end if
		set selection to completionText
		if the length of the selection is greater than 0 then
			select insertion point after selection
		end if
	end tell
end applyCompletion

on run
	tell application "BBEdit"
		if my canCompleteInWindow(window 1) then
			my applyCompletion(my makeCompletion())
		else
			display dialog "Completion doesn’t work when the front window is of type “" & class of window 1 & "”." buttons {"OK"} default button "OK"
		end if
	end tell
end run

capvideo
Posts: 20
Joined: 2008-03-16 16:41:16
Contact:

Re: NWP macro and AppleScript interoperability?

Post by capvideo » 2014-07-29 14:38:41

Well, since you’re creating the AppleScript within the Nisus macro, you can pass the Nisus array to AppleScript simply by creating it on the fly in your AppleScript string.

For the return trip, Nisus gets back the last value generated by the AppleScript as a string. As far as I can tell, it’s the same text that you get in the “results” pane inside AppleScript Editor.

Here’s a simple example of converting a Nisus hash into an AppleScript record, using it, and then getting back the string:

Code: Select all

$greetingData = Hash.new(‘greeting’, ‘hello’)
$greetingData{‘nickname’} = ‘fred’

$greetingGetter = “set greeting to {“

$comma = “ ”
ForEach $key, $value in $greetingData
	$greetingGetter &= “$comma$key: \"$value\"“
	
	$comma = “, ”
End

$greetingGetter &= “}\n”
$greetingGetter &= “get greeting of greeting & space & nickname of greeting”
prompt $greetingGetter

$error = “”
$greeting = Run AppleScript $greetingGetter, $error


if $greeting
	prompt $greeting
end

if $error
	prompt $error
end
Note that if you need a hash or array back, you’ll need to use something like .split on the returned string value to convert it from a string into an array. Something like:

Code: Select all

$greetingData = Hash.new(‘greeting’, ‘hello’)
$greetingData{‘nickname’} = ‘fred’

$greetingGetter = “set greeting to {“

$comma = “ ”
ForEach $key, $value in $greetingData
	$greetingGetter &= “$comma$key: \"$value\"“
	
	$comma = “, ”
End

$greetingGetter &= “}\n”
$greetingGetter &= “set response to {greeting: greeting of greeting & space & nickname of greeting, success:\"yes\"}”
prompt $greetingGetter

$error = “”
$greeting = Run AppleScript $greetingGetter, $error

$greeting = $greeting.split(‘,’)
$response = Hash.new()
foreach $keyvalue in $greeting
	$key, $value = $keyvalue.split(‘:’)
	$response{$key} = $value
end

if $greeting
	prompt $response
end

if $error
	prompt $error
end

m.danielsson
Posts: 12
Joined: 2014-07-12 03:21:50

Re: NWP macro and AppleScript interoperability?

Post by m.danielsson » 2014-07-30 01:53:49

capvideo wrote:Well, since you’re creating the AppleScript within the Nisus macro, you can pass the Nisus array to AppleScript simply by creating it on the fly in your AppleScript string.

For the return trip, Nisus gets back the last value generated by the AppleScript as a string. As far as I can tell, it’s the same text that you get in the “results” pane inside AppleScript Editor.
Thanks! That works well .

This thing does seem to be possible to do . One or two details left to fix.

Regards,
Martin

Post Reply