Macro to call a unix script

Get help using and writing Nisus Writer Pro macros.
Post Reply
rsutc
Posts: 16
Joined: 2015-03-13 14:59:06

Macro to call a unix script

Post by rsutc »

I'd like to be able to pygmentize a file by calling a unix script on the top window in Nisus and having the output go to a new window, Can I do this? (I'm not quite into the arcanity of this myself, just know what I want.
- use an AppleScript to call the unix script?
- call a unix script directly?
- write a macro for NISUS using python rather than perl?
- other
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Macro to call a unix script

Post by phspaelti »

You can't call a shell script directly from Nisus. But as you suggest you could probably use Applescript.You could get the file path using the macro language, and then pass the path to applescript to call the script. The Nisus language would have no way to know, if the process is complete. So either Applescript or the script itself would have to know to open the result in Nisus again. If the Applescript can return the path to Nisus after Pygmentization, then Nisus could open the file, as long as its rtf.

By the way, note that Nisus has its own macro language. You don't have to write anything in Perl. (You can write some macros in Perl, but most useful things would probably need to be written in Nisus' own macro language.) You can't use Python in Nisus.
philip
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Macro to call a unix script

Post by phspaelti »

Hello again,
Here is a very bare bones version of a Nisus Macro that should do this kind of thing:

Code: Select all

$doc = Document.active
$path = $doc.filePath
$savePath = $path.filePathByChangingExtension('rtf')
$code = "tell application \"Terminal\"\ndo script \"pygmentize -o '$savePath' '$path'\"\nend tell"
Run AppleScript $code
Open $savePath
philip
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Macro to call a unix script

Post by phspaelti »

Note that with the just released NWP 2.1 code like that above will no longer work, since the Sandbox will prevent calls to other applications through Applescript.
philip
rsutc
Posts: 16
Joined: 2015-03-13 14:59:06

Re: Macro to call a unix script

Post by rsutc »

Hmmm
You give me hope, then snatch it away.

Is there a way to pygmentize in Nisus macros:
I want to take a file that consists of code, and render some keywords in bold, some in a colour, some in grey with a 75% screen--the words to be supplied in three lists, which could I suppose be separate files.

Rick
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Macro to call a unix script

Post by phspaelti »

Hello Rick,
well the approach to use, in case you have updated to NWP 2.1, is to write the whole thing as an AppleScript and run it in Nisus as a Service. And I actually gave it a go. Here is what I came up with:

Code: Select all

tell application "Nisus Writer Pro"
	set codefilepath to path of front document
end tell
	
set basepath to (characters 1 thru -3) of codefilepath as text
set outputpath to basepath & "rtf"
	
tell application "Terminal"
	do script "pygmentize -o '" & outputpath & "' '" & codefilepath & "'"
end tell
	
tell application "Nisus Writer Pro"
	activate
	Do Menu Macro with macro "Macro.run ('Open File With Access', Hash.new ('filepath', '" & outputpath & "'))"
end tell
Note this this relies on an Nisus macro called 'Open File With Access' which I wrote, and does what the name implies. Here's the code for that:

Code: Select all

# Macro Open File With Access
$filepath = Macro.arguments{'filepath'}
File.requireAccessAtPath $filepath
Open $filepath
And if you try it you will probably find that it doesn't open your pygmentized file, at least not unless you open the file by hand first. Martin assures me that this is a bug, and that it should get fixed in an update. So it seems for the time being we'll have to be patient.
By the way this AppleScript also has one or two other issues. As written it keeps opening new Terminal windows. Another issue is that the script is basically too fast, so it will open, or try to open the pygmentized file, before it has been completed, so you'll either get an error because the file doesn't exist, or it will open an older version of the file, rather than the one that was the result of the script itself. Both of these issues may be fixable, but AppleScript is not really my area, so I'm not sure.

So not the greatest news. So much for now.

============
ADDENDUM:
It just occurred to me that there is a way around the main problem. The solution is to delete the second call to Nisus from the AppleScript. so that the AppleScript service only creates the pygmentized file. Then it becomes possible to use a Nisus Macro like this:

Code: Select all

# Macro Pygmentize File and Open
Services:Pygmentize Code File
$doc = Document.active
$filepath = $doc.filePath.filePathByChangingExtension 'rtf'
File.requireAccessAtPath $filepath
Open $filepath
This macro first calls the service to create the .rtf file and then it tries to open it. This will work, except it still suffers from the other two problems mentioned. It's also a bit hokey since the AppleScript and the macro are creating the same file path independently. And note that the AppleScript does this by subtracting characters. So it's hard-coded for 2 letter 'py' extensions.
Last edited by phspaelti on 2015-03-24 10:55:24, edited 3 times in total.
philip
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Macro to call a unix script

Post by phspaelti »

rsutc wrote: Is there a way to pygmentize in Nisus macros:
I want to take a file that consists of code, and render some keywords in bold, some in a colour, some in grey with a 75% screen--the words to be supplied in three lists, which could I suppose be separate files.
If you do have lists, ready it would certainly be possible to write a Nisus Macro to colour a file. It's actually pretty easy. I have written a macro to colour my Nisus Writer macros.
It's easy, except that true Syntax colouring does have to do a bit more than just colour according to a dictionary. It really has to parse the file, according to the syntax of the language to get it right. Since Pygmentize comes with open source code, I had a look inside, but it is a pretty big program, and I'm not sure I can invest the time to try and port something like that to Nisus Writer macro language, assuming that it is doable…
philip
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Macro to call a unix script

Post by phspaelti »

Okay, now with the new 2.1 beta, I have given this another try.

I have slightly refined the method, by changing the Service to directly use a shell script, rather than the Terminal. My Service gets the necessary Shell script line passed to it on the clipboard, so it looks like this:

Code: Select all

on run
	set scriptvar to (the clipboard)
	do shell script scriptvar
end run
I saved this Service with the name "Run Shell Script from Clipboard". Presumably this could now be used to run any suitable shell scripts.

Then I re-wrote my Nisus macro, to first prepare the shell script and call it. Then it makes sure that the script has completed by checking the modification date of the file, before trying to open the file. Note that I am now assuming that you have added the folder containing your code files to the accessible file with the Macro > Application > Manage Macro File Access.

Here is the code. (I attach a macro file below.)

Code: Select all

# Get the path of the code file
$doc = Document.active
$codeFile = $doc.filePath

# Prepare a path for the syntax colored File
$coloredFile = $codeFile.filePathByChangingExtension('rtf')

# Pass the Pygments coloring command to the shell
Write Clipboard "/usr/local/bin/pygmentize -o '$coloredFile' '$codeFile'"
$before = Date.now
Services:Run Shell Script from Clipboard

# Make sure Pygments has finished
while ! File.existsAtPath($coloredFile)
end
$info = File.infoAtPath $coloredFile
while $before.isAfterDate $info{'modificationDate'}
$info = File.infoAtPath $coloredFile
end

# Open the colored .rtf file
Open $coloredFile
Attachments
Pygmentize Code File.nwm
(4.2 KiB) Downloaded 1073 times
philip
Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: Macro to call a unix script

Post by Kino »

Code: Select all

on run
   set scriptvar to (the clipboard)
   do shell script scriptvar
end run
Wow! Thank you very much! With that Services command, perhaps I’ll be able to make some of my macros work again. I really hate sand box ;-(

Here is a bit complicated version of the macro.

Code: Select all

### Highlight Syntax ###


$highlightingStyle = 'tango'

if ! $highlightingStyle # is empty, then...
	$highlightingStyle = 'default'
end

# Get the path of the code file
$doc = Document.active
if ! $codeFile = $doc.filePath
	exit 'This macro works with a saved document only, exiting...'
end

# Check if the file is plain text (perhaps there may be a more appropriate NWP macro way but I don’t know and/or remember...)
$fileType = ''
Set Exported Perl Variables 'codeFile', 'fileType'
begin Perl
	$fileType = `/usr/bin/textutil -info "$codeFile" | grep "Type"`;
	$fileType =~ s/\s*Type:\s*|\n//g;
end
if $fileType != 'plain text'
	exit "This document is not plain text but $fileType, exiting..."
end

# Prepare a path for the syntax colored File
$coloredFile = $codeFile.filePathByChangingExtension('rtf')

# For Sandbox Access
$NWP_ver = Application Property "pro version"
if $NWP_ver >= 2.1
	$folderPath = $coloredFile.filePathByRemovingLastComponent
	File.requireAccessAtPath $folderPath
end

# Get name and size of the font at the insertion point
# which will be those of $coloredFile
$sel = TextSelection.active
$attr = $sel.text.displayAttributesAtIndex $sel.location
$rtfFontName = $attr.fontFamilyName
$rtfFontSize = $attr.fontSize
$rtfFontSize = Cast to Int ($rtfFontSize * 2) # pygmentize does not accept a float number

# Pass the Pygments coloring command to the shell
Write Clipboard "/usr/local/bin/pygmentize -f rtf -O encoding=utf-8,style='$highlightingStyle',fontface='$rtfFontName',fontsize='$rtfFontSize' -o '$coloredFile' '$codeFile' && open -a Nisus\\ Writer\\ Pro '$coloredFile'"
# command2 of 'command1 && command2' is executed only when command1 finished successfully

Menu 'Services:Run Shell Script from Clipboard'

### end of macro
HighlightSyntax.nwm
macro file with syntax highlighting ;-) What is the appropriate lexer for NWP macro?
(34.03 KiB) Downloaded 1209 times
RunShellScriptfromClipboard.workflow.zip
For those who don't want to play with Automator to create it. Unzip and put it in /Users/<you>/Library/Services/.
(35.31 KiB) Downloaded 1245 times
As to pygmentize, you have to install it manually by a Terminal command “pip install Pygments” as explained (?) in http://pygments.org.

Also, a Terminal command “pygmentize -L styles” will show available styles.
Post Reply